限流
百居易在三层做限流,避免单一调用方影响整体稳定性。命中后会返回 HTTP 200,响应体里 error_code: 429,响应头里 Retry-After(秒)。
第 1 层 —— 账号级
按百居易账号维度,覆盖 v3 所有接口——不是按单个 Access Token。同一账号下签发的
所有 token 共用这一份额度,无论是你在后台自己创建的,还是通过 OAuth 授权得到的。
多建一个 token 不会多一份额度。
| 时间窗口 | 上限 |
|---|---|
| 1 分钟 | 1,200 |
| 10 分钟 | 6,000 |
| 1 小时 | 20,000 |
| 24 小时 | 100,000 |
四个窗口同时校验——任意一个被破,整体即触发 429。
单 token 收紧(默认不启用)
在账号级额度之上,还可以给某一个 token 单独设更紧的每分钟 / 每小时上限。默认所有 token
都没有这个上限,只有百居易主动配置才生效——它的用途是「按住一个失控的集成」,而不必连累
同账号下其他集成。
它只收紧、不放宽:账号级与接口级限流照常叠加生效。命中单 token 上限时,响应头
X-RateLimit-Scope 为 token。若怀疑自己的某个 token 被收紧了,请联系客服——
这个值不通过 API 暴露。
第 2 层 —— 账号 + 接口级
按 (账号, 路由模板) 维度限流,账号口径与第 1 层相同:
分桶用的是路由模板而不是真实 URL:所有 POST /v3/conversations/{id} 调用共用一个桶,
换不同的会话 id 并不会换桶,把洪峰打散到多个 id 上并不能绕开这一层。
| 接口 | 1 分钟 | 10 分钟 | 1 小时 | 24 小时 |
|---|---|---|---|---|
POST /v3/availabilities | 120 | — | — | — |
POST /v3/listings/*(价格 / 库存 / 限制 / 日历) | 120 | — | — | — |
GET /v3/listings/airbnb/price_and_rules(实时读取 Airbnb) | 120 | — | — | — |
POST /v3/reservations | 60 | — | — | — |
| 其他所有接口 | 600 | 3,000 | 10,000 | 50,000 |
横线表示该窗口不限制(但账号级限流仍然生效)。
第 3 层 —— POST /conversations/{id} 线程级限流
POST /conversations/{id} 线程级限流向房客发消息按 会话维度 限流(与账号 / Token 额度彼此独立),因为 OTA 渠道侧通常对消息接口有严格限流,百居易必须保护渠道账号不被封禁:
| 时间窗口 | 单会话最多消息数 |
|---|---|
| 5 秒 | 5 |
| 60 秒 | 10 |
| 30 分钟 | 30 |
| 2 小时 | 60 |
| 24 小时 | 120 |
五个窗口同时校验。请据此设计你的消息模板和 HostGPT 自动回复频率。
第 4 层 —— 无效调用配额
与上面按请求数计的限流相互独立:同一接口上重复的客户端错误另有一份配额,
按 (账号, 路由模板) 计:
| 时间窗口 | 最多失败请求数 |
|---|---|
| 1 小时 | 500 |
| 24 小时 | 2,000 |
只计 400(请求有误)与 404(找不到)。这两种结果的共同点是:同样的请求再发一次
也永远不会成功,重试只是在消耗你和百居易两边的容量,不会有任何进展。
刻意不计 401、403、420 与 429。尤其是 429 不会计入本配额——被限流本身
不会延长你的封禁时间。
被本配额拦下时,响应带 X-RateLimit-Scope: endpoint_error:
{"error_code":429,"error_msg":"Too many failed requests to this endpoint. These requests cannot succeed as sent; fix the request instead of retrying.","request_id":"RT..."}
配额与其他限流一样按固定窗口边界重置;配额耗尽之前,同一接口上成功的调用不受任何影响。
正确的处理是改对请求,而不是等一等再重试——两种 404 的区分见
错误码。
命中限流时的响应
HTTP/1.1 200 OK
Retry-After: 60
X-RateLimit-Scope: user # "user" 即账号级;另有 "endpoint"、"token"、"endpoint_error"
X-RateLimit-Window: 1m
X-RateLimit-Reason: user rate limit exceeded: 1200 requests per 1m
{"error_code":429,"error_msg":"Too Many Attempts.","request_id":"RT..."}
X-RateLimit-Scope 只报解封最晚的那一个桶。同时破了多个桶时,另外几个不会出现在响应里,
解决了这一个之后可能立刻撞上下一个。
第 3 层(消息线程级)会在响应体里明确告知何时可以重试:
{"error_code":429,"error_msg":"Too many requests. Try again in 60 seconds.","request_id":"RT..."}
如何避免被限流
- 请求带上有意义的
User-Agent——例如MyCleaningApp/1.2.3 ([email protected])。这有助于百居易识别合法集成方、绕过 IP 层防爬虫,遇到问题时也方便值班同事联系到你。 - 字典类接口积极缓存。
GET /custom_channels、GET /income_items、GET /expense_items、GET /income_methods、GET /expense_methods、GET /tags、GET /groups变更很少,最多 1 小时拉一次,不要每次创建订单都重新拉一遍。 - 能批量就批量。
POST /listings/prices支持数组——按 "渠道房源 × 日期段" 一次提交,不要每天一调。 - 重试时加抖动。 收到
429后按Retry-After指数退避,再叠加 ±25% 随机抖动,避免下一个窗口开闸瞬间的踩踏。 - 不要轮询 Webhook 能告诉你的事情。 订阅 Webhook 比每分钟轮询
GET /reservations高效得多,事件延迟 < 5s。 - 写后查用
id过滤。 写完一条记录后用GET /reservations?id=…重新拉单条,比重新拉整页列表轻得多。
不属于限流的 "类 429"
| 错误 | 看起来像 429,但不是 |
|---|---|
420 Subscription expired / Basic edition | 账号层面问题,不要重试——只能由房东到后台处理。 |
429 Too many attempts. 来自 /oauth/authorizations | OAuth 暴力破解保护,不是用户级限流。client_secret / code_verifier 在 10 分钟内累计 10 次失败后会被锁定。 |
