Skip to main content

Errors

Every error returns the same JSON body. Branch on code when you recognize it, fall back to type when you don't, and handle the cases in Handle common errors.

The error body​

An error body
{
"type": "failed_precondition",
"code": "quote_stale",
"message": "quote expired before it landed; request a new quote",
"request_id": "7b1f0c2e-5a9d-4e36-8f10-2d4c6b8a9e31"
}
FieldMeaning
typeThe category of error. There is a fixed set of types, and each one maps to one HTTP status.
codeThe specific condition, such as quote_stale. We add codes over time, so handle the ones you know and fall back to type for the rest. Omitted when no specific condition applies.
messageA description for people. Don't branch on it, because the wording can change.
request_idOur id for the request. Include it when you write to support. Send your own X-Request-Id header and we use that instead.
field_violationsOn invalid_argument, the fields that failed validation and why.
metadataExtra string values for the code. Which keys appear depends on the code.

Status for each type​

typeStatus
invalid_argument400
unauthenticated401
permission_denied403
not_found404
method_not_allowed405
conflict409
failed_precondition422
resource_exhausted429
internal500
unavailable503

Handle common errors​

You seeDo this
401Check the token and, for a Gateway call, the TM-On-Behalf-Of header. Mint or refresh the token once; retrying without a change fails the same way.
422 with quote_staleThe quote expired. Place the order again and execute right away.
201 with an empty order_idNo order was created, and quote.issues says why. Usually the wallet can't fund the buy: fund it and place the order again.
422 with insufficient_balanceThe wallet can't fund a sell or perpetual order. Fund it, then place the order again.
409 with already_submitted on executeThe transaction already landed. Don't resubmit; read the order.
429You sent too many requests. Back off, then retry. Your token is still valid.
503 when you create a userRepeat the same request. It finishes creating the wallets.
500 or 503 on other callsRetry with backoff. If it keeps failing, send us the request_id.

Next: the API reference has the responses for each endpoint.