Error reference
Every non-2xx response carries error.code (stable, machine-readable), error.message (human-readable, subject to copy edits), and an optional error.details object.
Response shape
{
"error": {
"code": "amount_below_min",
"message": "Minimum amount is 0.05 xmr for this pair",
"details": {
"min_amount_from": "0.05",
"your_amount_from": "0.01"
}
}
} Branch on error.code, not error.message. Codes are versioned (additive only within v1); messages are not.
400 Bad Request
| Code | When |
|---|---|
| invalid_parameter | Missing or malformed query parameter / header value. |
| idempotency_conflict | Same Idempotency-Key seen earlier with a different query string. Pick a fresh key. |
401 Unauthorized
| Code | When |
|---|---|
| auth_invalid_key | API-Key header present but unrecognized or revoked. |
404 Not Found
| Code | When |
|---|---|
| pair_not_supported | The ticker_from / ticker_to / network_from / network_to combination is not in /api/v1/pairs. |
| trade_not_found | /trade lookup against an unknown trade_id. |
409 Conflict
| Code | When |
|---|---|
| quote_expired | Fixed-rate /new_trade against a rate ID past its expires_at. Re-quote. |
422 Unprocessable Entity
| Code | When |
|---|---|
| amount_below_min | amount_from is below the pair minimum. details.min_amount_from carries the bound. |
| amount_above_max | amount_from is above the pair maximum. details.max_amount_from carries the bound. |
| address_invalid | address or refund failed server-side format validation. For Bitcoin, this includes bech32 / base58check checksum failures. |
| address_blocked | Returned only if the operator has registered a ScreenerPlugin (Spec 11) and the plugin flagged the address. Default v3 build never returns this. |
| asset_unavailable | Self-fill is currently disabled for the requested source asset (operator-side control). |
429 Too Many Requests
| Code | When |
|---|---|
| rate_limit_exceeded | Caller is over their rate-limit class. Retry-After header advises wait time. |
503 Service Unavailable
| Code | When |
|---|---|
| pricing_stale | The internal pricing feed is unhealthy and quoting would be unsafe. Transient; retry in 30-60s. |
| fixed_rate_unsupported | ?payment=true requested. MVP is floating-rate only. |
| no_route_available | No provider (self-fill or partner) can fill this swap right now. |
| route_unavailable | The chosen provider can no longer fill mid-flight (mid-creation only). |
| screening_unavailable | Returned only if the operator has registered a ScreenerPlugin and the plugin is reporting unhealthy or threw. Retry the request; alert the operator if sustained. |
Stability
Within /api/v1, codes are additive only. New codes may appear; existing codes never change meaning or get repurposed. Breaking changes ship behind /api/v2.
If a code disappears (or a 5xx you've never seen surfaces in production), that's a bug — please open an issue.