API Reference
Errors
The semantic error codes and their HTTP mapping.
Every failure uses the error envelope. The error.code is a stable semantic token; the HTTP status is its transport mapping.
Error envelope
{
"ok": false,
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "human-readable summary",
"details": {}
},
"meta": { "result_type": "error" }
}| Field | Type | Rules |
|---|---|---|
error.code | string | Stable semantic error token. Always present. |
error.message | string | Human-readable summary. Always present. Not stable; do not branch on it. |
error.details | object | null | Optional structured detail. MAY be omitted or null. |
Semantic codes
error.code | HTTP status | Meaning |
|---|---|---|
VALIDATION_ERROR | 400 | Request was malformed: non-object body, unknown field, unexpected null, or a field that failed the documented contract. |
FORBIDDEN | 403 | The caller is authenticated but not authorized for the requested action or resource. Returned when a request targets a resource outside the caller's authorized merchant scope, or when an action requires elevated authorization that the credential does not carry. |
NOT_FOUND | 404 | A singleton selector did not resolve to an existing resource. |
PRECONDITION_FAILED | 409 | The request was well-formed but the resource's current state does not satisfy a required precondition. |
CONFLICT | 409 | A mutation was attempted on a resource that no longer permits it — for example, a duplicate resource or a transition from a terminal state. |
IDEMPOTENCY_CONFLICT | 409 | An idempotency key was reused with a different request payload. The original request's outcome cannot be extended to the new input. |
SESSION_BLOCKED | 409 | A checkout session or operation was blocked by pre-deposit compliance screening (geoblock or bot detection). |
RATE_LIMITED | 429 | The caller exceeded the allowed request rate. |
DEPENDENCY_UNAVAILABLE | 503 | An upstream dependency required to complete the request was unavailable. |
TIMEOUT | 504 | The request could not be completed within its time bound. |
INTERNAL_ERROR | 500 | An unexpected internal failure. No recoverable action for the caller; treat as transient, back off and retry, and contact support if the condition persists. |
Code preservation
- The semantic
error.codeis always preserved. Branch onerror.code, never on HTTP status alone or onerror.message. - A code not listed above is still returned verbatim in
error.code. Its exact HTTP status is not guaranteed by this table; the code remains authoritative. - Branch on
okfirst, then onerror.code.
Rate limiting — RATE_LIMITED
A caller that exceeds the allowed request rate is rejected with error.code RATE_LIMITED and HTTP 429.
- The response carries a
Retry-Afterheader: the number of whole seconds to wait before retrying. Honour it — retrying sooner is rejected again and counts against the per-source-IP ceiling. - The body is the standard error envelope. It does not disclose which limit was exceeded or the configured ceiling; pace retries off
Retry-After, not off the message. - On a retry, supply the endpoint's
idempotency_keywhere one is offered so a retry after a429cannot create a duplicate resource. See Idempotency.
A well-behaved client waits for Retry-After, then applies exponential backoff with jitter if a retry is itself rejected, and caps total retries rather than retrying indefinitely. The dimensions limiting is measured against and the published numbers are documented in Reference › Rate limits.