Errors
Envelope
Every error the gateway itself produces uses one shape:
{
"code": "UPSTREAM_ERROR",
"message": "the aggregator refused: invalid input",
"upstream": { "code": 40101, "msg": "invalid input" }
}code is a stable SCREAMING_SNAKE_CASE token and is the field to branch on. message is human-readable and its wording is not part of the contract. upstream is present only when an engine supplied a body worth relaying, and its shape varies by engine (see Upstream detail).
Code reference
| Code | HTTP | Meaning | Retryable |
|---|---|---|---|
INVALID_REQUEST | 400 | A parameter or body field failed validation | no, fix the request |
NOT_A_PCSX_QUOTE | 400 | An aggregator quote was submitted as an order | no |
INVALID_ORDER_BODY | 400 | PancakeSwap X rejected the order body's schema | no |
QUOTE_NOT_FOUND | 404 | Unknown quoteId | no, re-quote |
ORDER_NOT_FOUND | 404 | Unknown order hash | briefly, after a submit |
QUOTE_EXPIRED | 409 | The quote's validity window closed | no, re-quote |
UPSTREAM_ERROR | 502 | An engine failed or refused; also returned when every engine failed | yes, with backoff |
UPSTREAM_PAYLOAD_INVALID | 502 | An engine's response could not be interpreted | yes, with backoff |
QUOTE_TIMEOUT | 504 | No engine answered inside the time budget | yes |
NO_ENGINE_AVAILABLE | 503 | No engine serves this chain and source selection | yes, or widen sources |
DRAINING | 503 | This instance is shutting down and refuses new work | yes, immediately |
STORE_UNAVAILABLE | 503 | The gateway's quote store is unreachable | yes |
INTERNAL_ERROR | 500 | Defect in the gateway | yes, then report |
Codes originating in PancakeSwap X submission are passed through unchanged so that clients already handling them need no translation:
| Code | HTTP |
|---|---|
ORDER_PARSE_FAIL | 400 |
INVALID_ORDER | 400 |
VALIDATION_ERROR | 400 |
CHAIN_NOT_SUPPORTED | 400 |
INSUFFICIENT_FUNDS | 400 |
QUOTE_EXPIRED | 409 |
TOO_MANY_OPEN_ORDERS | 429 |
CONCURRENT_REQUEST | 429 |
UNAUTHORIZED | 502 |
INTERNAL_ERROR | 502 |
INSUFFICIENT_FUNDS reports that the on-chain pre-flight failed because the swapper cannot cover the input amount, so prompt for a top-up rather than a re-sign. TOO_MANY_OPEN_ORDERS means the swapper has reached its cap on simultaneously open orders; wait for one to settle or expire.
Failures without the envelope
Three classes of failure do not carry the envelope. A parser that assumes code is always present will throw on them.
400with a framework-generated body, when a required query parameter is missing or a parameter cannot be coerced to its declared type (a non-numericchainId, for example).422with a framework-generated body, when a request body does not match the endpoint's schema. Posting a PancakeSwap X candidate to/v1/calldata, or an aggregator candidate to/v1/submit, lands here.401or403with whatever body the edge produces, when a deployment enforces API keys andX-API-KEYis missing or unrecognised. The request never reaches the API, so no code of ours appears.
Parse defensively: read code when the body is JSON with that key, and fall back to the HTTP status otherwise.
Upstream detail
When present, upstream takes one of these forms:
| Shape | Origin |
|---|---|
{"code": 40101, "msg": "invalid input"} | An aggregator rejection, with its own numeric code |
{"errorCode": "INSUFFICIENT_FUNDS", "detail": "…"} | A PancakeSwap X submission rejection |
{"error": "…"} | A PancakeSwap X pricing rejection, or a schema rejection of the order body |
{"status": 502, "body": "<html>…"} | A response that was not interpretable at all, relayed 1:1 for diagnosis |
The upstream object is for diagnosis and logging. Branch on the top-level code.
The field is populated on /v1/calldata, /v1/submit, and /v1/status, where a single engine call either succeeds or fails and its body can be relayed intact. It is absent on /v1/quote.
When every engine fails
If no engine produced a candidate, the outcome depends on why:
- Every leg was cut off by the time budget:
504 QUOTE_TIMEOUT. - At least one leg failed for a reason of its own:
502 UPSTREAM_ERROR, withmessagenaming each engine and its reason, for exampleagg: aborted; pcsx: no market maker quoted.