限流与重试
OpenAPI 会限制过于频繁的请求,以保护服务和设备通信稳定性。客户端不应依赖固定的请求额度,而应正确处理服务端返回的限流信息。
触发限流
触发限流时,服务返回:
- HTTP 状态码
429 - 错误码
RATE_LIMITED Retry-After响应头,单位为秒data.retryAfterSeconds,与Retry-After含义一致data.rateLimitScope,表示触发限制的计数范围,不是 API Client 权限
实时刷新和设备控制比普通查询受到更严格的频率保护。需要同时改变多个继电器时,请将操作放在同一个 relays 数组中,不要拆成连续请求。
409 DEVICE_BUSY 与限流不同:它表示该设备已有一条通讯正在执行。等待当前操作完成后再试,不要并发重试。429 RATE_LIMITED 表示请求间隔过短或累计调用量超限,应按响应中的等待时间重试。
被 429 拒绝的请求不会继续消耗额度,也不会延长当前限流窗口。同一个 API Client 的多个服务实例共享端点额度;持续并发重试可能在窗口恢复后立即再次用完额度。
Idempotency-Key
Idempotency-Key 是调用方为一次命令请求生成的唯一请求键。
它用于处理 HTTP 连接中断、客户端等待响应超时等结果未知场景:如果客户端没有收到可解析的 OpenAPI 响应,无法确认请求是否已被接受,可以使用同一个 Idempotency-Key 重试相同请求,避免重复创建命令。
命令对象的 TIMEOUT 是原命令的终态,不等同于 HTTP 请求超时。此时再次使用相同 key 只会返回同一个 commandId 和结果,不会再次向设备发送命令。确认需要执行一次新的设备操作后,应生成新 key;对于有副作用的操作,应先确认设备状态并评估重复执行风险。
使用规则:
- 每次新的命令请求应生成新的
Idempotency-Key - 未收到明确 OpenAPI 响应时,重试同一次命令请求应复用原来的
Idempotency-Key - 同一个
Idempotency-Key不应复用于不同设备、不同命令或不同请求体 Idempotency-Key不是访问令牌,也不用于身份认证
客户端处理
- 收到
429后,按Retry-After或data.retryAfterSeconds指定的时间重试 - 收到
409 DEVICE_BUSY后,等待当前设备操作完成并使用退避重试 - 收到
500 INTERNAL_ERROR时,可使用有上限的指数退避重试 - 对有副作用的命令接口,重试必须复用原来的
Idempotency-Key - 多个服务实例应协调退避,避免同时再次发送请求
- 除
DEVICE_BUSY外,遇到400、401、403、404、409或422时,不应在不修改请求或凭证的情况下重试
响应示例
http
HTTP/1.1 429 Too Many Requests
Retry-After: 1json
{
"code": "RATE_LIMITED",
"message": "Too many requests",
"requestId": "req_001",
"data": {
"retryAfterSeconds": 1,
"rateLimitScope": "endpoint",
"limit": 30,
"windowSeconds": 60
}
}旧响应中的 data.scope 暂时保留用于兼容,新的客户端应使用 data.rateLimitScope。权限不足会返回 403 AUTH_SCOPE_DENIED 和 data.requiredScope,与限流范围无关。
