read:posts
Reads up to a hundred posts in one call, by id. X's bulk lookup, for hydrating ids you already hold: it does not search and it does not page.
It is its own operation rather than read:post with a list because
the price is different: ten ids cost $0.050.
Fields
ids |
Required. X's own numeric ids, as strings, up to 100. Ids only |
profile |
the account to read as. Optional when the agent has one |
reason |
Required over MCP. One short sentence, in the agent's own words, for the person |
What comes back
{ "status": "done",
"ref": "5K2PB9XD",
"data": {
"data": [
{ "id": "1832000000000000007",
"text": "We rebuilt the pipeline this week.",
"created_at": "2026-09-15T09:12:44.000Z",
"author_id": "1400000000000000001",
"edit_history_post_ids": ["1832000000000000007"],
"lang": "en",
"public_metrics": {
"repost_count": 2, "reply_count": 1, "like_count": 14,
"quote_count": 0, "bookmark_count": 3, "impression_count": 812
} }
],
"errors": [
{ "value": "1832000000000000099",
"detail": "Could not find tweet with id: [1832000000000000099].",
"title": "Not Found Error",
"resource_type": "tweet",
"parameter": "ids",
"resource_id": "1832000000000000099",
"type": "https://api.twitter.com/2/problems/resource-not-found" }
]
} }
Posts come back in no guaranteed order, so match them to your ids by id rather than by
position.
A partial answer is the normal case
An id X does not hold is an entry in errors rather than a gap in data, and the call is still
done. When nothing at all was found there is no data key.
You are charged for what came back, but the estimate - and therefore the cap - uses the number you asked for.