Appearance
通用约定
请求与响应
- 请求体与响应体均为 JSON(UTF-8)。发送请求体时请带
Content-Type: application/json。 - 字段名使用 lowerCamelCase;枚举值使用大写下划线(如
ONE_TIME_ADDRESS)。 - 请求体中未定义的字段会被忽略(不会报错),请注意拼写。
- ID(
walletId、交易id等)为 UUID 字符串(按时间递增的 UUIDv7)。 - 成功状态码:
200 OK;创建回调端点201 Created;POST /v1/wallets、POST /v1/transactions、POST /v1/webhooks/{id}/test为202 Accepted(异步处理);DELETE /v1/webhooks/{id}为204 No Content(无响应体)。
金额
- 所有金额字段都以
Raw结尾(个别字段例外,见各接口说明),值为最小单位的十进制整数字符串,不带小数点、正负号和科学计数法,例如"1500000"。 - 不要用 JSON 数字传金额;请求中金额格式错误返回
422 BAD_REQUEST(invalid JSON: …)。 - 精度(
decimals)来自GET /v1/supported_assets,换算公式:显示金额 = raw / 10^decimals。例如 USDT(decimals = 6)的"1500000"为1.5;ETH(decimals = 18)的"1000000000000000000"为1。 - 请使用大整数或十进制库(JS
BigInt、Pythonint/Decimal、JavaBigInteger/BigDecimal、Gomath/big)处理,避免浮点误差;数值范围可达 256 位。
时间
所有时间字段为 RFC 3339 格式的 UTC 时间,例如 2026-10-03T04:55:49.123456Z(小数秒位数不固定,请用标准 RFC 3339 解析器)。查询参数中的时间(如 createdFrom)也必须是 RFC 3339(例如 2026-10-01T00:00:00Z),放入 URL 时注意对 + 等字符做编码。
分页
列表按创建时间倒序(新的在前)返回。目前有三种游标形式:
| 接口 | 请求参数 | 响应 | 结束条件 |
|---|---|---|---|
GET /v1/transactions、GET /v1/wallets | limit(1–200,默认 50)、before(UUID) | { "items": [...], "nextBefore": "<uuid>" | null } | nextBefore 为 null。注意:本页恰好满 limit 条时也会返回 nextBefore,下一页可能为空 |
GET /v1/users | limit(1–200,默认 50)、cursor(UUID) | { "items": [...], "nextCursor": "<uuid>" | null } | nextCursor 为 null |
GET /v1/webhooks/deliveries | limit(1–200,默认 50)、before(整数) | { "items": [...] } | 返回条数 < limit;下一页把本页最后一条的 id 作为 before |
翻页时把上一页返回的游标原样放入下一次请求。其余列表接口(资产、网络、钱包资产、钱包地址、回调端点)一次性返回全部数据,不分页。
幂等
会产生资金或资源的接口支持幂等,防止网络超时后重试导致重复操作:
| 接口 | 幂等键 |
|---|---|
POST /v1/transactions | 请求体 externalTxId(推荐);不传 externalTxId 时必须带请求头 Idempotency-Key |
POST /v1/wallets | 必须带请求头 Idempotency-Key |
Idempotency-Key:1–128 个字符,只能包含 A-Z a-z 0-9 _ - : .,否则返回 422 BAD_REQUEST。
规则:
- 幂等记录按 租户 + API Key + 接口 + 幂等键 区分,长期保留。
- 相同幂等键 + 字节完全相同的请求体 → 不会重复执行,直接返回第一次的状态码和响应体。
- 相同幂等键 + 不同请求体 →
409 IDEMPOTENCY_CONFLICT(Idempotency-Key reused with a different request)。重试时务必复用第一次序列化好的请求体字节。 - 第一次请求仍在处理中 →
409 IDEMPOTENCY_CONFLICT(a request with this idempotency key (Idempotency-Key header or externalTxId) is already in progress),稍后用同样的请求重试。 - 第一次请求以不可重试的错误结束(
retryable = false,如余额不足)→ 幂等键被释放,可以用同一个键再次提交(请求体可以修改)。 - 第一次请求以可重试的错误结束(
retryable = true,如INTERNAL)→ 幂等键保持占用;60 秒后用同一个键、同一请求体重试会安全地重新执行,期间重试返回第 4 条的409。 externalTxId在租户内全局唯一(不区分 API Key):用另一个 API Key 提交已存在的externalTxId返回409 IDEMPOTENCY_CONFLICT(externalTxId already used)。
其他写接口本身就是幂等的:POST /v1/users 与 POST /v1/users/{customerRefId}/deposit_address 按 customerRefId 去重,重复调用返回同一用户/同一地址。POST /v1/webhooks 不幂等,重复调用会创建多个端点。
超时怎么办
提现请求超时后,不要换一个新的 externalTxId 重试,而是用原请求体原样重试,或先 GET /v1/transactions/external_tx_id/{externalTxId} 查询是否已创建。
限流
| 维度 | 限制 | 超出 |
|---|---|---|
| 每个 API Key | 每秒请求数,默认 50,可在控制台设为 1–1000 | 429 RATE_LIMITED |
| 每个用户新建钱包 | 24 小时内最多 5 个(租户可配置) | 429 RATE_LIMITED(too many wallets created in the last 24 hours) |
| 终端用户两步验证码 | 每用户 15 分钟内最多 10 次校验 | 429 RATE_LIMITED |
收到 429 时请指数退避后重试(每次重试都要重新签名)。
请求大小与超时
| 项目 | 限制 | 超出时 |
|---|---|---|
| 请求体 | 256 KiB | 422 BAD_REQUEST(body too large);超过 1 MiB 时为 HTTP 413,错误码同为 BAD_REQUEST |
| 服务端处理时间 | 30 秒 | HTTP 408,错误码 PROVIDER_UNAVAILABLE(retryable = true) |
POST /v1/users/{customerRefId}/deposit_address 在地址分配中时最多会等待约 6 秒再返回,请把客户端超时设为 30 秒以上。
错误响应
所有错误(4xx/5xx)都返回统一结构:
json
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "insufficient available balance",
"retryable": false,
"requestId": "a24ccbad-daca-4385-bf07-dd6b07768a9f"
}
}| 字段 | 说明 |
|---|---|
code | 稳定的机器可读错误码,程序应据此分支,完整列表见 错误码 |
message | 面向开发者的英文描述,可能调整,不要用于程序判断 |
retryable | true 表示原样重试可能成功(限流、服务暂不可用、内部错误),false 表示需要修改请求或业务条件 |
requestId | 请求 ID,与响应头 X-Request-Id 相同。联系平台排查问题时请提供 |
请求 ID:每个响应(包括成功响应)都带 X-Request-Id 头。你也可以在请求中自带 X-Request-Id(例如你方的链路追踪 ID),平台会沿用它。
HTTP 状态码与错误码:HTTP 状态码由错误码决定(对照表见 错误码)。需要特别注意 BAD_REQUEST:
| 来源 | HTTP | 示例 |
|---|---|---|
请求体 JSON 错误、字段校验失败、缺少 Idempotency-Key 等业务校验 | 422 | invalid JSON: missing field `assetId` 、customerRefId must be 1-128 chars |
| 路径参数或查询参数无法解析(在认证之前就会返回) | 400 | Invalid URL: Cannot parse `id` …、Failed to deserialize query string: … |
| 方法不支持 | 405 | method not allowed |
| 请求体超过 1 MiB | 413 | request body too large |
请按 error.code 而不是 HTTP 状态码做程序判断。
未知路径返回 404 NOT_FOUND(route not found)。