AllSwap

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

CodeHTTPMeaningSafe to retry?
origin not allowed403Request origin is not on the allowlist.No
body too large413POST body exceeds the accepted size.Fix first
unknown originAsset/destinationAsset400One of the CAIP-19 asset ids is not in the routable asset list.Fix first
no provider supports this pair404No current provider can route this originAsset to destinationAsset.No
amount_too_low400Below the provider's minimum tradeable amount for this pair.Fix first
amount_too_high400Above the current liquidity ceiling for this pair.Fix first
providerId required (route_A | route_B)400Order creation needs the provider selected from the quote preview.Fix first
missing txHash400Deposit submission needs the source-chain transaction hash.Fix first
order not found404The order id does not exist or is not visible to the caller.No
order already in terminal state410The order is already SUCCESS, REFUNDED, or FAILED.No
rate limit exceeded429Request budget exhausted. Slow down and retry later.Backoff
upstream timeout504A routing provider did not respond in time.Backoff
upstream error502A routing provider returned an unexpected error.Backoff
internal error500Something 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:     1718983261

When 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/assets or /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, or FAILED, 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++;
    }
  }
}