POST /v1/signup and get a working API key in one
call, with no review and no card on file.
That is only safe because of one gate: sandbox confinement. A confined request can only
check out against merchants we control.
Two independent triggers
A request toPOST /v1/checkouts is confined if either is true:
The account is sandbox-only
Every self-serve signup starts here. Confinement applies to every key the account holds,
including
ck_live_ ones it cannot create yet.The request used a test key
A
ck_test_ key is confined even on a fully activated account. Key mode is a property of
the credential, not the account.Why the gate is where it is
Every other guardrail on this platform limits how much money moves or how fast.maxCost
caps a purchase. Quotas cap concurrency and daily volume. Cards are single-use by policy.
None of those decide whether real money is reachable at all — and an agentic checkout
platform that hands a stranger unrestricted access to real merchants is, functionally,
carding infrastructure. Sandbox confinement is the one control that answers that question, so
it is on by default and cannot be turned off from inside the API.
What you can do in the sandbox
Everything. That is the point — it is not a mock.- Real browser, real merchant storefront, real checkout pages.
- The real engine, chosen the same way, driving the same code paths.
- A real variant prompt with the store’s real options.
- Real card entry into real payment iframes.
- A genuinely placed order on the sandbox store, with a real confirmation page and a real
merchantOrderId. - Webhooks, live view, buyer profiles, buyer sessions, usage — all identical.
What you cannot do
Target a merchant we do not control
Target a merchant we do not control
POST /v1/checkouts against any other host returns 403, and the body tells you the
offending host, which of the two triggers applied, and where you can check out:403 carries the other reason:sandboxMerchants from the response rather than parsing the message. Host matching
covers subdomains and ignores a leading www..Widen the net with allowedDomains
Widen the net with allowedDomains
target.allowedDomains is checked by the same gate, not just target.url. Naming a real
merchant there produces the same 403, with that host named as the offender.This matters because allowedDomains is what widens the engine’s navigation guard.
Checking only the target URL would leave a route straight off the sandbox store — start
at the sandbox host, declare a real merchant as an allowed domain, and walk over.Mint a live key (sandbox-only accounts)
Mint a live key (sandbox-only accounts)
POST /v1/api-keys with {"mode":"live"} returns 403:{"mode":"test"} works, and you can create as many test keys as you like.Two separate refusals live here, and both are 403: this one, about the account, and a second
about the credential — a ck_test_ key cannot issue a ck_live_ key even on an activated
account. See minting a live key.Signing up
Response (201)
email is only ever used to reach you if your agents start
doing something alarming. It is not a login — there is no password and no session.
sandboxMerchants is the authoritative list of hosts you may target. Read it from the
response rather than hard-coding it.
Signup limits
This is the one unauthenticated write on the API, so it is rate-limited on two axes:
Signup can also be closed entirely, in which case every request gets
403 Self-serve signup is closed.
The per-IP window is the cheap common case; the daily cap is the backstop that still holds
against a rotating-IP flood.
Testing failure paths
The sandbox is the right place to prove your error handling, and every path is reachable:Reaching real merchants
Two things have to be true: the account must be activated, and the request must use ack_live_ key.
Activating the account
Activation is self-serve, from the dashboard atapp.farthing.ai, and fully automated: hold
a paid plan, verify your identity through Stripe, accept the AUP, and the
workspace flips to live the moment all three are true. No approval queue. The whole journey
is on Going live.
One thing to know before you start: activation is driven from a dashboard workspace. A
tenant created with the curl-only POST /v1/signup below has no dashboard account attached
and cannot be activated — sign up at the dashboard when you intend to go live.
After activation
sandboxOnlyis false, so the account-level refusal onPOST /v1/api-keyswith{"mode":"live"}is gone.- Mint your first
ck_live_key from the dashboard. Ack_test_key still cannot issue a live one — authority passes down, never sideways — but the dashboard session of an activated workspace counts as a live credential, and any live key can mint more. See minting a live key. - Your existing
ck_test_keys are still confined to sandbox merchants. That is not a leftover restriction to work around — it is the point. Keep them for CI and staging. - Point production at a new
ck_live_key. Nothing else in your integration changes. - Quotas still apply: concurrency comes from your plan (Personal 1, Business 5, Scale 15), daily volume defaults to 200 per 24 hours on every plan, and Personal caps a single checkout at $200. See Pricing — the daily cap is raisable per-account.