Twitter API 错误码与解决办法
X(Twitter)API 的错误分两层:HTTP 状态码(400 到 504)说明故障的类别,JSON 响应体里的 code 或 type 说明具体原因。只有 429 和 5xx 状态码等一等就能恢复。
简短回答: 只有 429 和 5xx 错误值得重试,要么等到 x-rate-limit-reset 给出的时间,要么按递增的间隔重试。其余错误都会一直重复出现,直到你修好请求(400)、密钥(401)、预付余额(402)、应用权限(403、453)或 ID(404)。想用一个密钥、不走 OAuth 读取 X 数据,可以用 Sorsa API:帖子每 1,000 条 $0.014 起,注册即送 100 次免费请求。
- 接口
POST /tweet-info-bulk- 每页条数
- 每次请求 100 条帖子
- 价格
- 每 1,000 条 $0.014 起
#如何读懂 X API 的错误
调用官方 X API 失败时,返回的内容有三部分:HTTP 状态码、JSON 响应体,大多数接口还会带上速率限制的响应头。状态码说明故障属于哪一类,响应体说明具体是哪个原因,响应头则告诉你速率限制何时重置。
X API v2 的响应体结构统一:title、detail 和 type,其中 type 是 https://api.x.com/2/problems/ 下的一个 URI,有时还带 reason,例如 client-not-enrolled。较早的 v1.1 接口,以及 X 自己 v2 文档里的速率限制响应,则改用 errors 数组,里面是带编号的 code 和 message:{"errors": [{"code": 88, "message": "Rate limit exceeded"}]}。代码里请按 type、reason 或 code 分支判断,因为 X 随时可能改写给人看的文字。
200 响应里也可能带错误。一次请求查询多条帖子或多个用户时,如果其中一些已被删除或设为私密,X 会把找到的放在 data 里,其余的列在 errors 数组中,类型是 resource-not-found 或 not-authorized-for-resource。每个响应都要检查 errors,成功的响应也不例外。
抛出异常之前,先把响应体打印出来。在 Python 里,raise_for_status() 只显示状态行,X 官方人员在论坛上也建议开发者改为打印 response.text,因为响应体会指出出问题的参数或设置。
#X API 状态码与各自的解决办法
官方 X API 会返回 11 种错误状态码:其中 5 种(429、500、502、503 和 504)等一等再重试就能恢复,另外 6 种会一直失败,直到你修改请求、密钥、余额或权限。X 的响应码参考(在新标签页打开)列出了其中 10 种,漏掉的是 402。
| 状态码 | 在官方 X API 上的含义 | 解决办法 | 能否重试 |
|---|---|---|---|
| 400 Bad Request | 参数缺失、格式错误或超出范围;响应体的 errors 数组会指出是哪个 | 修正响应体指出的参数 | 否 |
| 401 Unauthorized | X 无法验证调用方:密钥错误或已被撤销、认证方式不对、OAuth 1.0a 签名有误 | 重新生成密钥,使用接口要求的认证方式,同步系统时钟 | 否 |
| 402 Payment Required | 预付的按量付费余额已用完:type 为 credits-depleted | 充值,或改用已充值应用的密钥 | 否 |
| 403 Forbidden | 密钥有效,但这个应用、令牌或账号无权执行该操作 | 查看 reason 或 code:应用登记、权限、访问级别 | 否 |
| 404 Not Found | 帖子、用户或 URL 不存在,或帖子已被删除 | 检查 ID 和接口路径 | 否 |
| 409 Conflict | 过滤流(filtered stream)没有任何规则 | 先添加规则,再连接 | 否 |
| 429 Too Many Requests | 某个速率限制窗口用完(code 88),或达到月度用量上限(usage-capped) | 等到 x-rate-limit-reset;用量上限要等下个计费周期 | 到重置时间后可以 |
| 500 Internal Server Error | X 内部故障(code 131) | 按递增的间隔重试 | 可以 |
| 502 Bad Gateway | X 的前端服务器没有收到后端服务的响应 | 按递增的间隔重试 | 可以 |
| 503 Service Unavailable | X 容量超载(code 130) | 按递增的间隔重试 | 可以 |
| 504 Gateway Timeout | X 的服务器处理请求超时 | 按递增的间隔重试,每次请求少取一些 | 可以 |
400 Bad Request
- 在官方 X API 上的含义
- 参数缺失、格式错误或超出范围;响应体的
errors数组会指出是哪个 - 解决办法
- 修正响应体指出的参数
- 能否重试
- 否
401 Unauthorized
- 在官方 X API 上的含义
- X 无法验证调用方:密钥错误或已被撤销、认证方式不对、OAuth 1.0a 签名有误
- 解决办法
- 重新生成密钥,使用接口要求的认证方式,同步系统时钟
- 能否重试
- 否
402 Payment Required
- 在官方 X API 上的含义
- 预付的按量付费余额已用完:type 为
credits-depleted - 解决办法
- 充值,或改用已充值应用的密钥
- 能否重试
- 否
403 Forbidden
- 在官方 X API 上的含义
- 密钥有效,但这个应用、令牌或账号无权执行该操作
- 解决办法
- 查看
reason或code:应用登记、权限、访问级别 - 能否重试
- 否
404 Not Found
- 在官方 X API 上的含义
- 帖子、用户或 URL 不存在,或帖子已被删除
- 解决办法
- 检查 ID 和接口路径
- 能否重试
- 否
409 Conflict
- 在官方 X API 上的含义
- 过滤流(filtered stream)没有任何规则
- 解决办法
- 先添加规则,再连接
- 能否重试
- 否
429 Too Many Requests
- 在官方 X API 上的含义
- 某个速率限制窗口用完(code 88),或达到月度用量上限(
usage-capped) - 解决办法
- 等到
x-rate-limit-reset;用量上限要等下个计费周期 - 能否重试
- 到重置时间后可以
500 Internal Server Error
- 在官方 X API 上的含义
- X 内部故障(code 131)
- 解决办法
- 按递增的间隔重试
- 能否重试
- 可以
502 Bad Gateway
- 在官方 X API 上的含义
- X 的前端服务器没有收到后端服务的响应
- 解决办法
- 按递增的间隔重试
- 能否重试
- 可以
503 Service Unavailable
- 在官方 X API 上的含义
- X 容量超载(code 130)
- 解决办法
- 按递增的间隔重试
- 能否重试
- 可以
504 Gateway Timeout
- 在官方 X API 上的含义
- X 的服务器处理请求超时
- 解决办法
- 按递增的间隔重试,每次请求少取一些
- 能否重试
- 可以
#402 Payment Required:X API 额度耗尽
官方 X API 返回 402,意味着应用背后的预付余额已经花完,在充值之前,X 会拒绝每一次计费调用。X 的按量付费模式在每次读取时预先扣费,按 X 的价目表(在新标签页打开),每条帖子 $0.005、每个用户 $0.010,而自 2026 年 2 月 6 日起,新开发者只有这一种接入方式。
下面是一位开发者在 2026 年 10 月发到 X 论坛上的响应体:
{
"title": "Payment Required",
"detail": "credits depleted",
"type": "https://api.x.com/2/problems/credits-depleted"
}
type 里的链接没什么用:X 的错误参考里没有 402 这一条,有开发者在 2026 年 7 月到 X 论坛反馈过(在新标签页打开)这个缺口。原因按常见程度排列如下:
- 余额为零,或略低于零。 一次请求可能留下很小的负数余额,在新额度补上之前,X 会拦截调用。请在开发者控制台里购买额度;余额为零或负数时,自动充值不会触发。
- 本周期的消费上限已用完。 你在控制台设置的上限,就是账号在一个计费周期内最多能花的钱。调高上限,或者等到下个周期。
- 密钥属于另一个应用。 如果 Client ID、密钥或 Bearer 令牌来自另一个 Project 里的应用,或者来自较早的开发者账号,那么控制台里明明有余额,每次计费调用也都会失败。有位开发者余额 $20 却收到 402(在新标签页打开),2026 年 10 月就是这个原因。请复制已充值应用的密钥,再重新授权。
GET /2/users/me能调通,只能说明认证通过了。 - 突发流量消耗余额的速度,超过自动充值补充的速度。 X 的价格页面提醒,如果用量能在 5 分钟内耗尽一次充值,额度仍然可能用光。请调高每次的充值金额。
须知
402 和 type 为
usage-capped的 429 都会让付费读取停下来,但原因不同。402 是钱的问题:充值之后,下一次调用就能成功。用量上限是读取量的问题:按量付费在每个计费周期读取 300 万条帖子后停止,超过之后只能等下个周期,或签 Enterprise 合同(每月约 4.2 万美元起)才能恢复读取。
#403 Forbidden、453 与其他权限错误
403 表示 X 接受了你的密钥,但拒绝了这个操作,响应体里的 reason 或带编号的 code 会告诉你哪道门没开;重试永远打不开。最常见的六种如下:
client-not-enrolled(type 为client-forbidden):密钥来自没有挂在 Project 下的应用,或者没有登记该接口所需的访问权限。在开发者控制台里,把应用放进按量付费的 Project,并使用该应用的密钥,这是 X 官方人员在 2026 年 10 月的一个帖子(在新标签页打开)里给出的建议。- 453:"You currently have access to a subset of X API v2 endpoints and limited v1.1 endpoints (e.g. media post, oauth) only."(你目前只能访问 X API v2 的部分接口和有限的 v1.1 接口,例如媒体发布和 OAuth。)调用落在了媒体上传和 OAuth 之外的 v1.1 接口上,
tweepy.API和其他较老的客户端就是这么做的。请改调 v2 接口:Python 里用tweepy.Client,Node.js 里用twitter-api-v2包。 - 261,"Your App cannot perform write actions"(你的应用无法执行写操作):应用被设为只读。把它切换为读写,然后重新生成访问令牌,因为旧令牌仍保留创建时的权限。
- 私密或已封禁的账号:受保护的帖子对应 code 179 或 type
not-authorized-for-resource,已封禁的用户对应 63。你这边做什么都打不开,跳过这一项即可。 - 326,临时被锁定:令牌所属的账号触发了 X 的垃圾信息检测。请登录 x.com,完成 X 显示的验证。
- 写操作时的 226 和 187:触发了 X 的垃圾信息过滤,或是重复发帖。226 的提示有专门的解决办法,见我们的指南:X 为什么提示请求看起来像自动化。
点赞、关注和引用帖子也已在 2026 年 4 月 20 日退出自助接入,所以按量付费的应用现在执行这些写操作,最后都会得到 403。每一种 403 提示及其在控制台里的处理步骤,见我们的指南:X API 403 Forbidden。
#429 和 5xx:靠等待解决的错误
X API 的错误里,只有 429 和 5xx 能靠重试解决,而且必须选对时机:429 等到重置时间,5xx 按递增的间隔重试。
code 88 的 429 表示某个接口的窗口里已经没有剩余请求。每个响应都带有三个响应头,告诉你当前的位置:x-rate-limit-limit、x-rate-limit-remaining 和 x-rate-limit-reset(以秒为单位的 Unix 时间),大多数窗口为 15 分钟。type 为 usage-capped 的 429 是每月 300 万条帖子的读取上限,重置响应头对它不起作用。X 应用和 API 里各项限制分别持续多久,见我们的指南:Twitter 超出速率限制。
5xx 是 X 一侧出了故障:500 和 code 131 是内部错误,503 和 code 130 表示容量超载,502 和 504 是 X 服务器之间的超时。两次尝试之间依次等 1、2、4、8 秒,之后就停下来,并记录响应体。
下面这个处理函数只重试有可能成功的错误,其余一律停下,并把响应体写进异常信息:
import time
import requests
RETRY = {500, 502, 503, 504}
def call_x(url, headers, params=None, tries=5):
for attempt in range(tries):
r = requests.get(url, headers=headers, params=params, timeout=30)
if r.ok:
body = r.json()
for err in body.get("errors", []): # partial errors in a 200
print("skipped:", err.get("detail"))
return body
if r.status_code == 429 and "usage-capped" not in r.text:
reset = int(r.headers.get("x-rate-limit-reset", time.time() + 60))
time.sleep(max(reset - time.time(), 1) + 1)
elif r.status_code in RETRY:
time.sleep(2 ** attempt)
else: # 400-409 and a capped 429: fix the cause first
raise RuntimeError(f"X API {r.status_code}: {r.text}")
raise RuntimeError(f"X API still failing after {tries} tries")
#按编号查 X API 错误码
带编号的错误码来自 v1.1 API,如今仍会出现:在 v1.1 响应里、Tweepy 的报错堆栈里,以及某些 v2 响应体里,比如被限流的调用返回的 code 88。下表中的提示文字和状态码都出自 X 自己,取自它最后一次公布的错误码表(2023 年 5 月存档(在新标签页打开));453 来自开发者在 X 论坛上的反馈。这里没有的错误码,就按上面表格里的状态码来处理。
| 错误码 | X 的提示文字 | 状态码 | 原因与解决办法 |
|---|---|---|---|
| 32 | Could not authenticate you. | 401 | 密钥、令牌或 OAuth 签名有误:重新生成并重新签名 |
| 34 | Sorry, that page does not exist. | 404 | 接口 URL 或 ID 有误 |
| 50 | User not found. | 404 | 账号已删除或改名:用用户 ID 查询 |
| 63 | User has been suspended. | 403 | 你查询的账号已被封禁:跳过 |
| 64 | Your account is suspended and is not permitted to access this feature. | 403 | 令牌所属账号被封禁:向 X 申诉 |
| 87 | Client is not permitted to perform this action. | 403 | 该接口没有向这个应用开放 |
| 88 | Rate limit exceeded. | 429 | 等到 x-rate-limit-reset |
| 89 | Invalid or expired token. | 401 或 403 | 令牌已撤销或过期:重新授权,保存新令牌 |
| 92 | SSL is required. | 403 | 使用 HTTPS 和 TLS 1.2 调用 |
| 99 | Unable to verify your credentials. | 403 | consumer 密钥或令牌密钥有误 |
| 130 | Over capacity. | 503 | 按递增的间隔重试 |
| 131 | Internal error. | 500 | 按递增的间隔重试 |
| 135 | Could not authenticate you. | 401 | 时钟偏差导致 OAuth 时间戳无效:同步时钟 |
| 144 | No status found with that ID. | 404 | 帖子已删除,或 ID 有误 |
| 179 | Sorry, you are not authorized to see this status. | 403 | 作者的帖子设为私密 |
| 185 | User is over daily status update limit. | 403 | 账号的发帖上限已用完:等几个小时 |
| 186 | Tweet needs to be a bit shorter. | 403 | 文本超出长度限制 |
| 187 | Status is a duplicate. | 403 | 已经发过相同的文本:修改内容 |
| 215 | Bad authentication data. | 400 | 没有 Authorization 头,或格式有误 |
| 220 | Your credentials do not allow access to this resource. | 403 | 令牌受限:改用具备所需权限范围的令牌 |
| 226 | This request looks like it might be automated. | 403 | X 的垃圾信息过滤拦截了写操作:放慢频率 |
| 261 | Your App cannot perform write actions. | 403 | 只读应用:设为读写,重新生成令牌 |
| 326 | ...this account is temporarily locked. | 403 | 登录 x.com,解除锁定 |
| 327 | You have already retweeted this Tweet. | 403 | 已经转发过:视为成功 |
| 349 | You cannot send messages to this user. | 403 | 收件人不接受你的消息 |
| 415 | Callback URL not approved for this client App. | 403 | 把准确的回调 URL 添加到应用设置里 |
| 453 | You currently have access to a subset of X API v2 endpoints... | 403 | 调用了 v1.1 接口,或缺少相应访问级别:改调 v2 接口 |
32
- X 的提示文字
- Could not authenticate you.
- 状态码
- 401
- 原因与解决办法
- 密钥、令牌或 OAuth 签名有误:重新生成并重新签名
34
- X 的提示文字
- Sorry, that page does not exist.
- 状态码
- 404
- 原因与解决办法
- 接口 URL 或 ID 有误
50
- X 的提示文字
- User not found.
- 状态码
- 404
- 原因与解决办法
- 账号已删除或改名:用用户 ID 查询
63
- X 的提示文字
- User has been suspended.
- 状态码
- 403
- 原因与解决办法
- 你查询的账号已被封禁:跳过
64
- X 的提示文字
- Your account is suspended and is not permitted to access this feature.
- 状态码
- 403
- 原因与解决办法
- 令牌所属账号被封禁:向 X 申诉
87
- X 的提示文字
- Client is not permitted to perform this action.
- 状态码
- 403
- 原因与解决办法
- 该接口没有向这个应用开放
88
- X 的提示文字
- Rate limit exceeded.
- 状态码
- 429
- 原因与解决办法
- 等到
x-rate-limit-reset
89
- X 的提示文字
- Invalid or expired token.
- 状态码
- 401 或 403
- 原因与解决办法
- 令牌已撤销或过期:重新授权,保存新令牌
92
- X 的提示文字
- SSL is required.
- 状态码
- 403
- 原因与解决办法
- 使用 HTTPS 和 TLS 1.2 调用
99
- X 的提示文字
- Unable to verify your credentials.
- 状态码
- 403
- 原因与解决办法
- consumer 密钥或令牌密钥有误
130
- X 的提示文字
- Over capacity.
- 状态码
- 503
- 原因与解决办法
- 按递增的间隔重试
131
- X 的提示文字
- Internal error.
- 状态码
- 500
- 原因与解决办法
- 按递增的间隔重试
135
- X 的提示文字
- Could not authenticate you.
- 状态码
- 401
- 原因与解决办法
- 时钟偏差导致 OAuth 时间戳无效:同步时钟
144
- X 的提示文字
- No status found with that ID.
- 状态码
- 404
- 原因与解决办法
- 帖子已删除,或 ID 有误
179
- X 的提示文字
- Sorry, you are not authorized to see this status.
- 状态码
- 403
- 原因与解决办法
- 作者的帖子设为私密
185
- X 的提示文字
- User is over daily status update limit.
- 状态码
- 403
- 原因与解决办法
- 账号的发帖上限已用完:等几个小时
186
- X 的提示文字
- Tweet needs to be a bit shorter.
- 状态码
- 403
- 原因与解决办法
- 文本超出长度限制
187
- X 的提示文字
- Status is a duplicate.
- 状态码
- 403
- 原因与解决办法
- 已经发过相同的文本:修改内容
215
- X 的提示文字
- Bad authentication data.
- 状态码
- 400
- 原因与解决办法
- 没有 Authorization 头,或格式有误
220
- X 的提示文字
- Your credentials do not allow access to this resource.
- 状态码
- 403
- 原因与解决办法
- 令牌受限:改用具备所需权限范围的令牌
226
- X 的提示文字
- This request looks like it might be automated.
- 状态码
- 403
- 原因与解决办法
- X 的垃圾信息过滤拦截了写操作:放慢频率
261
- X 的提示文字
- Your App cannot perform write actions.
- 状态码
- 403
- 原因与解决办法
- 只读应用:设为读写,重新生成令牌
326
- X 的提示文字
- ...this account is temporarily locked.
- 状态码
- 403
- 原因与解决办法
- 登录 x.com,解除锁定
327
- X 的提示文字
- You have already retweeted this Tweet.
- 状态码
- 403
- 原因与解决办法
- 已经转发过:视为成功
349
- X 的提示文字
- You cannot send messages to this user.
- 状态码
- 403
- 原因与解决办法
- 收件人不接受你的消息
415
- X 的提示文字
- Callback URL not approved for this client App.
- 状态码
- 403
- 原因与解决办法
- 把准确的回调 URL 添加到应用设置里
453
- X 的提示文字
- You currently have access to a subset of X API v2 endpoints...
- 状态码
- 403
- 原因与解决办法
- 调用了 v1.1 接口,或缺少相应访问级别:改调 v2 接口
#X API v2 的问题类型
在 v2 响应里,type 字段给出原因:X 文档列出了 11 种类型,另外还有一种文档没有写的 credits-depleted。这些 URI 都以 https://api.x.com/2/problems/ 开头。
| 类型 | 含义 | 解决办法 |
|---|---|---|
invalid-request | 400:某个参数有误,列在 errors 里 | 修正该参数 |
resource-not-found | 帖子或用户不存在,常出现在 200 响应里 | 跳过,或检查 ID |
not-authorized-for-resource | 受保护或私密的内容 | 跳过 |
client-forbidden | 带 reason 的 403,通常是 client-not-enrolled | 把应用移入 Project |
credits-depleted | 402:预付余额已用完 | 充值 |
usage-capped | 429:月度用量上限 | 等到下个计费周期 |
rate-limit-exceeded | 429:某个速率限制窗口 | 等到 x-rate-limit-reset |
streaming-connection | 流连接出了问题 | 按递增的间隔重新连接 |
rule-cap、invalid-rules、duplicate-rules | 过滤流规则:数量过多、语法有误、已存在 | 删除、修正或跳过该规则 |
about:blank | 通用错误 | 看状态码 |
invalid-request- 含义
- 400:某个参数有误,列在
errors里 - 解决办法
- 修正该参数
resource-not-found- 含义
- 帖子或用户不存在,常出现在 200 响应里
- 解决办法
- 跳过,或检查 ID
not-authorized-for-resource- 含义
- 受保护或私密的内容
- 解决办法
- 跳过
client-forbidden- 含义
- 带
reason的 403,通常是client-not-enrolled - 解决办法
- 把应用移入 Project
credits-depleted- 含义
- 402:预付余额已用完
- 解决办法
- 充值
usage-capped- 含义
- 429:月度用量上限
- 解决办法
- 等到下个计费周期
rate-limit-exceeded- 含义
- 429:某个速率限制窗口
- 解决办法
- 等到
x-rate-limit-reset
streaming-connection- 含义
- 流连接出了问题
- 解决办法
- 按递增的间隔重新连接
rule-cap、invalid-rules、duplicate-rules- 含义
- 过滤流规则:数量过多、语法有误、已存在
- 解决办法
- 删除、修正或跳过该规则
about:blank- 含义
- 通用错误
- 解决办法
- 看状态码
400 的 errors 数组会指出 X 拒绝的具体取值。下面是 2026 年 10 月 X 论坛上的一个例子:全量归档搜索拒绝了设为请求发出时刻的 end_time:
{
"title": "Invalid Request",
"detail": "One or more parameters to your request was invalid.",
"type": "https://api.x.com/2/problems/invalid-request",
"errors": [
{
"message": "Invalid 'end_time':'2026-10-20T08:04Z'. 'end_time' must be a minimum of 10 seconds prior to the request time.",
"parameters": { "end_time": ["2026-10-20T08:04Z"] }
}
]
}
X 官方人员给出的办法是:把 end_time 设为至少 10 秒之前,或者干脆不传。
#用一个 API 密钥读取 X 公开数据:Sorsa API
如果你出错的调用只是读取公开数据,那么 Sorsa API 这款 Twitter(X)API 与爬虫,能帮你免去这页上大部分麻烦。它只需要在 ApiKey 请求头里放一个 API 密钥,不需要 X 开发者账号、应用、Project 或 OAuth,所以 401 签名错误、client-not-enrolled、453 和 402 都不会出现。你自己的 X 账号也完全不会涉及。
Sorsa API 的所有错误都用同一种响应体结构,{"message": "..."},你会遇到的状态码如下:
| 状态码 | 在 Sorsa API 上的含义 | 解决办法 |
|---|---|---|
| 400 | 参数缺失或格式有误 | 修正参数 |
| 401 | invalid api key | 从控制台重新复制密钥 |
| 403 | missing key in request header,或该密钥的请求次数已用完 | 发送 ApiKey 请求头;充值或升级 |
| 404 | 帖子或账号不存在,或为私密账号 | 检查 ID |
| 429 | 一秒内超过 20 次请求 | 等一秒 |
| 500 | 我们这边出了故障 | 1 到 2 秒后重试 |
400
- 在 Sorsa API 上的含义
- 参数缺失或格式有误
- 解决办法
- 修正参数
401
- 在 Sorsa API 上的含义
invalid api key- 解决办法
- 从控制台重新复制密钥
403
- 在 Sorsa API 上的含义
missing key in request header,或该密钥的请求次数已用完- 解决办法
- 发送
ApiKey请求头;充值或升级
404
- 在 Sorsa API 上的含义
- 帖子或账号不存在,或为私密账号
- 解决办法
- 检查 ID
429
- 在 Sorsa API 上的含义
- 一秒内超过 20 次请求
- 解决办法
- 等一秒
500
- 在 Sorsa API 上的含义
- 我们这边出了故障
- 解决办法
- 1 到 2 秒后重试
2026 年 11 月 2 日,我们向线上 API 发送了与密钥相关的错误请求。请求头写成 Api-Key 而不是 ApiKey,会被当作完全没有密钥,调用返回 403:
curl "https://api.sorsa.io/v3/info?username=error_codes_demo_acct" \
-H "Api-Key: YOUR_API_KEY"
{"message": "missing key in request header"}
请求头写对但密钥错误时,同样的调用返回 401 和 {"message": "invalid api key"}。失败的请求从不计费,文档里的 Sorsa API 错误码(在新标签页打开)页面列出了每个状态码及其原因。
-
获取密钥。 注册后,从控制台复制你的 API 密钥。前 100 次请求免费。
-
一次请求读取最多 100 条帖子。
POST /tweet-info-bulk(在新标签页打开)接收帖子链接或 ID,返回每条帖子及其作者的完整资料。Terminal curl -X POST "https://api.sorsa.io/v3/tweet-info-bulk" \ -H "ApiKey: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"tweet_links": ["2117203385470271488", "2117199027635167232"]}'Response200 OK { "tweets": [ { "id": "2117203385470271488", "full_text": "Two layers in every error: status, then cause.", "created_at": "2026-11-02T09:12:44Z", "lang": "en", "likes_count": 41, "retweet_count": 6, "reply_count": 3, "view_count": 5210, "user": { "id": "1592041833471827968", "username": "error_codes_demo_acct", "display_name": "Error Codes Demo", "followers_count": 1840 } }, { "id": "2117199027635167232", "full_text": "Retry 429 and 5xx. Fix everything else first.", "created_at": "2026-11-02T08:55:20Z", "lang": "en", "likes_count": 27, "retweet_count": 4, "reply_count": 2, "view_count": 3380, "user": { "id": "1592041833471827968", "username": "error_codes_demo_acct", "display_name": "Error Codes Demo", "followers_count": 1840 } } ] } -
用同样的方式查询用户资料。
GET /info(在新标签页打开)按username、user_id或user_link返回一份资料,返回 404 说明账号已不存在或为私密账号。 -
留意余额。
GET /key-usage-info(在新标签页打开)返回剩余请求次数和续期日期,这个检查本身免费。遇到 429 等一秒再重试;密钥有效却返回 403,说明该充值了。
在 Sorsa API 上按 ID 读取帖子,每 1,000 条 $0.014 起,每次请求 100 条帖子;官方 X API 则是每 1,000 条 $5.00,而且按量付费套餐每月读取 300 万条帖子就会停止:
官方 X API
$5,000
读取 100 万 条帖子
每条帖子 $0.005
Sorsa API
$14 起
读取 100 万 条帖子
每 1,000 条 $0.014 起
从 2026 年 11 月 22 日起,官方 X API 还会对随每条帖子返回的作者资料另外计费,每个用户 $0.010(见 X 的通知(在新标签页打开));而 Sorsa API 的每条帖子,都在同一次请求里带有作者的完整资料。Sorsa API 只做读取:发帖、点赞或发私信,这些调用请继续用官方 X API。
#先解决眼前的错误,再迁移你的读取任务
几乎所有 X API 错误都只有两种解法:429 和 5xx 等一等,其余的则要修改请求、密钥、余额或应用权限。如果你的错误来自读取公开的帖子、用户资料或粉丝,就把这些读取迁移到 Sorsa API:一个 API 密钥,报错信息一目了然,所有套餐统一每秒 20 次请求,帖子每 1,000 条 $0.014 起,今天就能用 100 次免费请求试一试。
#常见问题
Twitter API 有完整的错误码列表吗?
X 已不再提供。它目前的参考文档列出了 10 种错误状态码(不含 402)和 11 种问题类型,而带编号的错误码表最后一次公布是在 2023 年,如今只能在网页存档和 GitHub 上的副本里找到。本页的表格把两者合在一起,并补上开发者如今反馈的错误码,比如 453 和 credits-depleted,每一条都附有原因和解决办法。
"Could not authenticate you"(错误 32)是什么意思?
错误 32 表示 X 无法验证请求上的签名或凭据,因此在读取请求内容之前就拒绝了调用方。常见原因有:在控制台里重新生成了密钥,代码里却没更新;用了另一个应用的访问令牌;OAuth 1.0a 签名构造错误。服务器时钟偏差时,code 135 会返回同样的提示。
为什么 Tweepy 会抛出 "403 Forbidden"?
对任何 403,Tweepy 都会抛出 tweepy.errors.Forbidden,X 的错误码在 e.api_codes 里,响应体在 e.response.text 里。code 453 表示你通过 tweepy.API 调用了 v1.1 方法:请改用 tweepy.Client。client-not-enrolled 表示应用不在任何 Project 里,code 261 表示应用被设为只读。
401 和 403 有什么区别?
401 表示 X 无法识别调用方:密钥、令牌或签名有误,修好凭据就能解决。403 表示 X 知道你是谁,但拒绝这个操作:应用的访问权限、登记状态、权限设置或目标账号阻止了它。换新密钥解决不了 403;必须改控制台里的设置,或者改请求。
要避开这些错误,读取 X 数据该用哪个 API?
读取 X 公开数据,用 Sorsa API:请求头里放一个 API 密钥,不需要开发者账号、Project 或 OAuth,所以官方 X API 的 401、402、403 登记类错误和 453 都不会出现。它每次请求返回 100 条帖子,每 1,000 条 $0.014 起,所有套餐统一每秒 20 次请求,失败的请求从不计费。
#我们如何核实
2026 年 11 月 2 日,我们查阅了 X 的开发者参考文档(响应码、速率限制和按量付费价格)、X 存档的 2023 年错误码表,以及上文链接的 X Developers 论坛帖子,其中 X 官方人员解释了 402、client-not-enrolled 和 400 的各种情况。我们向线上的 Sorsa API 发送了不带密钥和带错误密钥的请求,并记录了两个响应。上面的批量响应是一个精简示例,使用演示账号,依据线上 API 参考编写。
来源
- Response codes and errors, X developer docs(在新标签页打开)
- X API rate limits, X developer docs(在新标签页打开)
- X API pay-per-usage pricing, X developer docs(在新标签页打开)
- Twitter API error codes, X developer docs archived May 2023(在新标签页打开)
- X API docs missing HTTP status code 402, X Developers forum(在新标签页打开)
- 402 credits-depleted despite a $20 balance, X Developers forum(在新标签页打开)
- Archive-level API access (client-not-enrolled and a 400), X Developers forum(在新标签页打开)
- X API expansions billing update, X Developers forum(在新标签页打开)
- Error codes, Sorsa API docs(在新标签页打开)