X / Twitter User posts API
Get an X (Twitter) account's profile Posts-tab timeline by handle. Results follow profile order: a pinned post may appear first, followed by otherwise reverse-chronological authored posts, reposts, quotes, and self-thread continuations.
$0.45/1k req, pay per request, no subscription.
{"id": "1842093771280384512","url": "https://x.com/buildwithjonah/status/1842093771280384512","text": "Spent the last 6 months building a data pipeline that normalizes 40 scraper APIs into one schema. Here is what broke, and what I would do differently. A thread.","createdUtc": 1727366400,"lang": "en","likes": 3820,"retweets": 412,"replies": 96,... 12 more fields}
Pricing and providers
X / Twitter User posts API pricing: one API, 3 interchangeable providers
The cheapest provider serves first. If it fails, the next one takes over in the same call.
capped at $0.0021 per request1 result$0.000210 results$0.001120 results$0.0021 capYou are charged for what comes back. Lower the limit to pay less - and no single request can cost more than the cap, however much comes back.
Try it
Get X / Twitter user posts in one request
This sample shows 28 of 30 fields. See every field
{
"found": true,
"data": {
"tweets": [
{
"id": "1842093771280384512",
"url": "https://x.com/buildwithjonah/status/1842093771280384512",
"text": "Spent the last 6 months building a data pipeline that normalizes 40 scraper APIs into one schema. Here is what broke, and what I would do differently. A thread.",
"createdUtc": 1727366400,
"lang": "en",
"likes": 3820,
"retweets": 412,
"replies": 96,
"quotes": 28,
"views": 284000,
"bookmarks": 1540,
"isReply": false,
"isPinned": true,
"media": [],
"conversationId": "1842093771280384512",
"source": "Twitter Web App",
"authorId": "1401882093771280384",
"authorName": "Jonah Ruiz",
"authorHandle": "buildwithjonah",
"authorImage": "https://pbs.twimg.com/profile_images/1401882093771280384/jonah_400x400.jpg"
},
{
"id": "1841002881044099072",
"url": "https://x.com/buildwithjonah/status/1841002881044099072",
"text": "Shipped a small tool today that diffs API response schemas across versions. Saved me from a nasty silent break last week.",
"createdUtc": 1727280000,
"lang": "en",
"likes": 640,
"retweets": 52,
"replies": 18,
"quotes": 2,
"views": 41200,
"bookmarks": 210,
"isReply": false,
"isPinned": false,
"media": [
{
"type": "photo",
"url": "https://pbs.twimg.com/media/F9j1QoQWkAA_diff_tool.jpg",
"width": 1600,
"height": 1000
}
],
"conversationId": "1841002881044099072",
"source": "Twitter for iPhone",
"authorId": "1401882093771280384",
"authorName": "Jonah Ruiz",
"authorHandle": "buildwithjonah",
"authorImage": "https://pbs.twimg.com/profile_images/1401882093771280384/jonah_400x400.jpg"
},
{
"id": "1839881220337844224",
"url": "https://x.com/buildwithjonah/status/1839881220337844224",
"text": "@dataeng_marta Totally agree, cursor pagination beats offset once you get past a few hundred thousand rows.",
"createdUtc": 1727107200,
"lang": "en",
"likes": 88,
"retweets": 4,
"replies": 6,
"quotes": 0,
"views": 6200,
"bookmarks": 12,
"isReply": true,
"isPinned": false,
"media": [],
"conversationId": "1839880002114899968",
"source": "Twitter Web App",
"authorId": "1401882093771280384",
"authorName": "Jonah Ruiz",
"authorHandle": "buildwithjonah",
"authorImage": "https://pbs.twimg.com/profile_images/1401882093771280384/jonah_400x400.jpg"
}
],
"nextCursor": "DAABCgABGZ3xw5A2xVIKAAIY__posts_page2"
}
}Full parameter and response reference - every field, type, and example for this endpoint.
Reference
One request, one response shape.
Every field you send and every field you get back, each with a real example.
Last verified 2026-10-31 · uptime and latency measured over 30d
Request body
JSON, posted to this endpoint.
- handlestring
buildwithjonah
Twitter/X handle without the leading @.
- cursorstring
Opaque pagination cursor from a previous response's nextCursor. Omit for the first page.
- requireFieldsarray
Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `isPinned`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a tweet that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge. On a paginated walk it applies to the first page only; later pages stay with the source that page chose, at the price it was quoted.
Response
JSON, one example value per field.
The Posts-tab timeline page, or null when the account was not found.
- nextCursorstring
DAABCgABGZ3xw5A2xVIKAAIY__posts_page2
Opaque cursor for the next native Posts-tab page, or null when no more pages are available.
Posts in profile order. A pinned post may appear before otherwise reverse-chronological results. Populated whenever the provider has data for the entity.
- authorHandlestring
buildwithjonah
Handle of the account that posted.
- authorIdstring
1401882093771280384
Numeric X user id of the account that posted, as a string.
- authorImagestring
https://pbs.twimg.com/profile_images/1401882093771280384/jonah_400x400.jpg
Avatar image URL of the account that posted.
- authorNamestring
Jonah Ruiz
Display name of the account that posted.
- bookmarksinteger
1540
Number of bookmarks.
- conversationIdstring
1842093771280384512
Id of the conversation the post belongs to, as a string.
- createdUtcnumber
1727366400
UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. Populated whenever the provider has data for the entity.
- idstring
1842093771280384512
The post's numeric tweet ID, represented as a string. Populated whenever the provider has data for the entity.
- isPinnedbooleancan require
true
Whether X marks the post as pinned on the profile, or null when the serving source does not publish it.
- isReplyboolean
false
Whether X marks the record as a reply. Certified Posts-tab captures use this for self-thread continuations.
- langstring
en
Language code reported for the post, when available.
- likesinteger
3820
Number of likes.
- quotesinteger
28
Number of quote posts.
- repliesinteger
96
Number of replies.
- retweetsinteger
412
Number of reposts or retweets.
- sourcestring
Twitter Web App
Client the post was sent from, e.g. "Twitter Web App".
- textstring
Spent the last 6 months building a data pipeline that normalizes 40 scraper APIs into one schema. Here is what broke, and what I would do differently. A thread.
The post text. Empty for media-only posts. Populated whenever the provider has data for the entity.
- urlstring
https://x.com/buildwithjonah/status/1842093771280384512
Canonical x.com URL of the post. Populated whenever the provider has data for the entity.
- viewsinteger
284000
Number of views.
Photo, video, and GIF attachments on the post. Empty when the post has none.
- heightinteger
- typestring
One of photo, video, or gif.
- urlstring
Image URL. For a video or GIF this is the poster/thumbnail frame. X media URLs on pbs.twimg.com are publicly fetchable without authentication; append ?name=orig for the full-resolution original.
- videoUrlstring
Playable video file URL. Present only for video and gif items.
- widthinteger
- foundboolean
true
Whether the account's Posts-tab timeline was returned.
- reason"not_found" | "suspended"
Present only when `found` is false, and says why there is no result. `not_found`: the source states the target does not exist, or returned nothing for it. `suspended`: the platform has suspended the account. A `found: false` answer is a successful call, not an error, and `costUsd` is what it actually cost.
Selling this API? See the full schema your endpoint must return.
FAQ
About the X / Twitter User posts API
The AnyAPI X / Twitter User posts API returns X / Twitter user posts data as normalized JSON from one POST call to /v1/run/twitter.user_posts. Get an X (Twitter) account's profile Posts-tab timeline by handle. Results follow profile order: a pinned post may appear first, followed by otherwise reverse-chronological authored posts, reposts, quotes, and self-thread continuations. AnyAPI routes each request across 3 sources and falls back automatically when one fails. It costs from $0.45 per 1,000 requests, in US dollars with no subscription and no monthly minimum. Over the last 30 days, 100.0% of X / Twitter user posts calls through AnyAPI succeeded, with a median response time of 1.6 seconds across 165,325 measured calls.