错误与限制

Anysite API 可能返回的每一种响应、每种状态的含义、计费规则、超时、分页和速率限制。

目标:正确处理 API 可能返回的每一种响应,并清楚哪些调用会消耗积分。

成功的响应

成功的数据调用响应体始终是 JSON 数组,即使端点返回的是单个实体 —— linkedin/user 返回的是包含 一个元素的列表。没有匹配结果的搜索是正常的 200,响应体为 []。

x-result-count 响应头统计的是你收到的响应体中的结果行数,因此它永远不会超过数组长度。想知道除了 这一页之外还有多少结果,请读取 X-Total-Available-Results(仅在数据源能提供可用总数的端点上)。

一次调用是如何被处理的

检查按以下顺序执行;第一个未通过的检查会返回其错误,且不计费:

  1. 身份验证请求头存在且只有一个 → 否则返回 422。
  2. 密钥有效、套餐未到期、密钥允许用于 REST API → 否则返回 401 / 403。
  3. 端点在你的套餐中可用,且参数不超过套餐允许的最大值 → 否则返回 404 / 529 / 403 / 400。
  4. 余额中有足够的积分 → 否则返回 401。
  5. 速率限制和用量窗口 → 否则返回 429。
  6. 请求在端点上执行;其响应会返回给你,并按 What is charged 中的规则计费。

调用执行前返回的状态

以下状态在请求执行之前返回。这些响应均不计费,响应体的结构是 {"detail": ...}:

{"detail": "Token expired"}

422 返回的是字段错误列表,429 返回一个对象,并附带一个值相同(单位:秒)的 X-Retry-After 响应头:

{"detail": {"message": "Rate limit exceeded: ...", "retry_after": 12}}
状态码 detail 该怎么做
422 缺少必需的请求头 发送 access-token 请求头。
422 Body should be a valid dict object 请求体应为 JSON 对象,而不是数组或标量值。
401 Invalid token 从「订阅与 API」页面重新复制密钥。参见身份验证。
401 Token does not exist 密钥已被删除;请使用另一个密钥。
401 Token expired 套餐已到期;请在「订阅与 API」页面续订。
401 Points limit exhausted, required at least N points 购买更多积分或升级套餐。参见套餐与积分。
403 This token is restricted to MCP usage only and cannot be used for direct API access 改用 MCP 服务器,或选择一个包含 REST API 的套餐。
403 This endpoint is disabled for your plan 选择一个包含此端点的套餐。
400 Parameter 'count' exceeds the maximum allowed for your plan: N 把 count 降到 N 或更低,或分页获取结果。
404 Endpoint was removed 该端点已不存在;请在 API 参考中查找替代端点。
529 This endpoint is temporarily unavailable while we work on a fix. ... 该端点已被我们临时关闭。重试无济于事;如果你依赖它,请从「支持」页面提交工单。
429 object, Rate limit exceeded: scope=..., limit=N requests <window>. ... 等待 retry_after 秒。参见 Rate limits。
429 object, You've reached your <window> usage limit. ... 等待窗口释放额度,或升级套餐。参见 Usage windows。

429 一定来自 Anysite 的速率限制器 —— 端点背后的数据源本身永远不会产生这个状态码。

Statuses from the endpoint

通过检查之后,端点自身的状态码和响应体会原样返回给你。端点的错误响应体通常是空的 JSON 数组 [],但如果调用在出错前已经收集到数据行,这些行会连同错误状态码一起返回;原因在 x-error 响应头中,该响应头只有在状态码为 400 或更高时才会出现:

HTTP/1.1 412
x-error: Failed to fetch URL. Website is not accessible
x-result-count: 0

[]

验证错误是例外:格式错误的请求体会被 422 拒绝,并返回一个指明具体字段的 detail 对象。

状态码 含义
200 成功。响应体是一个数组,可能为空。
209 查找了但没有结果 —— 一次免费的未命中。仅出现在 What is charged 中列出的端点上。
400 你的客户端在结果准备好之前断开了连接。
408 调用超时。参见 Timeouts。响应体中仍可能包含截止前已收集到的数据行。
412 API 的「未找到」:实体不存在、资料是私密的或被限制访问,或者(在 webparser/* 上)目标主机不可达。
415 webparser/* 指向的是 PDF、Office 文档、图片、压缩包或其他非页面文件。
422 模式验证失败(detail 中指明字段)、LinkedIn URN 格式有误(detail 中的 "type": "linkedin_wrong_urn"),或响应过大而无法返回。
500 数据源无法访问,或对它的重试已耗尽。
529 该数据源目前的抓取能力全部繁忙。

API 参考中每个端点只列出它不那么显而易见的状态码 —— 例如 linkedin/user 会返回 412,而不是你可能预期的 404。列表中没出现的状态码并非不可能出现;上面的含义始终适用。

被限制访问的 LinkedIn 资料,只要仍处于限制状态就会一直返回 412 —— 用同一个别名重试不会改变结果。

What is charged

简而言之:

Endpoint response Charged
低于 400 的任意状态码(209 除外) 计费
209 不计费
408、412 计费
其他任意 4xx / 5xx 仅当响应报告了至少一条结果时计费
上述检查产生的任何错误,或响应体为 {"error": "Internal server error"} 的 500 不计费

调用的价格取决于端点和你的套餐,并且在许多端点上会随结果数量增长:每开始一个结果区块就按基础价格 计费一次,因此按每 10 条结果计价的端点,返回 11 条时收费两次,返回 21 条时收费三次。凡是公布了这两个 数字的端点,都可以在 API 参考中看到:x-price 是基础价格,x-increase-every 是区块 大小(没有该字段表示每次调用一口价)—— 有些端点两者都不公布,它们的价格只能在调用后从 x-credits-charged 中看到。 只请求你真正需要的 count:count 越大,可能越贵。少要一些数据同样可能更便宜 —— 在 linkedin/user 上,每关闭一个 with_* 区块都会降低本次调用的价格,而 fast_mode 会提高价格。

无论 API 参考怎么写,一次调用实际扣除的金额以 x-credits-charged 响应头为准 —— 0 表示本次调用 免费 —— 这个金额也会出现在「订阅与 API」页面的请求日志里。

积分优先从套餐积分中扣除,然后才扣除已购买积分。只要余额能覆盖基础价格,调用就会被允许;如果 最终价格更高(例如返回结果更多),余额可能变为负数,负的部分会从你之后追加的积分中扣除。

值得关注的响应头

响应头 含义
x-credits-charged 本次调用花费的积分。0 表示免费。
x-token-points 余额中剩余的积分。
x-result-count 本次响应中的结果行数 —— 即你收到的数组的长度。
x-error 调用失败的原因。仅当状态码为 400 或更高时出现。
x-warning 请求虽然成功,但存在一些问题 —— 参见 Ignored parameters。
x-execution-time 端点处理耗时,单位为秒。
x-request-id 本次调用的 id。在支持工单中引用它。你也可以自己指定它,但必须是合法的 UUID,否则请求会被 422 拒绝。
X-Total-Available-Results 在数据源提供可用总数的端点上,总共可获取的结果数量。

Timeouts

请求体中的 timeout 字段默认值为 300 秒,可接受 20-1500 之间的值。

它是整个调用的时间上限。timeout 到期时仍在运行的调用会以 408 结束,响应体中带有截至 那一刻已收集到的数据行。

请把你的 HTTP 客户端自身的超时设置得比你发送的 timeout 更长 —— 约 1600 秒即可覆盖最大值。 如果客户端在 30 秒或 60 秒就放弃,会中断那些其实仍在正常工作的调用。

curl --max-time 1600 -X POST "https://api.anysite.io/api/linkedin/search/users" \
  -H "access-token: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"keywords": "cto", "count": 100, "timeout": 600}'

ACTION FOR THE HUMAN: copy your API key at https://app.anysite.io/billing — an agent cannot obtain it.

Ignored parameters

请求体中无法识别的字段会被忽略,而不是拒绝。 因此拼错的过滤条件的表现和没有过滤条件完全一样: 你会得到 200 和未过滤的结果,并为此付费。每个被忽略的字段都会列在 x-warning 响应头中(在 MCP 结果中则是 warnings 字段),所以当某个过滤条件看起来没有生效时,检查一下这个响应头。

在每个可能返回多条结果的端点上,count 都是必填的,而且它是上限而不是承诺:请求的数量超过实际 存在的数量时,会返回 200 和更少的结果行。

传入 URL

接受 URL 的端点 —— 个人主页、帖子、公司页面、webparser/* 的目标页面 —— 期望的格式与 API 参考中该参数 examples 里展示的一致。去掉浏览器或分享按钮附加、而示例中没有的 东西 —— utm_source、utm_campaign、fbclid 之类的跟踪参数 —— 然后按示例的形式传入 URL。 URL 中带有多余数据时,端点可能无法正常工作,而调用仍按 What is charged 中的规则计费。

从分享按钮复制的 LinkedIn 个人主页 URL,以及参考文档中个人主页 URL 参数所展示格式的同一个 URL:

# 错误 —— 附带了分享跟踪参数
https://www.linkedin.com/in/satyanadella?utm_source=share&utm_campaign=share_via&utm_content=profile&utm_medium=member_desktop

# 正确 —— 只有主页地址
https://www.linkedin.com/in/satyanadella/

传给 linkedin/post 的帖子 URL 同理:

# 错误
https://www.linkedin.com/posts/agazdecki_if-your-startup-makes-500k-a-year-and-someone-share-7507419518231588864?utm_source=share&utm_medium=member_desktop

# 正确
https://www.linkedin.com/posts/agazdecki_if-your-startup-makes-500k-a-year-and-someone-share-7507419518231588864

分页

大多数端点根本没有分页参数:它们只接受 count,并在内部替你翻页,所以请在一次调用中就请求你需要的 结果数量。少数端点确实接受 offset 或 page —— 具体哪些请看 API 参考 —— 在这些端点上, 每次调用把 offset 增加 count,或者递增 page。不推进就重复这样的调用会返回相同的结果 —— 这通常就是「API 一直给我重复数据」的原因。

重试

Anysite 与数据源之间的传输失败已经替你自动重试过了(带退避间隔)—— 你看到错误之前这些重试已经发生。 这里没有幂等键:如果状态属于计费状态,你自己发起的重试会再次计费。

端点可能被关闭

某个端点即使已经被关闭,仍可能出现在 API 参考中。识别方式是:响应在端点执行之前就返回了 —— 404 Endpoint was removed,或者 detail 中写明该端点正在修复、暂时不可用的 529。重试无济于 事;如果你依赖它,请从「支持」页面提交工单。

detail 中没有这类说明的 529 是另一回事 —— 端点已经执行,只是该数据源的抓取能力正忙。请稍后重试。

Rate limits

套餐以及部分端点会在滚动窗口(10 秒、1 分钟、1 小时、1 天或 30 天)内限制请求数量。任何通过了之前 检查的请求都会计入这些限制,无论最终是否计费 —— 包括免费的 209。达到限制后,API 会返回 429, retry_after 等于窗口中最早那次请求过期所需的秒数。

Usage windows

部分套餐(包括 MCP 套餐)还会在两个滚动窗口内限制消耗的积分:5 小时和每周。部分套餐还会 加上单独的 LinkedIn 5 小时和每周窗口,只统计 linkedin/* 端点,并且跳过路径中含 /sql/ 的数据库 端点。用量是窗口内被计费积分的总和,所以随着较早的调用移出窗口,额度会逐渐释放。

窗口用满后,API 会返回 429,retry_after 等于整个窗口的长度 —— 这是最长的等待时间,实际释放 可能更早。

对于 MCP 套餐,每个窗口当前的用量百分比会显示在「MCP 集成」页面上。

ACTION FOR THE HUMAN: open https://app.anysite.io/mcp (查看 MCP 用量).