Tweet Scraper - $0.14 per 1,000, No X API Key
Pricing
Pay per event
Tweet Scraper - $0.14 per 1,000, No X API Key
A tweet quoted in a news article is live, not a screenshot: it loads from a public endpoint asking the reader for nothing. Tweet URLs take that route; handles use X's web GraphQL, also keyless. Rows carry text, likes, retweets, replies, views, media, hashtags. Search needs your X cookie. $0.14/1k.
Pricing
Pay per event
Rating
5.0
(1)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
37
Total users
14
Monthly active users
2 days ago
Last modified
Categories
Share
Tweet Scraper — X / Twitter posts by handle, URL or search
A tweet quoted inside a news article is live, not a screenshot: it loads from a public endpoint that asks the reader for nothing at all. A tweet URL here is fetched off that same endpoint; a handle walks the account's timeline through X's own web GraphQL. Every row comes back flat: the full text, likes, retweets, replies, quotes, bookmarks, views, media, hashtags, mentions, links, and who posted it.
Handles and tweet URLs need nothing from you: no account, no API key, no cookie. Search terms and replies do need one, and the reason is below.
What each row looks like
{"ok": true,"id": "2090487779268407625","url": "https://x.com/NASA/status/2090487779268407625","text": "Paint with all the colors of the (stellar) wind ...","createdAt": "Thu Aug 20 17:15:00 +0000 2026","lang": "en","replyCount": 203,"retweetCount": 912,"likeCount": 5614,"quoteCount": 57,"bookmarkCount": 290,"viewCount": 1264494,"isReply": false,"isRetweet": false,"isQuote": false,"conversationId": "2090487779268407625","inReplyToId": null,"inReplyToUser": null,"hashtags": [],"mentions": ["NASAHubble", "chandraxray", "NASAWebb"],"urls": [],"media": [{ "type": "photo", "url": "https://pbs.twimg.com/media/HQLZFUzW8AAxJOZ.jpg" }],"author": { "id": "11348282", "userName": "NASA", "name": "NASA", "verified": true, "isBlueVerified": true }}
That's a row from a run, trimmed for length.
Worth knowing before you build on it: the author object on a keyless timeline pull is thin. You reliably
get id, userName, name, verified and isBlueVerified. The bio and follower fields are in the
object but usually come back null, because the signed-out endpoint doesn't hand them over. If you
need follower counts, run the handles through the Twitter Profile Scraper, which reads a route that
does return them.
Long tweets are returned in full, not truncated at 280 characters.
What works without credentials
| Mode | Input | Needs a session? |
|---|---|---|
| Profile timeline | twitterHandles, or a profile URL in startUrls | No |
| Single tweet | a status URL in startUrls | No |
| Search query | searchTerms | Yes |
| Replies as well as posts | includeReplies: true | Yes |
X answers SearchTimeline and UserTweetsAndReplies with an empty 404 for a signed-out guest
token, in the same second that it happily serves a profile timeline with a full payload. It's an
allow-list, not a fingerprinting problem, so no proxy or address rotation gets around it. Paste
auth_token and ct0 from a logged-in x.com session into xAuthToken / xCsrfToken and those two
modes work. Leave them empty and the run still returns profile tweets, plus an uncharged diagnostic
row explaining the gap.
To get the cookies: log in to x.com (a throwaway account is a sensible choice), F12 → Application →
Cookies → https://x.com, copy auth_token and ct0.
Input
{"twitterHandles": ["nasa", "elonmusk"],"maxItems": 100,"includeReplies": false,"onlyVerifiedUsers": false}
| Field | Default | Notes |
|---|---|---|
twitterHandles | — | Usernames, with or without @. The most reliable mode. |
startUrls | — | Profile URLs scrape the timeline; status URLs scrape that one tweet. Mix them freely. |
searchTerms | — | Full X search queries — from:, since:, filter:media, min_faves: all work. Needs cookies. |
sort | Latest | Latest or Top. Search only. |
maxItems | 100 | Up to 5,000 across all inputs. This is your spend cap. |
includeReplies | false | Timeline replies as well as top-level posts. Needs cookies. |
onlyVerifiedUsers | false | Drop tweets whose author isn't verified. Filtered rows aren't charged. |
since / until | — | YYYY-MM-DD. See the note below. |
xAuthToken / xCsrfToken | — | The two cookies. Both from the same session or X rejects the pair. Stored as secrets. |
proxyConfiguration | Apify datacenter | Leave it. The run goes out over its own stable exit addresses and hops when one gets throttled, because X counts its guest limit per address. Nothing here is billed by the gigabyte. |
notionConnector / notionParentId | — | Optional: write each tweet into a Notion database too. |
Limits worth knowing
- Date filtering on timelines is client-side. X gives profile timelines no server-side date
filter, so
since/untilare applied while walking backwards through the timeline, up to 80 pages. A window several years in the past can sit beyond that budget. The run reports how far back it reached rather than silently returning nothing. - Only delivered tweets count toward
maxItems, so a heavyonlyVerifiedUsersfilter walks further to fill your quota. - Protected accounts return nothing. So do suspended and deleted ones; you get a
NOT_FOUNDdiagnostic row for them, free. - Tweets are deduplicated by id across every input in the run, so the same tweet is never returned or charged twice.
Billing
$0.00014 per tweet ($0.14 per 1,000), plus $0.001 when a run starts. The same rate on every Apify plan, with no volume tiers and no minimum.
Only tweets that actually land in the dataset are charged. Diagnostic rows, filtered-out tweets, duplicates, blocked handles and runs that come back empty cost nothing beyond the start fee.