Tweet Scraper - Tweets by Handle or URL, No X API Key
Pricing
from $0.14 / 1,000 tweet returneds
Tweet Scraper - Tweets by Handle or URL, No X API Key
Scrape X (Twitter) tweets by handle or URL, with no API key. Tweet URLs load from a public endpoint that asks the reader for nothing. Handles use X's web GraphQL, also keyless. Rows carry text, likes, retweets, replies, views, media and hashtags. Search needs your own X cookie. $0.14/1k.
Pricing
from $0.14 / 1,000 tweet returneds
Rating
5.0
(1)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
42
Total users
7
Monthly active users
18 hours ago
Last modified
Categories
Share
Tweet Scraper: tweets from a handle or a link, with no X API key
Give it X handles or tweet URLs and you get one row per tweet. The full text, likes, retweets, replies, views, media, hashtags, mentions, and the author it came from.
Handles and links need nothing from you. Search is the exception, and it is the thing to know
first: X stopped serving search results to signed-out clients, so search terms and the
include-replies option only work if you paste your own auth_token and ct0 cookies from a
logged-in session. A throwaway account is the sensible way to do that, since X does not love
accounts used this way.
One more. A tweet fetched from its own link comes from X's public tweet endpoint, which does not publish retweet, quote, bookmark or view counts. Those four fields are null on that kind of row, and they are filled in on rows that came from a timeline.
| Input | X handles, profile or tweet URLs, or search terms |
| Output | One row per tweet |
| Ceiling | 5,000 tweets per run, 80 pages of timeline per handle |
| Account needed | None for handles and links. Your own X cookies for search and replies |
| Price | $0.14 per 1,000 tweets, which is $0.00014 each, flat on every plan |
🐦 What Tweet Scraper does
Three ways in, and you can mix them in one run.
Handles. Give it nasa and it walks that account's timeline, newest first, 40 tweets a page,
up to 80 pages. This is the mode that needs nothing from you and the one to reach for.
URLs. A profile URL does the same as a handle. A status URL pulls that one tweet from X's public tweet endpoint.
Search terms. Full X search syntax, from:, min_faves:, filter:media and the rest, sorted
Latest or Top. This is the mode that needs your cookies.
Tweets are deduped by id across every input, so overlapping handles and links do not cost you twice.
onlyVerifiedUsers and the date window are applied before anything is written, and what they drop
is not charged.
Dates are worth a note. A timeline has no date filter at X's end, so the run walks backwards until it reaches your window. A window years in the past can be out of reach, and when that happens the run writes a row saying how many tweets it examined and how far back it got, rather than pretending the account had nothing.
📥 What you give it
{"twitterHandles": ["nasa"],"maxItems": 200,"since": "2026-01-01","onlyVerifiedUsers": false}
| Field | Default | What it is |
|---|---|---|
twitterHandles | none | Usernames, with or without the @. The keyless mode. |
startUrls | none | X URLs. A profile scrapes its timeline, a status link scrapes that one tweet. |
searchTerms | none | Full X queries. Needs both cookie fields below. |
sort | Latest | For search terms: Latest or Top. |
since, until | none | YYYY-MM-DD. until cuts at the start of that day in UTC, so add a day if you want the day itself. |
maxItems | 100 | Tweets across the whole run, 1 to 5,000. |
includeReplies | false | Adds the account's replies to its timeline. Needs the cookies. Without them the run keeps going with original tweets and says so in a row. |
onlyVerifiedUsers | false | Keep only tweets whose author is verified, legacy or Premium. |
xAuthToken, xCsrfToken | none | Your own auth_token and ct0 cookies from one logged-in x.com session. Both fields are marked secret. Only search and replies use them. |
notionConnector, notionParentId | none | Optional. Also deliver the tweets into your connected Notion workspace. |
proxyConfiguration | Apify default | Leave it alone unless you have your own servers and a reason to use them. |
📤 What you get back
A real row from a real run:
{"ok": true,"id": "2101770186156052959","url": "https://x.com/NASA/status/2101770186156052959","text": "RT @nasahqphoto: NASA astronuat Reid Wiseman joined the @Ravens NFL game today for @NASA's Inspiration Tour! Check out images: https://t.co…","createdAt": "Sun Sep 20 20:27:16 +0000 2026","lang": "en","replyCount": 0,"retweetCount": 47,"likeCount": 0,"quoteCount": 0,"bookmarkCount": 0,"viewCount": 52178,"isReply": false,"isRetweet": true,"isQuote": false,"conversationId": "2101770186156052959","inReplyToId": null,"inReplyToUser": null,"hashtags": [],"mentions": ["nasahqphoto", "Ravens", "NASA"],"urls": [],"media": [],"author": {"id": "11348282","userName": "NASA","name": "NASA","description": null,"followersCount": null,"friendsCount": null,"statusesCount": null,"verified": true,"isBlueVerified": true,"location": "Pale Blue Dot","profileImageUrl": "https://pbs.twimg.com/profile_images/1321163587679784960/0ZxKlEKB_normal.jpg","createdAt": "Wed Dec 19 20:20:32 +0000 2007"}}
| Field | What it is |
|---|---|
id, conversationId | The tweet, and the thread it belongs to. Use id to dedupe across runs. |
text | The whole thing, including the long-post body where there is one, not the truncated version. |
likeCount, retweetCount, replyCount, quoteCount, bookmarkCount, viewCount | Numbers at read time. The last four are null on a row that came from a single tweet link. |
isReply, isRetweet, isQuote | What kind of tweet it is. The row above is a retweet, which is why likeCount is 0. |
media | Photos and video, each with its type and a direct URL, and the best mp4 where there is one. |
urls | Links expanded, not the shortened t.co form. |
author | The account. The handle, name and verification flags are always there. Timeline rows also carry the location (when the account set one), the avatar and the join date. Pulled without cookies, the bio and follower counts come back null, as they do above. |
createdAt | X's own date string, not an ISO stamp. |
🧾 Reading the output
Real tweets carry ok: true and an id. Notes carry ok: false and an errorCode, and they are
never charged.
| Row | How to spot it | Charged |
|---|---|---|
| A tweet | ok is true and id is set | yes |
| A diagnostic | ok is false, and errorCode says what happened | no |
| Code | What it means |
|---|---|
BAD_INPUT | Something was asked for that this run cannot do: search terms or replies with no cookies set, or an address that is not an X profile or tweet. |
NOT_FOUND | The handle or tweet did not come back. Deleted, suspended, protected, or throttled at that moment, so retry a single tweet link once before concluding it is gone. |
NO_RESULTS | Nothing matched. On a date window the row also carries how many tweets were examined, how many pages were walked and the oldest date reached. |
RATE_LIMITED | X throttled the run. Wait and try again, or ask for fewer tweets. |
BLOCKED | X would not open a session for the run at all. |
▶️ How to run it
- Open Tweet Scraper and click Try for free.
- Put handles into Profile handles, one per line. Or paste links into Start URLs.
- Set Max tweets. A hundred is a sensible first run.
- Only if you need search or replies: paste your own
auth_tokenandct0into the two cookie fields. - Click Start, then download the dataset as JSON, CSV or Excel, or read it from the API.
💰 How much does it cost?
$0.14 per 1,000 tweets, which is $0.00014 each. Flat on every Apify plan, no volume tiers.
You pay per tweet row. Diagnostics are not charged, and neither is anything the filters threw away: a duplicate seen twice across two inputs, a tweet outside your date window, an unverified author when you asked for verified only.
A thousand tweets is fourteen cents.
💡 What people use it for
- A daily pull of what a set of accounts posted, deduped on
id. - Engagement tracking: likes, retweets and views on your own account over time.
- Pulling the media URLs off an account for an archive.
- Watching announcements from a handful of official accounts without sitting in the app.
- Feeding a Notion database straight from the run, using the two connector fields.
🚧 What it does not do
- Search needs your own X cookies. So does including replies. X refuses both to signed-out clients, and no setting here gets around it.
- Protected, suspended and deleted accounts return nothing, and a note saying so.
- A single tweet link carries fewer numbers. Retweets, quotes, bookmarks and views are null on
those rows, and there is no
inReplyToId. - Author detail is thin without cookies. Bio and follower counts come back null on a timeline pulled that way.
- 80 pages of timeline per handle. A window far in the past may be out of reach, and the run tells you how far back it got.
- 5,000 tweets per run across all inputs.
- Nothing private. No DMs, no analytics, no followers list, nothing behind a login.
- The pinned tweet comes with the timeline and can sit out of date order.
🧭 Which social scraper do you need?
| If you want | Use |
|---|---|
| Tweets from a handle, a profile or a single link | This one |
| Tweets by keyword, without cookies | Twitter (X) Search Scraper |
| LinkedIn posts by keyword | LinkedIn Post Search Scraper |
| Instagram profiles | Instagram Profile Scraper |
❓ Questions people ask
Do I need an X API key? No. Handles and links need nothing at all.
Why does my search return a note instead of tweets? Because no cookies were set. X serves search only to signed-in clients now. If you would rather not paste cookies, the keyword scraper linked above is the straightforward route.
Can I get a whole account history? Up to 80 pages back per handle, which is thousands of tweets on most accounts but not a full archive on a busy one.
Why is likeCount zero on a retweet? Because the likes belong to the original tweet. Look at
isRetweet before reading the numbers.
Can I schedule it? Yes. Run it each morning with a since of yesterday and keep id as your
key.
Is scraping X legal? These are public posts. They are personal data under GDPR and similar laws, so have a reason for holding them and be careful about republishing. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the handle or link and the run ID. If a diagnostic
row landed, its errorCode and hint usually name the reason already. Never paste a cookie into an
issue.