Twitter API expansions 与推文作者
官方 X API 返回的帖子只有 ID 和文本;加上 expansions=author_id,作者资料会出现在单独的 includes 块里,而从 2026 年 11 月 22 日起,以这种方式返回的每位作者按 $0.010 计费。
简短回答: 在请求中加上 expansions=author_id 和 user.fields,再把每条帖子的 author_id 与 includes.users 中的用户对应起来。从 2026 年 11 月 22 日起,一条带作者的帖子最高收费 $0.015。Sorsa API 把完整的作者资料放在每条推文里:POST /tweet-info-bulk 每次请求读取 100 条推文,每 1,000 条 $0.014 起,100 次免费请求就够读前 1 万条。
- 接口
POST /tweet-info-bulk- 每页条数
- 每次请求 100 条推文
- 价格
- 每 1,000 条 $0.014 起
#Twitter API 的 expansions 是什么,会返回什么
expansion 是官方 X API v2 的一个请求参数,用来把相关对象(比如作者、图片或被引用的帖子)加进响应里。不加的话,查询帖子只会返回三个字段:id、text 和 edit_history_tweet_ids。作者不在其中,连作者的 ID 都没有。
加上 expansions=author_id 后,每条帖子会多出一个 author_id,响应里则多出一个 includes.users 列表,每位作者一项。这一项默认只有 id、name 和 username。其他内容,比如简介、粉丝数或头像,都必须在 user.fields 里点名。
下表列出开发者最常用的帖子 expansion,以及从 2026 年 11 月 22 日起适用的 X API 价格下各自的费用。每个用户对象的价格,是随它返回的那条帖子的两倍。
| Expansion | 加入 includes 的内容 | 官方 X API,11 月 22 日起每个对象 |
|---|---|---|
author_id | 帖子的作者 | $0.010 |
referenced_tweets.id | 被引用、被回复或被转发的帖子 | $0.005 |
referenced_tweets.id.author_id | 那条帖子的作者 | $0.010 |
in_reply_to_user_id | 被回复的账号 | $0.010 |
entities.mentions.username | 每个被提及的账号 | $0.010 |
attachments.media_keys | 每张图片、视频或 GIF | $0.005 |
attachments.poll_ids | 投票 | $0.005 |
geo.place_id | 标记的地点 | $0.005 |
author_id- 加入
includes的内容 - 帖子的作者
- 官方 X API,11 月 22 日起每个对象
- $0.010
- 加入
referenced_tweets.id- 加入
includes的内容 - 被引用、被回复或被转发的帖子
- 官方 X API,11 月 22 日起每个对象
- $0.005
- 加入
referenced_tweets.id.author_id- 加入
includes的内容 - 那条帖子的作者
- 官方 X API,11 月 22 日起每个对象
- $0.010
- 加入
in_reply_to_user_id- 加入
includes的内容 - 被回复的账号
- 官方 X API,11 月 22 日起每个对象
- $0.010
- 加入
entities.mentions.username- 加入
includes的内容 - 每个被提及的账号
- 官方 X API,11 月 22 日起每个对象
- $0.010
- 加入
attachments.media_keys- 加入
includes的内容 - 每张图片、视频或 GIF
- 官方 X API,11 月 22 日起每个对象
- $0.005
- 加入
attachments.poll_ids- 加入
includes的内容 - 投票
- 官方 X API,11 月 22 日起每个对象
- $0.005
- 加入
geo.place_id- 加入
includes的内容 - 标记的地点
- 官方 X API,11 月 22 日起每个对象
- $0.005
- 加入
这些费率来自 X 在 2026 年 10 月 23 日发布的 expansions 计费通知(在新标签页打开),通知写明,通过 expansions 返回的对象将"按该资源的标准 PPU 费率计费,与直接查询相同"。在此之前,它们在帖子本身的费用之外不收钱。
#用 Sorsa API 一次调用拿到推文和作者
Sorsa API 是一款 Twitter(X)API 与爬虫,它返回的每条推文里都有一个 user 对象:作者的完整公开资料,共 19 个字段,不额外收费。不需要加 expansion,不需要再去拼接第二个列表,也没有按作者计费。用你的 API 密钥发一次请求,就能拿到推文,而且每条推文都已经带着作者。
-
获取密钥。 注册后,从控制台复制 API 密钥。不需要 X 开发者账号,也不涉及 OAuth。
-
发送最多 100 个推文链接或 ID。
POST /tweet-info-bulk(在新标签页打开)接收一组推文 URL 或纯 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": ["1849212213712385091", "https://x.com/kai_builds_tools/status/1849212213712385092"]}'Response200 OK { "tweets": [ { "id": "1849212213712385091", "full_text": "Shipped the new export queue today.", "created_at": "2026-10-24T09:12:44Z", "likes_count": 214, "retweet_count": 31, "view_count": 18402, "user": { "id": "1592041833471827968", "username": "kai_builds_tools", "display_name": "Kai Builds", "description": "Data tooling for small teams.", "followers_count": 1840, "followings_count": 312, "tweets_count": 2291, "verified": false, "created_at": "2022-11-14T08:03:10Z", "location": "Lisbon", "profile_image_url": "https://pbs.twimg.com/profile_images/1/kai.jpg" } } ] } -
直接从每条推文里读取作者。 资料就在
tweet["user"]下,所以遍历这些推文的循环就是全部代码。import requests URL = "https://api.sorsa.io/v3/tweet-info-bulk" HEADERS = {"ApiKey": "YOUR_API_KEY"} def tweets_with_authors(ids): for start in range(0, len(ids), 100): batch = ids[start:start + 100] r = requests.post(URL, headers=HEADERS, json={"tweet_links": batch}) r.raise_for_status() for tweet in r.json()["tweets"]: author = tweet["user"] yield (tweet["id"], author["username"], author["followers_count"], tweet["full_text"])
返回 403 表示密钥缺失或请求次数已用完;返回 429 表示一秒内超过 20 次请求,稍等片刻再重试。失败的请求从不计费。
搜索、时间线、回复和引用返回的推文,也都带有同样的 user 对象。POST /search-tweets(在新标签页打开)每页返回约 20 条推文及其作者,可以用 X 的搜索运算符检索回溯到 2006 年的公开帖子,并返回 next_cursor 用于翻到下一页,直到游标返回为空。
#在官方 X API 上把帖子和作者对应起来
要在官方 X API 上把帖子和作者对应起来,先把 includes.users 按用户 ID 建成字典,再用每条帖子的 author_id 去查。X 的 expansions 指南(在新标签页打开)提到,includes 里的对象不带位置信息,所以 ID 是两个列表之间唯一的联系。
curl -G "https://api.x.com/2/tweets" \
-H "Authorization: Bearer YOUR_BEARER_TOKEN" \
--data-urlencode "ids=1849212213712385091,1849212213712385092" \
--data-urlencode "expansions=author_id" \
--data-urlencode "user.fields=description,public_metrics,profile_image_url"
{
"data": [
{
"id": "1849212213712385091",
"text": "Shipped the new export queue today.",
"author_id": "1592041833471827968",
"edit_history_tweet_ids": ["1849212213712385091"]
},
{
"id": "1849212213712385092",
"text": "Next up: retries with backoff.",
"author_id": "1592041833471827968",
"edit_history_tweet_ids": ["1849212213712385092"]
}
],
"includes": {
"users": [
{
"id": "1592041833471827968",
"name": "Kai Builds",
"username": "kai_builds_tools",
"description": "Data tooling for small teams.",
"public_metrics": {"followers_count": 1840, "following_count": 312}
}
]
}
}
两条帖子,一位作者:includes.users 在每个响应里每位作者只列一次,而不是每条帖子列一次。所以这个列表往往比 data 短,按位置去索引,或者把 includes["users"]["username"] 当成单个对象来读,都会出错。下面的循环会翻页读取最近的搜索结果,并在各页之间共用同一个作者字典。
import requests
URL = "https://api.x.com/2/tweets/search/recent"
HEADERS = {"Authorization": "Bearer YOUR_BEARER_TOKEN"}
params = {
"query": "from:kai_builds_tools",
"max_results": 100,
"expansions": "author_id",
"user.fields": "description,public_metrics,profile_image_url",
}
authors, rows = {}, []
while True:
page = requests.get(URL, headers=HEADERS, params=params).json()
for user in page.get("includes", {}).get("users", []):
authors[user["id"]] = user
for post in page.get("data", []):
author = authors.get(post["author_id"], {})
rows.append((post["id"], author.get("username"), post["text"]))
token = page.get("meta", {}).get("next_token")
if not token:
break
params["next_token"] = token
读取作者时请用 .get():被封禁或被屏蔽的账号可能不在 includes 里,而它的帖子仍在 data 中,这时响应会在 errors 数组里列出这个缺口。
转发或引用的作者
转发或引用本身是一条指向另一条帖子的帖子,它的 author_id 是转发者或引用者,不是原作者。要同时拿到原作者,需要请求三个 expansion:author_id、referenced_tweets.id 和 referenced_tweets.id.author_id。原帖会出现在 includes.tweets 里,它的作者与转发者一起出现在 includes.users 里,你通过 referenced_tweets[0].id 找到原帖,再用原帖的 author_id 找到作者。从 11 月 22 日起,这样一次转发要计两条帖子和两个用户的费用:$0.030。
在 Sorsa API 上,被转发的推文以 retweeted_status 返回,被引用的以 quoted_status 返回,两者都是完整的推文,里面各有自己的 user。
#2026 年 11 月 22 日起 expansions 怎么收费
从 2026 年 11 月 22 日起,expansion 加进来的每个对象都按直接读取计费:每个用户 $0.010,每条帖子、图片、视频、投票或地点 $0.005。因此一条带作者的帖子最高收费 $0.015,是原来 $0.005 的三倍。每条再加一张图片,最高 $0.020;再加上被引用的帖子及其作者,就到 $0.035。
X 在 UTC 的 24 小时内去重:按其按量付费价格页面(在新标签页打开),同一天内再次获取的同一资源不会重复计费。某位用户当天写了你读取的 50 条帖子,也只算一次。所以来自 200 位不同作者的 1,000 条帖子,帖子部分 $5.00,作者部分 $2.00,共 $7.00;来自 1,000 位作者的 1,000 条帖子则是 $15.00。去重在 UTC 午夜重置,X 称其为软性保证。
在 Sorsa API 上,价格不随推文携带的内容变化。按 ID 读取推文,每 1,000 条 $0.014 起,作者、被引用的帖子和媒体链接都包含在内;搜索结果每 1,000 条 $0.07 起。对比官方 X API 带作者的帖子每 1,000 条 $15.00,大约便宜 1,000 倍。
| 读取内容,每 1,000 条帖子 | Sorsa API | 官方 X API,11 月 22 日起 |
|---|---|---|
| 仅帖子 | $0.014 起 | $5.00 |
| 帖子加作者 | $0.014 起 | 最高 $15.00 |
| 每条再加一张图片或一段视频 | $0.014 起 | 最高 $20.00 |
| 再加被引用的帖子及其作者 | $0.014 起 | 最高 $35.00 |
仅帖子
- Sorsa API
- $0.014 起
- 官方 X API,11 月 22 日起
- $5.00
帖子加作者
- Sorsa API
- $0.014 起
- 官方 X API,11 月 22 日起
- 最高 $15.00
每条再加一张图片或一段视频
- Sorsa API
- $0.014 起
- 官方 X API,11 月 22 日起
- 最高 $20.00
再加被引用的帖子及其作者
- Sorsa API
- $0.014 起
- 官方 X API,11 月 22 日起
- 最高 $35.00
计算器会按你用到的 expansions,估算一个月读取帖子的费用。它把每位作者都算作新作者,也就是区间的上限;选择重复作者,可以看到去重的效果。
在官方 X API 上,每个扩展项都会单独计费;在 Sorsa API 上,作者、被引用的帖子和媒体链接都包含在推文里。
须知
X 的按量付费套餐每月读取 300 万条帖子后停止;超过之后,官方 X API 只能走 Enterprise 合同,每月约 4.2 万美元起。在 Sorsa API 上,套餐越大,每 1,000 条推文的价格越低,而且所有套餐的每条推文都包含作者。
#为什么作者不再放在推文里面
作者原本就是推文的一部分。在 v1.1 的格式里,每个推文对象都带一个 user 对象,里面是作者资料,所以一条推文是自包含的,twarc 文档(在新标签页打开)也这么说。2020 年发布的 API v2 把每个对象砍到只剩几个默认字段,把相关对象移到 includes 里,只能通过 expansions 获取。
到目前为止,这种拆分增加的是代码量,不涉及费用:通过 expansions 返回的对象不计入用量,所以 expansion 只是省掉了第二次请求。2026 年 10 月的通知改变的正是费用这一块。从 11 月 22 日起,你从 includes.users 里拼接出来的作者,会按单独查询计费。
在这一点上,Sorsa API 的推文和 v1.1 的很像:user 就在里面。为 v1.1 写的代码如果读取 tweet["user"]["screen_name"],只需要换一个键名 username;指南从 Twitter/X API 迁移按接口逐个对应了 v2 代码库的其余部分。
#每条 Sorsa API 推文附带哪些作者字段
每条 Sorsa API 推文的 user 下都带 19 个作者字段,不需要另外请求。下表把大多数代码用得到的字段,对应到你在官方 X API 的 user.fields 里要列出的名称。
Sorsa API 的 user 字段 | 官方 X API 的 user.fields 名称 |
|---|---|
username | username |
display_name | name |
description | description |
followers_count | public_metrics.followers_count |
followings_count | public_metrics.following_count |
tweets_count | public_metrics.tweet_count |
profile_image_url | profile_image_url |
created_at | created_at |
location | location |
verified | verified |
protected | protected |
pinned_tweet_ids | pinned_tweet_id |
bio_urls | entities.description.urls |
username- 官方 X API 的
user.fields名称 username
- 官方 X API 的
display_name- 官方 X API 的
user.fields名称 name
- 官方 X API 的
description- 官方 X API 的
user.fields名称 description
- 官方 X API 的
followers_count- 官方 X API 的
user.fields名称 public_metrics.followers_count
- 官方 X API 的
followings_count- 官方 X API 的
user.fields名称 public_metrics.following_count
- 官方 X API 的
tweets_count- 官方 X API 的
user.fields名称 public_metrics.tweet_count
- 官方 X API 的
profile_image_url- 官方 X API 的
user.fields名称 profile_image_url
- 官方 X API 的
created_at- 官方 X API 的
user.fields名称 created_at
- 官方 X API 的
location- 官方 X API 的
user.fields名称 location
- 官方 X API 的
verified- 官方 X API 的
user.fields名称 verified
- 官方 X API 的
protected- 官方 X API 的
user.fields名称 protected
- 官方 X API 的
pinned_tweet_ids- 官方 X API 的
user.fields名称 pinned_tweet_id
- 官方 X API 的
bio_urls- 官方 X API 的
user.fields名称 entities.description.urls
- 官方 X API 的
另外六个是 id、favourites_count、media_count、profile_background_image_url、can_dm 和 possibly_sensitive。ID 以字符串返回,日期采用 ISO 8601 格式。推文、用户资料和其他对象包含的全部内容,见指南 Twitter API 能获取哪些数据。
如果你的起点是一份推文 ID 列表,指南还原推文 ID讲了如何处理数百万条的列表,每次请求 100 个 ID。
#读取你的第一批带作者的推文
在官方 X API 上,帖子的作者是一个 expansion:要多拼接一个列表,而且从 2026 年 11 月 22 日起,在 $0.005 的帖子费用之上,每位作者另收 $0.010。想一次拿到推文和作者,就用 Sorsa API:POST /tweet-info-bulk 每次请求返回 100 条推文,每条里面都有作者的完整资料,每 1,000 条 $0.014 起,所有套餐统一每秒 20 次请求。
Sorsa API 从不要求你的 X 登录信息,所以你自己的账号永远不会有风险,而且它在设计上就是只读的:要发帖,请搭配官方 X API 使用。你的 100 次免费请求,可以读取前 1 万条带作者的推文。
#常见问题
官方 X API 会随每条推文返回用户名吗?
默认不会。官方 X API v2 返回的帖子只有 id、text 和 edit_history_tweet_ids。加上 expansions=author_id,响应里会多一个 includes.users 列表,包含每位作者的 id、name 和 username,你再按 author_id 与帖子对应起来。从 2026 年 11 月 22 日起,这些作者每位按 $0.010 计费。
如何获取转发或引用推文的原作者?
在官方 X API 上,请求 expansions=referenced_tweets.id,referenced_tweets.id.author_id。原帖出现在 includes.tweets 里,它的作者出现在 includes.users 里;先沿 referenced_tweets[0].id 找到帖子,再用它的 author_id 找到用户。在 Sorsa API 上,被转发的推文以 retweeted_status 返回,被引用的以 quoted_status 返回,里面各有自己的 user 对象。
Twitter API 的 expansions 收费吗?
收费,从 2026 年 11 月 22 日起。X 在 10 月 23 日的通知中说明,通过 expansions 返回的对象按标准按量付费费率计费:每个用户 $0.010,每条帖子、媒体项、投票或地点 $0.005。每个资源在 UTC 的 24 小时内只收一次费,所以同一天内重复出现的作者不会再次计费。
为什么 includes.users 的条目比 data 少?
官方 X API 在每个响应里把每位作者只列一次,不管他写了其中多少条帖子。三个人写的十条帖子,只会返回三个用户。账号被封禁或被屏蔽时,作者也可能缺失,这时响应会在 errors 数组里指出。请用字典按 ID 关联,千万不要按位置关联。
想获取带作者资料的推文,该用哪个 API?
用 Sorsa API。它返回的每条推文都带有作者的完整资料,共 19 个字段,无需 expansion,也没有按作者计费:POST /tweet-info-bulk 每次请求读取 100 条推文,每 1,000 条 $0.014 起,而官方 X API 带作者的帖子每 1,000 条最高 $15.00。一个 API 密钥,所有套餐统一每秒 20 次请求,另有 100 次免费请求可以上手。
#我们如何核实
2026 年 11 月 2 日,我们阅读了 X 的 expansions 和 fields 指南、按量付费价格页面,以及 10 月 23 日关于 expansions 计费的通知,官方 X API 的所有费率和默认值都取自这些资料。Sorsa API 的接口、请求体和 19 个作者字段,来自同一天的线上 API 参考。请求和响应示例参照这两份参考编写,用演示账号代替真实账号。