# 配额与限流

> Embedded 各接口的限流维度、限流响应契约与客户端重试策略;内测期具体阈值以联调口径为准。

配额与限流处于内测阶段,各维度的具体阈值不在本页给出,一律以联调时对接工程师提供的口径为准。接入请见[联系我们](/docs/mcp-cli/contact/)。

## 限流维度

限流以 `client_id` 为主体计量。当前生效的限流维度如下,阈值在联调时按你的业务规模逐项确认。

| 限流维度 | 说明 | 内测期取值 |
|---|---|---|
| API QPS | 单个 `client_id` 每秒可发起的 API 请求数,覆盖认证、文件上传与转写全部接口。 | 以联调口径为准 |
| 并发转写任务数 | 同一 `client_id` 下同时处于进行中状态(`PENDING` / `RECEIVED` / `STARTED` / `PROGRESS`)的转写任务数量上限。 | 以联调口径为准 |
| 令牌签发频率 | 合作方令牌与用户令牌的签发、续期接口的调用频率。令牌应在有效期内缓存复用,不应在每次业务请求前重新签发。 | 以联调口径为准 |
| 上传并发连接 | 分片上传时,单个客户端可同时打开的上传连接数。分片并发度应控制在该上限内。 | 以联调口径为准 |

## 免费额度

限流与用量额度是两件事:限流约束请求的速率,用量额度约束累计消耗。新接入的 Embedded 开发者拥有 50 台设备连接 + 300 小时转写的免费额度,超出后走按量付费。完整口径见[计费](/docs/embedded/billing/)。

## 限流响应契约

触发限流时,接口返回 HTTP `429`,并携带 `Retry-After` 响应头(单位为秒),指示至少等待多久后再重试。响应体为统一错误结构,字段口径见[错误码](/docs/embedded/errors/)。

  429 限流响应示例
    
  

  
```
HTTP/1.1 429 Too Many Requests
Retry-After: 3
Content-Type: application/json

{
  "code": "IKHO_ERR_RATE_LIMITED",
  "message": "请求频率超出当前配额,请稍后重试。",
  "request_id": "req_7f2e9c"
}
```

以上为内测契约,错误结构与 `Retry-After` 的具体行为以联调时提供的正式文档为准。排查问题时请保留 `request_id`,便于对接工程师定位。

## 重试策略最佳实践

客户端遇到 `429` 或 `5xx` 时,建议按以下顺序决定等待时间:

  
- 响应带 `Retry-After` 时,优先遵守服务端下发的等待时间;
  
- 否则按指数退避计算等待时间,并叠加随机抖动,避免多个客户端在同一时刻集中重试;
  
- 设置重试次数上限,用尽后把最后一次响应交给业务层处理,不要无限重试。

  JavaScript · 指数退避 + 抖动
    
  

  
```
const MAX_RETRIES = 5;
const BASE_DELAY_MS = 1000;
const MAX_DELAY_MS = 30000;

function sleep(ms) {
  return new Promise(function (resolve) { setTimeout(resolve, ms); });
}

async function requestWithRetry(url, options) {
  let resp;
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
    resp = await fetch(url, options);

    // 非限流、非服务端错误:直接返回,交给业务层处理
    if (resp.status !== 429 && resp.status < 500) {
      return resp;
    }
    if (attempt === MAX_RETRIES) {
      break; // 重试次数用尽,把最后一次响应交给上层
    }

    // 优先遵守服务端下发的 Retry-After(秒)
    const retryAfter = Number(resp.headers.get('Retry-After'));
    let delay;
    if (Number.isFinite(retryAfter) && retryAfter > 0) {
      delay = retryAfter * 1000;
    } else {
      // 指数退避:1s、2s、4s,封顶 30s
      delay = Math.min(BASE_DELAY_MS * 2 ** attempt, MAX_DELAY_MS);
    }
    // 全抖动:在 [0, delay] 区间取随机值
    await sleep(Math.random() * delay);
  }
  return resp;
}
```

### 幂等性提示

[提交音频转写](/docs/api-reference/transcription/submit/)接口不做服务端去重:同一段音频重复提交会创建多个转写任务,分别计入并发任务数与转写小时数。对提交类请求重试前,请先确认上一次请求是否已成功创建任务(例如记录已返回的 `transcription_id`,或在业务侧维护自己的幂等键),避免重复任务带来的额度消耗。

## 需要更高额度怎么办

内测期的限流阈值面向联调与小范围试点。如果你的业务需要更高的 QPS、更多并发转写任务或更大的用量额度,可以走企业方案,按业务规模单独约定阈值与结算方式。请通过[联系我们](/docs/mcp-cli/contact/)与团队沟通。
