Twitter (X) List Scraper - Full Tweets, Views & Authors
Pricing
from $0.40 / 1,000 tweet scrapeds
Twitter (X) List Scraper - Full Tweets, Views & Authors
Scrape every tweet from an X (Twitter) list. One row per tweet: full text, likes, retweets, replies, quotes, bookmarks and views. Hashtags, media and the author come too. X serves list timelines only to a signed-in session, and this brings its own. $0.40 per 1,000 tweets.
Pricing
from $0.40 / 1,000 tweet scrapeds
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
19 hours ago
Last modified
Categories
Share
Twitter (X) List Scraper: every tweet posted into a curated X list
Point it at an X list and you get one flat row per tweet: full text, likes, retweets, replies, quotes, bookmarks and views, with hashtags, media links and the author's profile attached. A list someone else curated is a ready-made feed, and this turns it into a table.
Worth knowing first: X only serves a list timeline to a signed-in session, so this runs signed in. You do not need an account of your own for that. Every run also has a wall-clock limit, and when it runs out the tweets collected so far are kept and returned rather than thrown away.
| Input | X list ids, or x.com/i/lists/ links |
| Output | One row per tweet |
| Ceiling | 5,000 tweets per run, plus a run-time limit you set |
| Account needed | None from you, unless you want to use your own |
| Price | $0.40 per 1,000 tweets, flat on every plan |
๐ What Twitter (X) List Scraper does
Each list is read newest-first and paged through until it runs out of tweets, hits your maxItems,
or reaches maxRunSeconds.
The list id is the number in the URL: x.com/i/lists/34179516 is list 34179516. Paste the id or
the whole link, whichever is quicker. Several lists in one run are fine, and a tweet that appears in
two of them is delivered once and charged once.
The run-time limit is the part people miss. It defaults to 240 seconds, and hitting it is a normal
ending, not a failure: paging stops, everything already collected is yours, and a PARTIAL row goes
into the dataset so you know it stopped early. Raise it for a busy list, lower it when you only want
a quick look at the top.
Retweets, replies and quotes all come through, flagged so you can filter them out yourself rather than having that decision made for you.
๐ฅ What you give it
{"listIds": ["34179516"],"maxItems": 500,"maxRunSeconds": 300}
| Field | Default | What it is |
|---|---|---|
listIds | none | The numbers from x.com/i/lists/<id>. The form opens with one filled in as an example, which is a starting point rather than a default. |
startUrls | none | Or paste whole list links. Mix them with listIds freely. |
maxItems | 100 | Hard cap on tweets across every list, up to 5,000. You pay per tweet, so this is the run's budget. |
maxRunSeconds | 240 | Wall-clock limit, between 30 and 900. Reaching it stops paging and returns what it has. |
sessionCookies | none | Optional. Your own X account, as auth_token=XXXX; ct0=YYYY, one per line, for a rate limit nobody else is drawing on. It is never printed to the log, but it is saved with the run input like any other field, so use a throwaway account. |
proxyConfiguration | Apify's default | Leave it alone. It is there for people who need the run to leave through servers they already pay for. |
notionConnector, notionParentId | none | Optional. Write each tweet into a Notion database as well as the dataset. |
๐ค What you get back
A real row from a real run, with the author's bio cut short:
{"ok": true,"charged": true,"id": "2096637550337155498","url": "https://x.com/RepAdamSmith/status/2096637550337155498","text": "Looking forward to this year's Apple Cup as the UW Huskies take on the WSU Cougs at Husky Stadium. May the best team in Washington win (Go Dawgs!) https://t.co/egUSbdL7tq","createdAt": "Sun Sep 06 16:32:00 +0000 2026","lang": "en","replyCount": 0,"retweetCount": 0,"likeCount": 0,"quoteCount": 0,"bookmarkCount": 0,"viewCount": null,"isReply": false,"isRetweet": false,"isQuote": false,"conversationId": "2096637550337155498","inReplyToId": null,"inReplyToUser": null,"hashtags": [],"mentions": [],"urls": [],"media": [{ "type": "photo", "url": "https://pbs.twimg.com/media/HRYNHLDa8AAU6fL.jpg" }],"author": {"id": "58928690","userName": "RepAdamSmith","name": "Rep. Adam Smith","description": "Proudly serving Washington State's 9th District. ...","followersCount": 46954,"friendsCount": 2026,"statusesCount": 13142,"verified": true,"isBlueVerified": true,"location": "Washington's 9th District","profileImageUrl": "https://pbs.twimg.com/profile_images/1046859374055047169/OrFwOGl6_normal.jpg","createdAt": "Tue Jul 21 21:31:55 +0000 2009"}}
| Field | What it is |
|---|---|
text, createdAt, lang | The tweet as posted, X's own timestamp format, and the language X tagged it with. |
viewCount | Impressions. It is null when X does not report them for that tweet, as in the row above. |
isReply, isRetweet, isQuote | What kind of tweet it is, so you can filter the list down yourself. |
conversationId, inReplyToId, inReplyToUser | Enough to rebuild a thread out of a set of rows. |
hashtags, mentions, urls | Pulled out of the text as arrays. |
media | One entry per photo or video, with a direct link. |
author | The posting account: handle, name, bio, counts, location, avatar and join date, as X reported them at read time. location is empty when the account never set one. |
๐งพ Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it | Billed |
|---|---|---|
| A tweet | ok: true and an id | yes |
| The sample row | _sample: true | no |
| A diagnostic | ok: false and an errorCode | no |
Filter on ok == true and you have your data. The charged field separates real rows from sample
and diagnostic rows, and is not a receipt.
PARTIAL means the run-time limit was reached: the tweets above it are complete and correct, there
are simply fewer than the list holds. NO_RESULTS means nothing came back for that list, usually
because the id is wrong or the list is private. BLOCKED means it could not be read on this run.
BAD_INPUT means no usable list id was supplied.
One thing worth knowing about NO_RESULTS: a single awkward answer from X ends that list where it
stands, so if a list you know is public and busy comes back empty, run it again before concluding
the id is wrong.
The Overview table shows five columns: text, likeCount, retweetCount, createdAt and url.
The author block, viewCount and replyCount are not among them, so open a row or download the
JSON for the full picture. The sample row's text says in as many words that it is a sample, but the
counts beside it are made up, so filter on _sample rather than trusting a table scan.
โถ๏ธ How to run it
- Open the list on X and copy the number out of the address bar.
- Open Twitter (X) List Scraper and click Try for free.
- Paste the id into List IDs, or the whole link into List URLs.
- Set Max tweets and, for a busy list, raise Max run seconds.
- Click Start, then download the dataset as JSON, CSV or Excel.
๐ฐ How much does it cost?
$0.40 per 1,000 tweets. Flat on every Apify plan, no volume tiers.
You pay per tweet delivered. The sample row, diagnostic rows, and the second copy of a tweet that
appeared in two of your lists are not charged. maxItems is the ceiling on what a run can spend, so
set it deliberately while you are testing.
๐ก What people use it for
- Turning a hand-curated industry list into a daily feed, without following any of the accounts.
- Watching a competitor's own public list to see who they consider worth reading.
- Building a dataset from a conference or event list while it is active.
- Media monitoring, where someone else has already done the work of deciding who matters.
๐ง What it does not do
- Private lists are unreadable, and so are deleted ones. You get a diagnostic row instead.
- No list membership. This returns the tweets posted by members, not the roster of who is in the list.
- Newest-first only, with no way to start from an older point in the timeline.
viewCountisnullon plenty of tweets, because X does not report it for all of them.- 5,000 tweets per run, and a wall-clock limit on top of that.
๐งญ Which X scraper do you need?
| If you want | Use |
|---|---|
| Everything posted into a curated list | This one |
| Tweets matching a keyword or an advanced query | Twitter (X) Search Scraper |
| Specific tweets, or one profile's timeline | Tweet Scraper |
| Profile records for handles you already have | Twitter Profile Scraper |
| Who follows an account | X Followers Scraper |
โ Questions people ask
Where do I find the list id? In the URL. Open the list on X and take the number from
x.com/i/lists/34179516, or paste the whole address into startUrls.
Do I need an X account or an API key? Neither. The cookie field is optional and only worth filling in if you want a rate limit of your own.
Why did my run stop before maxItems? Either the list ran out of tweets or the run-time limit
was reached. A PARTIAL row tells you which, and what you got is still complete and correct.
Can I scrape a private list I am a member of? Only by supplying that account's own cookies. Without them the list is not visible.
Is scraping X legal? This reads public tweets only, never private accounts or messages. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
Can I run it on a schedule? Yes. Use Apify's scheduler, or start it from the API and read the dataset when it finishes.
๐ If something breaks
Open the Issues tab on the actor page. Include the list id and the run ID, and paste any
errorCode you got back, since that usually says what happened straight away.