X (Twitter) Tweets & Profiles Scraper avatar

X (Twitter) Tweets & Profiles Scraper

Pricing

from $6.15 / 1,000 results

Go to Apify Store
X (Twitter) Tweets & Profiles Scraper

X (Twitter) Tweets & Profiles Scraper

Scrape public X (Twitter) tweets and profiles by handle or tweet ID. Extract text, author, likes, retweets, replies, quotes, views, followers, bio, hashtags and media. No login needed. Export to JSON, CSV or Excel.

Pricing

from $6.15 / 1,000 results

Rating

5.0

(1)

Developer

Scrapers Lat

Scrapers Lat

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

1

Monthly active users

21 hours ago

Last modified

Share

X (Twitter) Tweets & Profiles Scraper

X (Twitter) Tweets & Profiles Scraper

Here is one real result, with every field a tweet record returns:

{
"id": "2085865635586912359",
"url": "https://x.com/OpenAI/status/2085865635586912359",
"text": "https://t.co/zBh8ck0Gbc",
"author": {
"handle": "OpenAI",
"name": "OpenAI",
"verified": true,
"followers": 5096946
},
"createdAt": "Fri Aug 07 23:08:15 +0000 2026",
"conversationId": "2085801349866729975",
"likeCount": 358,
"retweetCount": 3,
"replyCount": 37,
"quoteCount": 3,
"bookmarkCount": 18,
"viewCount": 183207,
"lang": "zxx",
"source": "Twitter Web App",
"isReply": true,
"inReplyToTweetId": "2085801349866729975",
"inReplyToUserId": "4398626122",
"inReplyToHandle": "OpenAI",
"isRetweet": false,
"isQuote": true,
"possiblySensitive": false,
"noteTweet": null,
"media": [],
"entities": {
"hashtags": [],
"mentions": [],
"urls": [
"https://x.com/sama/status/2085862292311396515"
]
},
"quotedTweet": {
"id": "2085862292311396515",
"text": "astra is a powerful model and we are working to make it generally available.\n\nwe do not think it is a good strategy to keep powerful models to a chosen few.\n\ngiven its cyber capabilities, we need a little big longer to do do this safely. but hopefully not too long!",
"author": {
"handle": "sama",
"name": "Sam Altman"
}
},
"retweetedTweet": null,
"observedAt": "2026-08-10T14:39:54.066Z"
}

The most complete X (Twitter) scraper available for logged-out reads. It returns every field X exposes for each tweet, from full engagement metrics (likes, retweets, replies, quotes, bookmarks, views) to entities, media, and the referenced quote or retweet, plus three modes so you can pull an account's tweets, a full profile, or specific tweets by ID or URL.

📥 Input · 📤 Output · 💰 Pricing · ▶️ Examples

Apify Coverage Output Billing

Table of contents

What it does

The actor reads public X (Twitter) data through X's guest GraphQL endpoints and writes one normalized record per tweet or profile to the run's dataset. Pick a mode:

  • userTweets (default): pull a public account's recent posts. One record per tweet.
  • userProfile: pull profile details (bio, followers, counts). One record per handle.
  • tweet: fetch specific tweets by numeric ID or full status URL.

Handles can be provided as @name, name, or a profile URL; duplicates are removed. Missing source values are returned as null. Longform note-tweets are returned with their full untruncated text.

Keyword search is shown in the input but is not available: X requires a logged-in account for search, so that mode returns a clear error instead of fake or empty data.

Quickstart

Open the actor, paste this into the input, and press Run. It returns up to 10 recent tweets from the given accounts.

{
"mode": "userTweets",
"handles": ["nasa", "OpenAI"],
"tweetsLimit": 10,
"maxPosts": 10
}

Switch mode to userProfile for profile records, or to tweet and pass tweetIds (IDs or URLs) to fetch specific tweets. Set includeReplies to true to include the account's replies.

Input reference

FieldTypeRequiredDefaultDescription
modeenumnouserTweetsWhat to scrape: userTweets, userProfile, tweet, or search (search returns a login-required error).
handlesstring[]for user modes["nasa","OpenAI"]Public X handles for userTweets and userProfile. Accepts @name, name, or a profile URL.
tweetsLimitintegerno100For userTweets: maximum tweets to collect per handle (paginated). Range 1 to 3200.
includeRepliesbooleannofalseFor userTweets: also include the account's replies (tweets-and-replies timeline).
tweetIdsstring[]for tweet mode(sample)Numeric tweet IDs (for example 20) or full status URLs such as https://x.com/jack/status/20.
maxPostsintegerno(unbounded)Maximum posts to collect across all inputs. Caps the whole run.
searchQuerystringno(empty)Keyword for search mode. Not available (X login-gated); returns a clear error.
searchTypeenumnoTopTop or Latest for search mode. Not used (search login-gated).
langstringnoenTwo-letter UI language hint sent to X for localized fields.

Output reference

Tweet records (userTweets and tweet modes). Types: string, number, boolean, object, object[], or null when the source value is absent.

FieldTypeDescription
idstringTweet ID (unique per tweet).
urlstringCanonical tweet URL on x.com.
textstringTweet text (full untruncated text for longform note-tweets).
authorobjectAuthor object: handle, name, verified, followers.
createdAtstringTweet creation timestamp as returned by X.
conversationIdstringID of the conversation (thread root).
likeCountnumberNumber of likes.
retweetCountnumberNumber of retweets.
replyCountnumberNumber of replies.
quoteCountnumberNumber of quote tweets.
bookmarkCountnumberNumber of bookmarks, or null.
viewCountnumberNumber of views, or null when X does not expose it.
langstringLanguage code X assigned to the tweet.
sourcestringPosting client label, for example Twitter Web App.
isReplybooleanWhether the tweet is a reply.
inReplyToTweetIdstringID of the tweet being replied to, or null.
inReplyToUserIdstringUser ID being replied to, or null.
inReplyToHandlestringHandle being replied to, or null.
isRetweetbooleanWhether the tweet is a retweet.
isQuotebooleanWhether the tweet quotes another tweet.
possiblySensitivebooleanX sensitivity flag, or null.
noteTweetstringFull longform note-tweet text when present, else null.
mediaobject[]Attached media: each object holds type, url, videoUrl, width, height, expandedUrl.
entitiesobjectParsed entities: hashtags, mentions, urls; null when the tweet has none.
quotedTweetobjectCompact quoted tweet (id, text, author), or null.
retweetedTweetobjectCompact retweeted tweet (id, text, author), or null.
observedAtstringISO 8601 timestamp of when the record was collected.

In userProfile mode each record instead holds profile fields: handle, name, bio, website, followers, following, tweetsCount, mediaCount, listedCount, verified, protected, location, joinedAt, pinnedTweetId, avatar, banner, url, id, observedAt. On any failure, a single item with a populated error field is written instead.

Example output record

Real tweet record from a live run (input {"mode":"userTweets","handles":["nasa","OpenAI"],"tweetsLimit":10}):

{
"id": "2085865635586912359",
"url": "https://x.com/OpenAI/status/2085865635586912359",
"text": "https://t.co/zBh8ck0Gbc",
"author": {
"handle": "OpenAI",
"name": "OpenAI",
"verified": true,
"followers": 5096946
},
"createdAt": "Fri Aug 07 23:08:15 +0000 2026",
"conversationId": "2085801349866729975",
"likeCount": 358,
"retweetCount": 3,
"replyCount": 37,
"quoteCount": 3,
"bookmarkCount": 18,
"viewCount": 183207,
"lang": "zxx",
"source": "Twitter Web App",
"isReply": true,
"inReplyToTweetId": "2085801349866729975",
"inReplyToUserId": "4398626122",
"inReplyToHandle": "OpenAI",
"isRetweet": false,
"isQuote": true,
"possiblySensitive": false,
"noteTweet": null,
"media": [],
"entities": {
"hashtags": [],
"mentions": [],
"urls": ["https://x.com/sama/status/2085862292311396515"]
},
"quotedTweet": {
"id": "2085862292311396515",
"text": "astra is a powerful model and we are working to make it generally available.\n\nwe do not think it is a good strategy to keep powerful models to a chosen few.\n\ngiven its cyber capabilities, we need a little big longer to do do this safely. but hopefully not too long!",
"author": {
"handle": "sama",
"name": "Sam Altman"
}
},
"retweetedTweet": null,
"observedAt": "2026-08-10T14:39:54.066Z"
}

Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace <TOKEN> with your Apify API token.

Run synchronously and get dataset items in one call:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~x-twitter-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"mode":"userTweets","handles":["nasa"],"tweetsLimit":25}'

Start a run asynchronously:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~x-twitter-scraper/runs?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"mode":"tweet","tweetIds":["https://x.com/BarackObama/status/266031293945503744"]}'

Apify CLI:

apify call scrapers_lat/x-twitter-scraper \
--input '{"mode":"userProfile","handles":["OpenAI"]}'

Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing format:

# JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"
# CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"
# Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"

<DATASET_ID> is returned as defaultDatasetId in the run object. Use offset and limit to page through large result sets. clean=true drops empty and internal fields.

Billing and limits

  • Pay per result. You are charged per tweet or profile record returned (result event). See the pricing tab for the current per-result price.
  • No charge on failure. Handles or tweets that cannot be read (not found, suspended, protected, rate-limited) are written with a populated error field and are not charged.
  • Spend cap respected. Set maxTotalChargeUsd on the run; once reached, the actor stops emitting and charging further billable results.
  • Free Apify plans are capped at 10 records per run. Upgrade for more.

FAQ and troubleshooting

Why can't I search by keyword? X disabled logged-out (guest) search, so the search mode returns a clear error rather than fake results. Use userTweets to pull a specific account's posts.

How many tweets can I get per account? Up to tweetsLimit (max 3200), paginated through the account timeline. maxPosts caps the whole run across all handles.

Why did a handle or tweet return an error? The account or tweet is protected, suspended, deleted, or X rate-limited the request at that moment. Error records are not charged. Re-run rate-limited inputs.

How do I get replies too? Set includeReplies to true in userTweets mode. If X's replies timeline is temporarily unavailable, the actor falls back to the default timeline so you still get the account's posts.

Is this an official X tool? No. This actor is independent and has no affiliation with X (formerly Twitter). It reads only data that is publicly available to logged-out users.

More scrapers at scrapers.lat

Built and maintained by scrapers.lat, where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at scrapers.lat.


Independent tool, not affiliated with X (formerly Twitter). Accesses only publicly available data. Keyword search is login-gated by X and is not supported.