osgarden API Reference

The osgarden 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.

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✅ 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
schema-and-deploy.mddefineSchema DSL, the /deploy endpoint, the osgarden CLI✅ Available
sdk.mdThe @osgarden/sdk TypeScript client✅ Available
metering.mdRate card: payer, rate, and mechanism per surface✅ Available
not-yet-implemented.mdVisitors, realtime, functions, 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-Osgarden-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.

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:

{ "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-Osgarden-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.
503*_not_configuredA required server dependency (OpenRouter, Stripe, deploy token) is unset.

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

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 osgarden CLI (deploy, typegen). See not-yet-implemented.md for the fuller roadmap.