速率限制
各套餐在 Listings 和 Social 中的请求限制、429 响应结构,以及如何退避和重试。
Listings API 按账户计量请求,并应用您套餐的速率限制。保持在限制范围内可让您的集成及时响应;超出限制时,API 会返回 429 Too Many Requests,其中包含妥善重试所需的全部信息。
各套餐的限制
想在没有付费套餐的情况下试用 API?启动免费沙盒单日通行证时,您会同时收到 API 密钥及其当前请求限制。
限制取决于套餐,并按账户执行:同一账户下的所有 API 密钥共用同一请求配额。请求按 3 个时间窗口计量:每分钟突发请求限制、每小时限制和每日上限。无论使用哪个端点,每个请求消耗的配额都相同。免费试用采用您选择的套餐,因此从第 1 个请求起就适用该套餐的限制。
Social 共用同一配额
Social 端点与其他所有端点共用同一账户级请求配额。包含 500 行的 POST /social/bulk-posts 只计为 1 次请求,而不是 500 次,因此批量操作是加载大量内容时最节省配额的方式。
Listings 和 Social 是独立的订阅,但并不各自拥有独立配额。同时订阅两者的账户采用两个套餐等级中较高的限制,该限制统一应用于所有端点,既不将两者的配额相加,也不为每个产品单独分配配额。订阅 Listings Launch 和 Social Growth 的客户,其所有流量均按上方列出的 Growth 限制计量。
429 响应
当您超出限制时,API 会返回 HTTP 429 和标准错误响应。有 3 个字段与重试相关:
retry_after_seconds:重试前需要等待的时长。如果响应中有Retry-AfterHTTP 响应头,它的值与此相同。correlation_id:请求标识符,联系支持团队时请提供此标识符。doc_url:指向错误代码参考中rate_limited条目的链接。
{ "error": { "code": "RATE_LIMITED", "message": "Too many requests. Slow down.", "retry_after_seconds": 30, "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c", "doc_url": "https://listingsapi.com/docs/error-codes#rate_limited" }}通过退避处理 429 响应
如果存在 retry_after_seconds,请遵循其指定的等待时长;否则,请采用指数退避:每连续收到一次 429,就将延迟加倍,直至达到上限,并加入少量随机抖动,避免大量客户端同时重试。
import randomimport time import requests MAX_RETRIES = 5 def get_with_backoff(url: str, headers: dict, max_retries: int = MAX_RETRIES): for attempt in range(max_retries): resp = requests.get(url, headers=headers) if resp.status_code != 429: resp.raise_for_status() return resp.json() # Prefer the server's hint; fall back to exponential backoff + jitter. body = resp.json().get("error", {}) retry_after = body.get("retry_after_seconds") if retry_after is None: retry_after = min(2 ** attempt, 30) + random.uniform(0, 1) time.sleep(retry_after) raise RuntimeError("Still rate limited after retrying")保持在限制范围内
- 每次只请求一页:密集的并行分页循环是触发
429最常见的原因。读取pageInfo.hasNextPage,并且仅在当前页返回后才获取下一页。 - 使用
filter查询参数在服务器端筛选,而不是拉取所有页面后再在客户端丢弃不需要的行。 - 缓存不常变化的响应,避免在每次请求时重新获取。