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.
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.
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.
