Error Codes
Details
When a request fails, the API answers with an RFC 7807 problem details object. The detail field carries a human-readable explanation. Because we reserve the right to reword that text, failures that originate upstream (the Chainflip quoting service or broker) also carry a code field: a stable, machine-readable identifier your client can branch on. The HTTP status follows the code: a request Chainflip rejects as unfulfillable answers 400, a temporary upstream condition answers 503, and only unclassified failures answer 500.
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
"title": "Service Unavailable",
"status": 503,
"detail": "One of the assets in this swap is currently disabled on Chainflip",
"traceId": "00-6e04726aca44787669d57a48b1833007-ddd09a1fe1f24426-00",
"code": "asset_disabled"
}
code is a top-level member next to title, status and detail. It is always lowercase snake_case. Codes are contract: once published, a code is never renamed or reused with a different meaning. New codes may be added over time.
Where code appears
code is emitted on the failure responses of:
- Asking for a Quote (
/quotes,/quotes-native, and the deprecated/quote,/quote-native) - Starting a Swap (
/swap, bothGETandPOST) - The vault swap transaction payload endpoints (
/tx-payload/bitcoin,/tx-payload/evm,/tx-payload/solana,/tx-payload/tron)
It is not present on:
- Input validation failures, which use the validation problem details shape with an
errorsobject. These are also HTTP 400, so on a 400 check forcodebefore assuming anerrorsobject. - Route denial on
/swap(HTTP 403 when a pair is not enabled for your account). Only the quote endpoints carryroute_disabled. - Failures the API could not classify, for example a provider timing out or throwing unexpectedly. These return the same problem details shape with no
codemember. - The dashboard and the MCP endpoint.
Handling code in your client
- Treat
codeas optional. When it is absent, the member is omitted entirely; it is nevernullor an empty string. Fall back tostatusanddetail. - Treat unknown values as "some other failure". New codes will be added without notice; do not fail hard on a value you do not recognise.
- Do not branch on
detail. That text can change. - Use
statusfor the coarse decision andcodefor the fine one.400means the request as sent will not succeed (change the amount or the pair).503means the condition is temporary (retry later, with backoff).500means something unexpected happened on our side or upstream. - Do not retry a
400unchanged. A503is safe to retry.
Catalogue
code | HTTP status | Applies to | Meaning |
|---|---|---|---|
amount_below_minimum | 400 | quote | The input amount does not cover the ingress fee. Try a bigger amount. |
egress_below_minimum | 400 | quote | The output would be under the destination chain's minimum egress amount, usually because of high gas prices. Try a bigger amount. |
egress_fee_not_covered | 400 | quote | The output would not cover the egress fee, usually because of high gas prices. Try a bigger amount. |
insufficient_liquidity | 400 | quote | No quote is available for this amount. Try a lower amount. |
quoting_maintenance | 503 | quote, swap, vault payload | Chainflip quoting is in maintenance mode. Retry later. |
swapping_maintenance | 503 | quote, swap, vault payload | The Chainflip swap service is in maintenance mode. Retry later. |
deposit_channel_failed | 503 | quote, swap, vault payload | The broker could not open a deposit channel. Retry later. |
too_many_channels | 503 | quote, swap, vault payload | Chainflip's open channel cap has been hit. Retry later. |
asset_disabled | 503 | quote, swap, vault payload | Chainflip has switched one of the assets off upstream. Nothing about the amount or route will fix it; retry later or choose another asset. |
upstream_error | 500 | quote, swap, vault payload | An upstream failure the API could not classify further. |
provider_unavailable | 503 | quote | No healthy quote provider is available right now (for example every circuit breaker is open). Retry later. |
request_cancelled | 500 | quote | The caller cancelled the request before the upstream answered. Rarely observable, since the connection is usually already gone. |
route_disabled | 403 | quote | The pair is not enabled for your account. Enable it in your dashboard route configuration, or pick another pair. |
"quote, swap, vault payload" means the code can appear on any of those endpoints, because they all map the same upstream error text. In practice the amount- and liquidity-related codes are mostly seen on quotes, and the channel-related codes on swaps.
Example
A quote request for an asset Chainflip has disabled:
curl --location 'https://perseverance.chainflip-broker.io/quotes-native?apikey=93c2bff017e243f29ffb14e42dccbec8&sourceAsset=usdc.hub&destinationAsset=btc.btc&amount=100000000'
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
"title": "Service Unavailable",
"status": 503,
"detail": "One of the assets in this swap is currently disabled on Chainflip",
"traceId": "00-6e04726aca44787669d57a48b1833007-ddd09a1fe1f24426-00",
"code": "asset_disabled"
}
A quote for an amount that is too large for the current liquidity:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "Bad Request",
"status": 400,
"detail": "There is currently no quote available for this amount, try a lower amount",
"traceId": "00-2f0c3d9b1a5e4c7d8e9f0a1b2c3d4e5f-1a2b3c4d5e6f7a8b-00",
"code": "insufficient_liquidity"
}