Errors
The gateway's own error model — ten codes scoped to the gateway's concerns, never overlapping a product's own errors.
The One API has its own error shape, used only for errors the gateway itself raises — authentication, entitlement, routing, and provisioning-orchestration. A product's own errors are never reshaped into this; they pass through with the product's own body and status.
The error shape
{
"error": {
"code": "entitlement_denied",
"message": "Human-readable explanation; not for branching.",
"detail": {}
}
}Branch on code, never on message.
The twelve gateway codes
Branch on code, never on message. Some codes map to more than one HTTP status
depending on the situation (shown below); branch on the code, and treat the status as
the transport-level hint.
| Code | HTTP | Meaning | What to do |
|---|---|---|---|
invalid_request | 400 / 409 | A gateway-level validation failure (400), or a state conflict such as dispatching an in-flight batch (409). | Fix the request per the message. |
unauthenticated | 401 | Missing, malformed, expired, or invalid signing credential. | Check your signing — see Sign a request. |
entitlement_denied | 403 | Not entitled to the named product (fail-closed; the product is never touched). | Enable the product — see Entitlements. |
forbidden | 403 / 409 | The acting member's role does not permit the action (403), or the action conflicts with current state (409). | Use an owner/admin credential, or resolve the conflicting state. |
unknown_product | 404 | The named product is not recognised. | Check the product slug in your path. |
unknown_operation | 404 | The route or operation is not recognised on the gateway. | Check the method and path. |
unknown_reference | 404 / 409 / 422 | A referenced resource does not exist (404), conflicts (409), or cannot be resolved for this operation (422) — e.g. a paying holder not bound to a pool. | Check the referenced id; ensure prerequisites (e.g. pool binding) exist. |
context_conflict | 409 | The context binding conflicts with the request. | Reconcile the One-Context you sent — see Contexts. |
available_liquidity_rejection | 422 | The ledger rejected a hold — insufficient available balance or an invalid account. No funds were reserved. | Check the paying account's available balance and id. Safe to retry once funded. |
provision_failed | 502 | The product's provision operation failed, or the service key was rejected. | Transient — retry. If it persists, the rail may be down. |
product_unavailable | 502 / 503 | The product was unreachable; no response was received at all. | Transient — retry with backoff. Nothing was committed. |
rate_limited | 429 | A gateway rate limit was exceeded. | Back off and retry after the indicated window. |
Signing errors carry a docs link
Errors caused by your own signing (unauthenticated from an incomplete envelope, a
timestamp outside the window, a nonce replay, or a signature mismatch) include a
detail.docs_url pointing straight at Sign a request.
Gateway codes never overlap product errors
These ten are scoped to the gateway's own concerns. A product's own error classes are distinct and pass through unchanged — so a code here will never collide with a code a product returns.
Two failures that look similar
forbidden (403) is an authorization failure — your member's role can't perform the
action (only owner or admin may manage members, for example). entitlement_denied (403)
is about product access — you're not entitled to the product at all. Different causes,
different fixes.
Unavailable vs a product error
product_unavailable (502/503) means the gateway could not reach the product — it never
answered. A product that does answer with its own 4xx/5xx has that forwarded
byte-faithfully instead. See Passthrough.
Next
- Authentication — avoiding
unauthenticated. - Entitlements — avoiding
entitlement_denied.
Provisioning
How the gateway onboards you into a product on your behalf using the product's privileged service key.
Register a partner organization (issues a JWT on-ramp + a durable HMAC root) POST
Creates a durable, organization-shaped partner identity, identified by a contact email, with an initial member (the human who signs up, acting on the org's behalf). Sign-up issues TWO credentials against the new identity, both resolving the same partner: a JWT ON-RAMP (fast to integrate, but it EXPIRES) and a durable HMAC ROOT (non-expiring, your recoverable credential). Each credential's secret is returned ONCE in the response — store both securely. Holding the durable HMAC root from sign-up means an expired JWT on-ramp is never a lockout: re-mint a fresh JWT via the root. Issuing further HMAC credentials later is additive, not a re-plumb. Carries no phone and no end-user KYC — those are end-user attributes with no place in a developer/ organization gateway.