tallpond API Reference

The tallpond gateway is the single authority for every app request: it authenticates the caller, compiles and enforces data access, meters usage, and attributes cost to a payer. This reference documents the HTTP API it exposes and the TypeScript SDK that wraps it.

Model in one line: developers host open-source apps for free; end users pay their own direct usage costs; the app holds no secrets. Every operation is authenticated, access-checked, and metered by the gateway.

Coding agent? docs/agent-skill/SKILL.md (also served at tallpond.com/skill.md) is the fast path — auth modes, error shapes, and what to read before guessing at a failure. tallpond.com/llms.txt indexes the full doc set.

Contents#

DocCoversStatus
authentication.mdOAuth/PKCE sign-in, sessions, consent✅ Available
database.md/v1/db — scoped, metered CRUD; scopes, shared tables, federated queries✅ Available
resources.md/v1/resources — resources, consensual membership, claim links✅ Available
ai.md/v1/ai/chat — metered LLM passthrough✅ Available
billing.md/v1/wallet, /v1/apps, top-up, Stripe webhook✅ Available
files.md/v1/files — object storage on both scopes✅ Available
users.md/v1/users — profiles, author(...), account deletion✅ Available
realtime.md/v1/realtime/ticket, /realtime/connect — live queries, ticket handshake, resume🚧 Partial (complete; publish metering not yet billed)
functions.md/v1/functions — as-user server functions, via provenance gating🚧 Partial (MVP)
schema-and-deploy.mddefineSchema DSL, the /deploy endpoint, the tallpond CLI✅ Available
sdk.mdThe @tallpond/sdk TypeScript client✅ Available
metering.mdRate card: payer, rate, and mechanism per surface✅ Available
not-yet-implemented.mdVisitors, presence, jobs📋 Planned

Status legend#

Base URL & versioning#

All endpoints are served from the gateway origin (for local development, http://localhost:3000).

Requests and responses are JSON (Content-Type: application/json) unless noted (the AI streaming response is text/event-stream; the Stripe webhook takes a raw signed body).

Authentication#

Every /v1/* request must present one of:

  1. Session cookie (browser SDK). The gateway sets httpOnly cookies during sign-in; the app never sees the token. Cookie-authed requests must also send the header X-Tallpond-Csrf: 1 — browsers only attach custom headers after a CORS preflight, which makes cookie-bearing state changes CSRF-proof. Requests use credentials: include.
  2. Bearer token (server-to-server): Authorization: Bearer <access_token>. No CSRF header is required for bearer auth. Several token families are accepted, distinguished by prefix and verified locally with no Ory round-trip: tpa_ (a non-human principal's runtime token), tpt_ (a dev-minted test session), and tpi_ (a function invocation context, minted by the gateway and never by a client).

The gateway validates the token against Ory (introspection when ORY_API_KEY is set — which also yields the app/client id used for per-app budgets — otherwise the public userinfo endpoint). See authentication.md.

Errors#

Errors are JSON with a stable machine-readable error code and a human detail:

json
{ "error": "forbidden", "detail": "not permitted to create \"messages\"" }

Data-engine (/v1/db, /v1/resources) error codes and their HTTP statuses:

errorStatusMeaning
invalid_request400Malformed request, unknown column, unbounded destructive op, unsupported op for the scope.
resource_required400The operation needs a resource scope.
forbidden403Authenticated but not permitted (access rule denied).
not_found404No such table/resource — also returned to hide the existence of a members-only resource from non-members.
conflict409Constraint violation, or single() matched more than one row.

Cross-cutting statuses:

StatuserrorWhere
401missing credentials / invalid or expired tokenAny /v1/* without valid auth.
403missing csrf headerCookie-authed request missing X-Tallpond-Csrf.
402insufficient_balance / spend_cap_exceededMetered ops when the wallet can't cover the escrow hold, or the app hit its per-app monthly cap.
502upstream_errorA dependency (e.g. the model provider) failed; you owe nothing. The body carries upstream_status, upstream_request_id, and upstream_body (parsed JSON when the upstream returned it, raw text otherwise — including non-JSON bodies from a firewall or load balancer in front of the provider).
503*_not_configuredA required server dependency (OpenRouter, Stripe, deploy token) is unset.

Every response, success or error, carries X-Tallpond-Request-Id — a Cloudflare Ray ID in production. Include it when reporting an issue; it's what a gateway log line keys on.

The SDK rethrows all of these as TallpondError with { message, status, data, requestId }.

Billing & metering (how cost attaches)#

Known limitations in shipped areas#

These are implemented paths with a deliberate, temporary simplification:

Now shipped (previously listed here): object storage (Stage E), user profiles, author(...), and account deletion (Stage F), plus the tallpond CLI (dev, confirmed production deploy, environment-only test sessions, and typegen). See not-yet-implemented.md for the fuller roadmap.