AllSwap

錯誤與速率限制

Allswap API 的所有錯誤都會回傳簡潔 JSON 信封。error 字串給機器處理;可選的 detailupstream 欄位用於定位 provider 側失敗。

錯誤信封

{
  "error": "unknown originAsset/destinationAsset",
  "detail": "originAsset or destinationAsset is not available in /v1/assets",
  "upstream": {
    "status": 404,
    "path": "POST /aggregate/quotes"
  }
}

常見錯誤碼

錯誤碼HTTP含義可以重試?
origin not allowed403請求 Origin 不在允許列表。
body too large413POST 請求體超過允許大小。先修
unknown originAsset/destinationAsset400某個 CAIP-19 資產 ID 不在可路由資產列表中。先修
no provider supports this pair404目前沒有 provider 能路由這組 originAsset 到 destinationAsset。
amount_too_low400低於該交易對的 provider 最小可交易金額。先修
amount_too_high400超過該交易對目前流動性上限。先修
providerId required (route_A | route_B)400建立訂單需要傳入報價預覽中選定的 provider。先修
missing txHash400提交入金記錄時必須提供來源鏈交易哈希。先修
order not found404訂單 ID 不存在,或目前呼叫方不可見。
order already in terminal state410訂單已經是 SUCCESS、REFUNDED 或 FAILED。
rate limit exceeded429請求預算已耗盡。降低頻率後再試。退避
upstream timeout504路由 provider 未在逾時內回應。退避
upstream error502路由 provider 回傳了非預期錯誤。退避
internal error500Allswap 內部處理失敗。聯絡支援時請附上回應詳情。退避

速率限制

每個金鑰有兩個限制:每分鐘請求數(RPM,控制突發)和 每月報價次數(檔位月配額)。具體檔位數字見 定價頁

每條回應都包含目前 RPM 桶的狀態:

X-RateLimit-Limit:     300
X-RateLimit-Remaining: 248
X-RateLimit-Reset:     1718983261

當你打到 0,下一次請求回傳 429 rate_limited,帶 Retry-After header(秒)。務必遵守。

重試策略

按類別建議做法:

  • 輸入問題unknown originAsset/destinationAssetproviderId requiredmissing txHash):先修請求;重複提交同一 payload 只會浪費配額。
  • 不支援的交易對:不要立即重試。重新整理 /v1/assets/v1/swappable-targets,仍不可用就從 UI 中移除該路線。
  • 429 rate limit:等待後再試。用伺服器端節流,避免單個使用者耗盡整個整合的共享預算。
  • 5xx / upstream 失敗:帶抖動的指數退避。建議 base = 500ms、cap = 8s、最多重試 4 次。
  • 訂單終態:訂單進入 SUCCESSREFUNDEDFAILED 後,新使用者動作應建立新訂單。

參考:退避偽碼

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++;
    }
  }
}