Twitter X Tweets Scraper- Repost and Quote
Pricing
from $4.99 / 1,000 results
Twitter X Tweets Scraper- Repost and Quote
Twitter X Tweets Scraper: Extract tweets, reposts, and quoted posts with text, authors, URLs, timestamps, likes, replies, views, and engagement data. Analyze content reach, repost activity, quote discussions, audience engagement, and social media trends.
Pricing
from $4.99 / 1,000 results
Rating
0.0
(0)
Developer
API Empire
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
0
Monthly active users
13 days ago
Last modified
Categories
Share
Twitter X Tweets Scraper Scraper - Repost and Quote
An X (Twitter) scraper that opens every repost and quote into the post that was actually shared — and tells you who wrote it and how big they are.
A normal Twitter profile scraper hands you a row that reads RT @somebody: … and stops. This one labels every row original, repost or quote, and for the shared rows attaches an original_post object holding the source post's own likes, reposts, replies, quotes, bookmarks and views, plus the original author's handle, display name, numeric user id, follower count, bio and verified badge.
That turns an X timeline export into an amplification map: whose material does this account push, and how large are those accounts?
Public profile timelines, single post URLs and the whole repost/quote resolution run with no login. Two options need an X session cookie — they are listed explicitly under Which features need an X session.
What this X (Twitter) scraper does
- Scrapes X / Twitter profiles by handle, profile URL or numeric user ID, and single post URLs — one dataset row per post.
- Labels every post with
share_type:original,repostorquote. - Resolves the shared post into
original_post— full untruncated text (long-formnote_tweetincluded), its own engagement counts, and the original author's audience stats. - Amplification-only mode (
onlySharedPosts) — drops the account's own posts so the export is purely what it shares. - Author-size screen (
minOriginalAuthorFollowers) — keep only shared posts whose original author is above a follower threshold. - Reposter roster (
listReposters, needs a session) —reposterchild rows naming the accounts X will serve as having reposted each collected post, with follower count, bio, location, badge and account age. - Keeps the full base output contract: every column the base
Twitter X Tweets Scraper Scraperemits is present with the same value, includingquoted_postwith all eight of its keys and its historically misspelleddata_postedkey.
Use cases
- Partnership and creator scouting — find whose posts a brand account repeatedly amplifies.
- Competitive media monitoring — separate an account's own voice from what it re-broadcasts.
- Newsroom sourcing — resolve a quoted post to the original author and their reach.
- Audience research — export the accounts that reposted a specific post.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
startUrls | array of strings | ["NASA"] | Profiles or single post URLs. Accepts https://x.com/NASA, https://twitter.com/NASA, NASA, @NASA, a numeric user id, or https://x.com/NASA/status/2083317461269598348. Required. |
resolveSharedPosts | boolean | true | Build the original_post object on repost and quote rows. Off: rows are still labelled, original_post is null. No extra request either way. |
onlySharedPosts | boolean | false | Keep only reposts and quotes; drop the account's own original posts. |
minOriginalAuthorFollowers | integer | 0 | Drop shared posts whose original author has fewer followers than this. Above 0 it also drops original posts and quotes X refused to hydrate. Requires resolveSharedPosts. |
maxTweets | integer | 10 | Matching post rows to keep per profile (1–1000). Post URLs ignore it. |
sortOrder | enum | recent | recent / oldest / popular — re-orders the posts collected in this run only. |
includeReplies | boolean | false | Also read the profile's own replies ("Posts and replies" tab). Needs an X session. |
listReposters | boolean | false | Add reposter child rows per post. Needs an X session. |
maxRepostersPerPost | integer | 100 | Cap on reposter rows per post (1–5000). |
auth_token | string (secret) | — | auth_token cookie from an x.com browser session. Optional. |
ct0 | string (secret) | — | ct0 cookie from the same session. Required together with auth_token. |
proxyConfiguration | object | Apify Proxy off | Optional. X was measured serving this data to a bare Apify datacenter exit. |
Input example
{"startUrls": ["Interior"],"maxTweets": 20,"onlySharedPosts": true,"minOriginalAuthorFollowers": 100000,"resolveSharedPosts": true}
Output
Post rows (type: "tweet")
Every base column, unchanged:
type, id, url, user_posted, name, description, date_posted, likes, replies, reposts, quotes, bookmarks, views, lang, conversation_id, is_repost, reposted_by, is_quote, is_reply, in_reply_to_user, in_reply_to_post_id, is_pinned, is_verified, is_blue_verified, verified_type, followers, following, posts_count, profile_image_link, biography, external_url, hashtags, tagged_users, photos, videos, media, quoted_post, poll, link_preview, input
Added by this actor:
| Field | Type | Notes |
|---|---|---|
share_type | string | original, repost or quote. Always present. |
original_post | object / null | null on an original post, and on every row when resolveSharedPosts is off. |
original_post.post_id | string | The shared post's own id. |
original_post.url | string | https://x.com/<author>/status/<post_id>. |
original_post.text | string | Full text, long-form note_tweet preferred over the truncated full_text. |
original_post.date_posted | string | ISO-8601 UTC. |
original_post.likes / .reposts / .replies / .quotes / .bookmarks / .views | integer | The original's counts, not the sharer's. |
original_post.author_username / .author_name / .author_id | string | Who actually wrote it. |
original_post.author_followers | integer | Their follower count at fetch time. |
original_post.author_is_verified | boolean | Blue verification. |
original_post.author_bio | string | Their profile bio. |
original_post.media_count | integer | Photos + videos attached to the original. A genuine 0 — X publishes the attachment list. |
Note on reposts: this actor family builds a repost row from the original post, so id, user_posted, likes and friends on the row itself already describe the original, with the sharing account named in reposted_by. original_post states the same source explicitly and adds the author-audience fields the row does not carry. On a quote row the two halves genuinely differ — the row is the quoting post, original_post is the quoted post.
Reposter rows (type: "reposter", only when listReposters is on)
id, handle, name, profile_url, followers, following, posts_count, is_blue_verified, verified_type, biography, location, account_created_at, profile_image_link, post_id, post_url, post_author, post_reposts_declared, post_reposters_collected, input
post_reposts_declared is X's own repost counter for that post; post_reposters_collected is how many accounts its Retweeters timeline actually served. Both ship so the gap is visible.
Fill rates on the 84-account roster measured 2026-08-04: handle, id, followers, following, posts_count, account_created_at, profile_image_link 84/84; biography 76/84; location 48/84 (X only has it when the account filled the field in); verified_type 2/84 (only Business/Government accounts carry one — null means no special type, not unknown). These live in the 👥 Reposters view, never in the default post table.
There is no is_protected column on a reposter row: X's Retweeters timeline structurally never serves a protected account (measured false on 134/134 accounts, true never once), so the column could only carry a single value and was dropped rather than shipped dead. Protected reposters are still visible as the gap between post_reposts_declared and post_reposters_collected.
Accounting rows (type: "error", never charged)
type, id (null), target, errorReason, message. Reasons include user_not_found, account_suspended, protected_account, post_not_found, no_posts_returned, no_shared_posts, auth_required, rate_limited, request_failed. no_shared_posts states how many posts were read before concluding nothing matched.
Dataset views
📋 Posts (default), 🔁 Shared originals, 👥 Reposters, 🖼️ Media & entities, 💬 Quoted posts (base contract), 📊 Polls & link cards, 👤 Author profile, ⚠️ Skipped targets. Columns that only fill under an opt-in setting live in their own view, so the default table is not half blank.
Which features need an X session
| Feature | Session needed? |
|---|---|
| Profile timelines, single post URLs | No |
share_type | No |
original_post — including the original author's followers, bio and badge | No |
onlySharedPosts, minOriginalAuthorFollowers | No |
includeReplies (the profile's own replies) | Yes — X answers a logged-out caller with HTTP 404 and an empty body |
listReposters (the reposter roster) | Yes — same empty 404 on X's Retweeters timeline |
Both session-only options refuse before spending a single request when the cookies are missing, and the run ends FAILED with an explanation. Neither ever returns an empty roster or a public timeline dressed up as a result.
The cookies are declared as encrypted secret inputs, are read from the run input only, are sent only to api.x.com, and are scrubbed out of every log line and exception message. They are never written into the dataset, the source, or this file.
Limits (re-measured 2026-08-04)
- How much a run returns depends entirely on the account's habits. Measured 2026-08-04, newest posts first:
@NASA8 reposts and 0 quotes of 20 posts,@Interior7 reposts and 2 quotes of 20,@NASAWebb2 and 1 of 13,@BBCBreaking0 and 0 of 20. These are habits, not constants — they move as the account posts. A newswire account withonlySharedPostson correctly returns nothing — and says so with a FAILED status and a row stating how many posts were read (119 for@BBCBreaking), not a silent empty dataset. - Community notes are not shipped.
birdwatch_pivotwas absent on every post sampled (0 of 73 posts across those four accounts, counting each post and its resolved original), so ahas_community_notecolumn would have been constantlyfalse. It was dropped rather than shipped dead. - There is no "who liked this" feature. X's
Favoriterstimeline answers even an authenticated caller with HTTP 200 and a server-terminated empty timeline, on posts with six-figure like counts. No likers column exists here. - Quote enumeration (who quoted a post) is not offered. X has no
QuoteTweetsTimelineoperation; the only route is an authenticated keyword search, which belongs to a different tool. - A quote can arrive with no original attached. When the quoted post is deleted, protected or from a suspended account, X sends only its id. Those rows keep
share_type: "quote", filloriginal_post.post_id, and leave every other fieldnull— never a0and never an empty string. - Nested shares stop after one hop. If the original is itself a quote of a third post,
original_postdescribes the original and stops there. - The reposter roster is "the reposters X will serve", not the full list. Measured on this actor 2026-08-04, post
2083281738525028863withmaxRepostersPerPost: 200: 84 unique accounts collected against 91 declared by X's own counter at fetch time (92%). The shortfall is protected and suspended accounts that stay inside the counter but are not served. Both numbers ship on every reposter row (post_reposts_declared,post_reposters_collected) so the gap is visible instead of smoothed over. A very large post keeps paginating well past several thousand accounts, somaxRepostersPerPostis the real limit there. - Turning the roster on costs one extra discovery step. X's
Retweetersquery id is not in the main client bundle, so the actor crawls the webpack chunk map onabs.twimg.com— a static CDN, zero X API quota — the first time the roster runs. - Everything is a single snapshot. Counts are read once, at fetch time, and reported as read. Nothing is stored, compared against a previous run, or turned into a rate or a score.
- Filters trim what X returned.
onlySharedPostsandminOriginalAuthorFollowersare applied in-run to the timeline pages the actor read; with a filter on it keeps reading until it has the requested number of matches or has looked at 5× that many posts (minimum 100), and logs both numbers. - Rate limits are X's. They are read from the
x-rate-limit-*headers and summarised in the log; a 429 rotates the guest token, then waits out a short window, then fails loudly.
Billing
One row_result event per charged row. Post rows and reposter rows are charged; accounting (type: "error") rows are not.