Base URL
/v1 and requires Authorization: Bearer <key>. Two
surfaces do not:
POST /v1/signup— the one unauthenticated write. Registered ahead of the auth middleware./embed/*— gated by a short-lived embed JWT instead of an API key. See Live view.
/v1/workspaces and /v1/billing are
session-only — driven by the dashboard, refusing API keys with 401. See
dashboard sessions.
Conventions
application/json
Send
content-type: application/json on every request with a body. Responses are JSON,
except DELETE /v1/checkouts/{id} (empty 202) and the /embed routes (HTML and
text/event-stream).UUID v4
Checkouts, actions, buyer profiles, buyer sessions, API keys and webhook endpoints are all
UUIDs. Merchant order ids on a receipt are the merchant’s own format — do not parse them.
ISO 8601, UTC
2026-07-29T09:14:31.190Z. Every timestamp field, everywhere.{ amount, currency }
amount is a decimal string — "42.10", never 42.1. currency is an ISO 4217 code
and defaults to "USD" where you may omit it.cursor
Checkouts, buyer profiles, API keys and webhook endpoints all return
{ data, nextCursor },
newest first. Pass nextCursor back as ?cursor=; null means the end. limit defaults to 20
and caps at 100.Checkouts and buyer profiles are genuinely paged. GET /v1/api-keys and GET /v1/webhooks are
not — they answer the whole collection, with nextCursor: null and their original keys /
endpoints arrays alongside data for callers written before the shapes converged. Read data.GET /v1/buyer-sessions is the exception that has not converged: it answers
{ sessions, vaultEnabled }, with no data and no cursor.{ error: true, message }
Plus
issues on validation failures, requiredScope on a scope refusal, sandboxMerchants
on sandbox confinement, planCeilingUsd when maxCost exceeds the plan’s per-checkout
ceiling. See Errors and limits.<resource>.read | <resource>.write | *
Every route requires a scope derived from its path and method.
write implies read on the
same resource; a key issued without scopes holds *. See
Authentication.subject
A key may be bound to one of your end users at creation, after which it sees and creates only
that person’s rows.
subject is your own opaque id — 1 to 200 characters, "" is a 400 —
accepted on POST /v1/api-keys, POST /v1/checkouts and POST /v1/buyer-profiles, filterable on
GET /v1/checkouts?subject=, and present on the checkout.status_changed webhook payload. A key
without one is tenant-wide. See End-user isolation.unknown fields are a 400
The three create bodies that accept
subject reject unrecognised top-level fields, so a
misspelled subjectt fails loudly instead of returning 201 with an untagged row. target,
constraints and metadata stay permissive inside.Idempotency-Key header
POST /v1/checkouts only. A replay returns the original checkout with 200; the same key with
a different body is 409. Keys are namespaced per (tenant, subject) and expire 24 hours after
the checkout that claimed them was created. See
Idempotency.Machine-readable spec
The whole/v1 surface is described in OpenAPI 3.1. The spec lives at openapi.json in the
root of the docs repository, and the
Endpoints group in this tab is generated from it — so that group is the version that cannot
drift from the schemas, and it is what to feed a code generator or an agent.
The pages below are the hand-written companion: the same endpoints, with the reasoning a spec
has no room for. Where the two disagree, the spec is right about shapes and these pages are
right about why.
The live-view embed (/embed/*) is not in the spec — it is browser-facing, authenticates with
a minted JWT rather than an API key, and returns HTML and text/event-stream. See
Live view.
Endpoints
Health
Signup
Checkouts
User actions
Buyer profiles
Buyer sessions
Webhooks
API keys
Usage
Workspaces (dashboard session only)
Billing (dashboard session only)
These are the routes behind the dashboard’s onboarding and billing pages — provisioning a
workspace, choosing a plan, identity verification, the AUP, and the activation checklist. An
API key on any of them is a
401, whatever its scopes. The flow they implement is
documented in Going live.
Live view (embed-token auth)
Documented in Live view.
There is no SDK yet. Everything here is plain HTTP; the Quickstart has a
complete TypeScript client in about a hundred lines of
fetch, and
Use Farthing from an LLM agent has the same thing shaped as model tools.