โ† back to the pond

RDaaS API

Rubber Duck as a Service is a tiny HTTP API. It lives at the same origin as this site โ€” Fly Pages reverse-proxies /api/* (and /quack) to the backend, so you call it with plain relative paths. No API key, no CORS, no second domain.

Base URL: https://rdaas.flypages.dev

๐Ÿค– Reading this as an agent?

Fetch this same URL with a Markdown Accept header and Fly Pages hands you clean Markdown instead of this page:

curl -H "Accept: text/markdown" https://rdaas.flypages.dev/docs

Endpoints

GET /api/duck

Summon a duck. Returns an ASCII duck and a debugging tip, and bumps the global counter.

{
  "id": 42,
  "ascii": "โ€ฆ",
  "tip": "Read your code out loud to me. Halfway through, you'll gasp.",
  "source": "canned",
  "summoned": 42
}

source is claude when the tip was generated live via the Anthropic gateway, or canned when served from the baked (Claude-written) pack.

GET /api/stats

Live counters.

{ "ducks_summoned": 42, "pond_notes": 7, "uptime_seconds": 1234, "live_claude": false }

GET /api/pond

The guestbook. Recent notes, newest first.

{ "notes": [ { "name": "ada", "note": "quack.", "at": "2026-08-14T13:00:00Z" } ] }

POST /api/pond

Sign the pond. name caps at 40 chars, note at 240.

POST /api/pond
Content-Type: application/json

{ "name": "your handle", "note": "leave a ripple" }

GET /quack

A second backend, mounted at its own prefix to prove the point.

{ "quack": "Quack quack. Ship small, ship often, nap on the water." }

Auth (the honest bit)

Every /api and /quack request that reaches the backend carries a Fly-Pages-Secret header that Fly Pages injects at the edge โ€” your browser never sees it. The backend rejects anything without a known secret, so you can hit /api/duck here but a stranger can't call the raw backend URL and burn the duck's budget. Same-origin, private-by-default.