Skip to main content

Error format

Every error response has this body:
code is stable and safe to branch on. message is for people. Two rules hide details:
  • A response with status 500, 502, or 503 always has the message Service temporarily unavailable.
  • A response with status 422 always has the message Transaction rejected during simulation or preflight.
In both cases code still names the cause, such as RpcUnavailable or SlippageToleranceExceeded. No response contains provider logs.

Status codes

The common codes are a partial list. Builders pass on decoded Hedgin program errors, so new codes can appear.

Errors that are not failures

POST /transactions/send and POST /transactions/phoenix/onboard/submit do not return an error when the outcome is ambiguous. Once the signed transaction passes the API’s own checks, an RPC outage or a Phoenix request that fails in flight returns HTTP 200 with status: "unknown", a signature, and a receipt.
After status: "unknown", poll the receipt with GET /transactions/status before you build or retry anything. The transaction may already have landed. See Send and status.

Retry rules

Rate limits

Every request counts against these limits. A rejected request does not use up any of them. All limits refill continuously. The per-IP limit of 60 per minute is lower than the per-key limit, so a bot on one IP address reaches it first. Each server instance counts on its own, so treat these values as ceilings, not as a guaranteed quota. Status polling counts too. Poll every 2 seconds or slower.

Request limits