Twitter X Tweets Scraper- Repost and Quote avatar

Twitter X Tweets Scraper- Repost and Quote

Pricing

from $4.99 / 1,000 results

Go to Apify Store
Twitter X Tweets Scraper- Repost and Quote

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

API Empire

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

0

Monthly active users

13 days ago

Last modified

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, repost or quote.
  • Resolves the shared post into original_post — full untruncated text (long-form note_tweet included), 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) — reposter child 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 Scraper emits is present with the same value, including quoted_post with all eight of its keys and its historically misspelled data_posted key.

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

FieldTypeDefaultWhat it does
startUrlsarray 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.
resolveSharedPostsbooleantrueBuild the original_post object on repost and quote rows. Off: rows are still labelled, original_post is null. No extra request either way.
onlySharedPostsbooleanfalseKeep only reposts and quotes; drop the account's own original posts.
minOriginalAuthorFollowersinteger0Drop 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.
maxTweetsinteger10Matching post rows to keep per profile (1–1000). Post URLs ignore it.
sortOrderenumrecentrecent / oldest / popular — re-orders the posts collected in this run only.
includeRepliesbooleanfalseAlso read the profile's own replies ("Posts and replies" tab). Needs an X session.
listRepostersbooleanfalseAdd reposter child rows per post. Needs an X session.
maxRepostersPerPostinteger100Cap on reposter rows per post (1–5000).
auth_tokenstring (secret)auth_token cookie from an x.com browser session. Optional.
ct0string (secret)ct0 cookie from the same session. Required together with auth_token.
proxyConfigurationobjectApify Proxy offOptional. 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:

FieldTypeNotes
share_typestringoriginal, repost or quote. Always present.
original_postobject / nullnull on an original post, and on every row when resolveSharedPosts is off.
original_post.post_idstringThe shared post's own id.
original_post.urlstringhttps://x.com/<author>/status/<post_id>.
original_post.textstringFull text, long-form note_tweet preferred over the truncated full_text.
original_post.date_postedstringISO-8601 UTC.
original_post.likes / .reposts / .replies / .quotes / .bookmarks / .viewsintegerThe original's counts, not the sharer's.
original_post.author_username / .author_name / .author_idstringWho actually wrote it.
original_post.author_followersintegerTheir follower count at fetch time.
original_post.author_is_verifiedbooleanBlue verification.
original_post.author_biostringTheir profile bio.
original_post.media_countintegerPhotos + 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

FeatureSession needed?
Profile timelines, single post URLsNo
share_typeNo
original_post — including the original author's followers, bio and badgeNo
onlySharedPosts, minOriginalAuthorFollowersNo
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: @NASA 8 reposts and 0 quotes of 20 posts, @Interior 7 reposts and 2 quotes of 20, @NASAWebb 2 and 1 of 13, @BBCBreaking 0 and 0 of 20. These are habits, not constants — they move as the account posts. A newswire account with onlySharedPosts on 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_pivot was absent on every post sampled (0 of 73 posts across those four accounts, counting each post and its resolved original), so a has_community_note column would have been constantly false. It was dropped rather than shipped dead.
  • There is no "who liked this" feature. X's Favoriters timeline 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 QuoteTweetsTimeline operation; 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", fill original_post.post_id, and leave every other field null — never a 0 and never an empty string.
  • Nested shares stop after one hop. If the original is itself a quote of a third post, original_post describes 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 2083281738525028863 with maxRepostersPerPost: 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, so maxRepostersPerPost is the real limit there.
  • Turning the roster on costs one extra discovery step. X's Retweeters query id is not in the main client bundle, so the actor crawls the webpack chunk map on abs.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. onlySharedPosts and minOriginalAuthorFollowers are 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.