X (Twitter) Post Detail Scraper avatar

X (Twitter) Post Detail Scraper

Pricing

from $0.15 / 1,000 results

Go to Apify Store
X (Twitter) Post Detail Scraper

X (Twitter) Post Detail Scraper

Get full detail for any public X (Twitter) tweet by ID or URL. Returns text, media (photos/videos), engagement counts (likes/retweets/replies/views), entities (hashtags/URLs/mentions), and author info. HTTP-only, no login.

Pricing

from $0.15 / 1,000 results

Rating

0.0

(0)

Developer

Farhan Febrian Nauval

Farhan Febrian Nauval

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Fetch the full detail of any public X (Twitter) tweet by URL or status ID — text, media, engagement counters, author, timestamp, mentions, and hashtags — in clean structured JSON.

Why use this actor

  • No account / no login required — paste a tweet URL or status ID and get the data back.
  • No API key needed — X's official API is paid and rate-limited; this actor returns the same data the public web app shows.
  • Full tweet text — including long-form (premium) tweets over 280 characters, returned in full_text.
  • Media URLs — every photo size and video bitrate variant is included in extended_entities.media.
  • Engagement counters — like, retweet, reply, quote, bookmark, and view counts in one shot.
  • Author snapshot — handle, display name, followers, profile image, verified status captured at scrape time.
  • Bulk input — pass a mix of URLs and status IDs in one run; one clean dataset row per tweet.
  • Stable JSON output suitable for pipelines, spreadsheets, and databases — every row carries _input, _source, _scrapedAt envelope fields so you can join results back to your input list.

How it works

  1. You provide a list of tweet URLs (https://twitter.com/jack/status/20, https://x.com/jack/status/20) or bare status IDs (20).
  2. The actor fetches each tweet the same way X's web app does, then assembles a flat JSON record with full text, media, counters, and author.
  3. Results stream into your dataset, ready to download as JSON, CSV, or Excel.

You do not need to manage scrapers, browsers, or rotating IPs — all handled internally. If the primary path is unavailable for an older tweet, the actor automatically falls back to a secondary source so you still get a result.

Input

{
"tweets": [
"https://twitter.com/jack/status/20",
"1445078208190291973"
],
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["DATACENTER"]
}
}
FieldTypeDescription
tweetsarrayList of tweet URLs or status IDs. Accepts twitter.com/<user>/status/<id>, x.com/<user>/status/<id>, mobile URLs, and bare numeric IDs. Mix freely.
proxyConfigurationobjectApify Proxy settings. Datacenter proxy works for most cases; switch to residential for very large jobs.

Output

Input: https://twitter.com/jack/status/20

{
"_input": "https://twitter.com/jack/status/20",
"_source": "S1-primary",
"_scrapedAt": "2026-05-18T11:04:30.976327+00:00",
"rest_id": "20",
"id_str": "20",
"conversation_id_str": "20",
"user_id_str": "12",
"created_at": "Tue Mar 21 20:50:14 +0000 2006",
"lang": "en",
"full_text": "just setting up my twttr",
"display_text_range": [0, 24],
"favorite_count": 311853,
"retweet_count": 126211,
"reply_count": 17883,
"quote_count": 6481,
"bookmark_count": 21449,
"views": { "state": "Enabled" },
"is_quote_status": false,
"source": "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>",
"entities": {
"hashtags": [],
"symbols": [],
"urls": [],
"user_mentions": []
},
"author": {
"rest_id": "12",
"screen_name": "jack",
"name": "jack",
"description": "no state is the best state",
"created_at": "Tue Mar 21 20:50:14 +0000 2006",
"followers_count": 7537422,
"friends_count": 3,
"statuses_count": 30509,
"media_count": 2963,
"listed_count": 33146,
"favourites_count": 38827,
"is_blue_verified": true,
"profile_banner_url": "https://pbs.twimg.com/profile_banners/12/1742427520",
"url": "https://t.co/ZEpOg6rn5L"
}
}
FieldTypeDescription
_inputstringThe URL or ID exactly as you supplied it. Use this to join results back to your input list.
_sourcestringInternal tag for the path used to fetch the record. S1-primary is the fastest, richest path; S2-fallback is a simpler shape used when the primary path is unavailable.
_scrapedAtstringISO-8601 UTC timestamp when the record was scraped.
rest_idstringNumeric tweet ID as a string. Stable identifier.
id_strstringSame as rest_id; kept for compatibility with older tooling.
conversation_id_strstringID of the root tweet in the conversation thread. Equals rest_id for top-level tweets.
user_id_strstringNumeric ID of the author.
created_atstringTweet publication time in X's native format.
langstringAuto-detected language code (e.g. en, id, ja).
full_textstringComplete tweet text, including long-form content beyond 280 characters.
display_text_rangearray[start, end] character offsets of the visible portion (excludes trailing media URLs).
favorite_countintegerLike count at scrape time.
retweet_countintegerRetweet count.
reply_countintegerReply count.
quote_countintegerQuote tweet count.
bookmark_countintegerBookmark count.
viewsobjectView counter. count (string) is present when public; state indicates whether counts are exposed.
is_quote_statusbooleantrue if this tweet quotes another tweet.
sourcestringClient used to post the tweet (HTML snippet — typically "Twitter for iPhone", "Twitter Web Client", etc.).
entitiesobjectParsed entities: hashtags, user_mentions, urls, symbols.
extended_entities.mediaarrayPhoto, video, and animated-GIF attachments with every size/bitrate variant. Present only when the tweet has media.
authorobjectSnapshot of the tweet's author (handle, display name, followers, profile image, verified status, etc.).

Error envelope

Tweets that are deleted, protected, or otherwise unreachable return a structured error instead of crashing the run:

{
"_input": "https://twitter.com/jack/status/999999999999999999",
"_error": "not_found",
"_errorDetail": "S1: TweetUnavailable: NotFound; S2: 404",
"_source": "S2-fallback",
"_scrapedAt": "2026-05-18T11:05:14.012345+00:00"
}

_error values:

ValueMeaning
not_foundTweet was deleted, never existed, or the ID is invalid.
privateAuthor's account is protected — only their approved followers can see this tweet.
blockedTweet exists but X declined to serve it (age-restricted, region-blocked, or temporarily unavailable).
invalid_requestInput could not be parsed as a tweet URL or numeric ID.

Filter on _error to triage failed rows.

Pricing

This actor is billed per result: $8.00 per 1,000 tweets (Tier 6). Each successful tweet = 1 result. Errors (not_found, private, blocked, invalid_request) are not billed.

Other Sosmed Actors

PlatformActorBest for
Twitter / XX Account ScraperProfile + follower counts for any handle
Twitter / XX Account Tweets ScraperAll tweets from a user's timeline
Twitter / XX Search ScraperKeyword and hashtag search across tweets
BlueskyBluesky Post Detail ScraperSingle post detail on Bluesky
ThreadsThreads Post Detail ScraperSingle post detail on Threads
InstagramInstagram Post Detail ScraperSingle post detail on Instagram
RedditReddit Post Detail ScraperSingle post + comments thread on Reddit

Browse the full catalog at apify.com/xtracto.

Notes

  • Deleted tweets return {"_error": "not_found", "_input": "..."} — they cannot be recovered after the author or X removes them.
  • Protected accounts cannot be fetched. If the author has set their tweets to "Protected" (followers-only), the tweet returns {"_error": "private", ...}.
  • View counts may be missing (views.count absent) for very new tweets or accounts that opted out of public view-count display.
  • Long-form tweets (premium tweets over 280 characters) return the full body in full_text — no truncation.
  • Media variants: when present, extended_entities.media carries every photo size and the full mp4 bitrate ladder for videos, verbatim from X's response — ready for direct download.
  • Counters are eventually-consistent and may lag the live network by a few minutes.
  • Fallback path: some older tweets are only available via the secondary source (_source: "S2-fallback"), which returns a slightly simpler shape — reply_count and quote_count may be absent in that case.