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