Errors & rate limits
Every Allswap API error returns a compact JSON envelope. The error string is the machine handle; optional detail and upstream fields help your integration team debug provider-side failures.
Error envelope
{
"error": "unknown originAsset/destinationAsset",
"detail": "originAsset or destinationAsset is not available in /v1/assets",
"upstream": {
"status": 404,
"path": "POST /aggregate/quotes"
}
}Common error codes
| Code | HTTP | Meaning | Safe to retry? |
|---|---|---|---|
origin not allowed | 403 | Request origin is not on the allowlist. | No |
body too large | 413 | POST body exceeds the accepted size. | Fix first |
unknown originAsset/destinationAsset | 400 | One of the CAIP-19 asset ids is not in the routable asset list. | Fix first |
no provider supports this pair | 404 | No current provider can route this originAsset to destinationAsset. | No |
amount_too_low | 400 | Below the provider's minimum tradeable amount for this pair. | Fix first |
amount_too_high | 400 | Above the current liquidity ceiling for this pair. | Fix first |
providerId required (route_A | route_B) | 400 | Order creation needs the provider selected from the quote preview. | Fix first |
missing txHash | 400 | Deposit submission needs the source-chain transaction hash. | Fix first |
order not found | 404 | The order id does not exist or is not visible to the caller. | No |
order already in terminal state | 410 | The order is already SUCCESS, REFUNDED, or FAILED. | No |
rate limit exceeded | 429 | Request budget exhausted. Slow down and retry later. | Backoff |
upstream timeout | 504 | A routing provider did not respond in time. | Backoff |
upstream error | 502 | A routing provider returned an unexpected error. | Backoff |
internal error | 500 | Something failed inside Allswap. Include the response details when contacting support. | Backoff |
Rate limiting
Every key has two limits: requests per minute (RPM, burst control) and quotes per month (monthly tier cap). Per-tier numbers are on the pricing page.
Every response includes the current state of your RPM bucket:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 248
X-RateLimit-Reset: 1718983261When you hit zero, the next request returns 429 rate_limited with a Retry-After header (seconds). Honor it.
Retry strategy
What we recommend, by category:
- Input problems (
unknown originAsset/destinationAsset,providerId required,missing txHash): fix the request first; retrying the same payload only burns quota. - Unsupported pairs: do not retry immediately. Refresh
/v1/assetsor/v1/swappable-targets, then remove the route from your UI if it is still unavailable. - 429 rate limit: wait before retrying. Use server-side throttling so a single user cannot exhaust the integration's shared budget.
- 5xx / upstream failures: exponential backoff with jitter. Suggested base = 500ms, cap = 8s, max 4 retries.
- Terminal order states: once an order is
SUCCESS,REFUNDED, orFAILED, create a new order for any new user action.
Reference: backoff in pseudocode
async function withRetry<T>(fn: () => Promise<T>): Promise<T> {
let attempt = 0;
while (true) {
try {
return await fn();
} catch (err: any) {
const code = err?.body?.error?.code;
const status = err?.status;
if (status === 429) {
const wait = Number(err.headers["retry-after"] ?? 1) * 1000;
await sleep(wait);
continue;
}
const retriable = code === "upstream_timeout" || code === "internal_error";
if (!retriable || attempt >= 4) throw err;
const base = Math.min(8000, 500 * 2 ** attempt);
const jitter = Math.random() * base * 0.3;
await sleep(base + jitter);
attempt++;
}
}
}
