error key at the top level so you can handle failures uniformly regardless of which resource you are working with.
Error Response Structure
High-level error category. Use this for branching your error-handling logic. See the error types table below.
Machine-readable code that identifies the specific failure within a category. Stable across API versions — safe to
switch on in code.Human-readable description of what went wrong. Intended for logs and debugging — do not display this string verbatim to end users.
Present on
invalid_request errors. Names the specific request field that failed validation, e.g. "fiatAmount" or "successUrl".Unique identifier for this request. Include this value whenever you contact support so the request can be traced on the server side.
Error Types
Each error type maps to a fixed HTTP status code. Match ontype for high-level branching, and code when you need to handle a specific scenario.
| Type | HTTP Status | Description |
|---|---|---|
authentication | 401 | API key is missing, invalid, or revoked |
permission | 403 | API key lacks the required scope for this operation |
invalid_request | 400 | Request body or query parameters failed validation |
not_found | 404 | The requested resource does not exist or does not belong to your account |
conflict | 409 | Idempotency key reused with a different request body |
rate_limited | 429 | Too many requests; back off and retry |
server | 500 | Internal server error on our side |
Common Error Codes
The request body failed schema validation. The
param field identifies which property is missing or malformed. Fix the field and resend — do not retry the same payload.A query string parameter failed validation (e.g.
limit is out of range). The param field names the offending parameter.The payment link referenced by
linkId has been deactivated. You cannot create a checkout session against an inactive link. Reactivate the link from the dashboard or use a different one.The resource with the given ID either does not exist or belongs to a different account. Verify the ID and that you are using the correct API key.
Handling Errors with the TypeScript SDK
The SDK maps everyerror.type from the API to a strongly-typed error class. You can instanceof-check against any of the exported classes, or catch the base CheckoutError to handle everything in one branch.
CheckoutError and exposes the following properties: type, code, status (HTTP status code), message, param (optional), and requestId (optional).
Handling Errors Without the SDK
If you are calling the API directly over HTTP without the SDK, checkres.ok and parse the error object from the JSON body:
Retry Strategy
Not every error warrants a retry. Use the table below to decide:| Status | Action |
|---|---|
429 — rate limited | Retry with exponential backoff starting at 1 second (e.g. 1s → 2s → 4s → 8s) |
500 — server error | Retry up to 3 times with backoff; surface the error to the user if it persists |
409 — conflict | Do not retry with the same body. Check whether the original request succeeded before taking any other action |
400 — invalid request | Do not retry. The request is malformed — fix the payload first |
401 — authentication | Do not retry. Verify your API key is correct and has not been revoked |
403 — permission | Do not retry. The key lacks the required scope — update scopes from the dashboard |
404 — not found | Do not retry. Verify the resource ID and that you are using the right API key |
The requestId Field
Every error response includes a requestId in the error object. This ID uniquely identifies your request in the server logs. When you open a support issue or file a bug report, always include the requestId — it is the fastest way to pinpoint what happened on the server side.