Twitter Profile Scraper: tweets and their replies
Twitter Profile Scraper returns the tweets an X account has posted, and optionally the reply threads hanging off the ones that got a conversation going.
Free Apify plan: 5 runs a month, 10 items a run. No credit card.
- $0.016
- per profile, 40 tweets in
- $0.016
- per reply thread, 36 in
- 2.8K
- users · 3.4 from 11 reviews
- 99.94%
- run success, last 30 days
Read on 21 September 2026.
What makes a run cheap or expensive?
Naming a profile costs $0.016 and brings 40 tweets with it. Everything after that is decided by two inputs: a date range, which trims what you pay for, and a reply threshold, which multiplies how many queries fire.
twitterHandles · startUrls$0.016per profile
40 tweets included
Name the account. The first 40 of its tweets come inside the fee, two pages worth.
["taylorswift13"]The multiplier, not the filter
minReplyCountquery countnot a filter
Each qualifier is $0.016
The threshold a tweet must clear before its replies are fetched. Prefilled at 0, so every tweet with a single reply qualifies.
minReplyCount: 100start · enddate rangeyour cost trim
Hour precision available
Trims the window. You still pay the profile fee, but you stop paying for tweets outside the period you care about.
2026-11-06_07:00:59_UTCgetAboutData$0.002per profile
Nested under author.about
Adds account metadata: creation date, username change history, verification timestamps, account source.
getAboutData: true
Every tweet past the 40 and every reply past the 36 costs $0.0004. Those two allowances are deliberately different numbers, and confusing them is how a budget comes out 7% wrong and the listing does it in its own cost table.
| Apify actor | apidojo/twitter-profile-scraper |
|---|---|
| Inputs | twitterHandles · startUrls · start · end · getReplies · minReplyCount · getAboutData · includeNativeRetweets · onlyImages · maxItems |
| Returns | One record per tweet or reply, with the author object on every one |
| Two free allowances | 40 tweets on a profile query, 36 replies on a reply query. Different numbers |
| Date formats | 2026-10-10, or 2026-11-06_07:00:59_UTC for hour precision |
| Native retweets | Excluded unless includeNativeRetweets is on |
| Login or proxy | Neither. Public accounts only |
| Reliability | 99.94% of 75,753 runs succeeded in the last 30 days |
Tweets, threads, or a window
Three ways to run it, and they differ by an order of magnitude in cost. Pull an account’s tweets, walk into the conversations underneath the ones that mattered, or bound the whole thing to a campaign window.
How do you scrape all the tweets from an X profile?
Put the handle in twitterHandles and leave getReplies off. The profile costs $0.016 with 40 tweets inside it, then $0.0004 a tweet. Five hundred tweets from one account cost $0.20.
Input
{
"twitterHandles": ["taylorswift13"],
"getReplies": false,
"maxItems": 500
}$0.016 + 460 × $0.0004=$0.20
What comes back
The tweet record, Six engagement counters, the author object, media URLs and parsed entities.
{
"type": "tweet",
"id": "1970912731290058851",
"url": "https://x.com/taylorswift13/status/1970912731290058851",
"text": "A showgirl knows to save some of her best tricks…",
"retweetCount": 34399,
"replyCount": 4152,
"likeCount": 190278,
"quoteCount": 7463,
"viewCount": 7901648,
"bookmarkCount": 5363,
"conversationId": "1970912731290058851",
"source": "Twitter for iPhone"
}Native retweets are left out unless you ask
includeNativeRetweets is off, so what comes back is what the account actually wrote. Turn it on when amplification is the thing you are measuring rather than authorship and the listing notes it only applies in some cases.
How do you scrape the replies to an account’s tweets?
Turn getReplies on and set minReplyCount to the level that matters. Every tweet clearing the bar fires its own $0.016 query with 36 replies inside it. Five threads of 50 replies add $0.11 to the run.
Input
{
"twitterHandles": ["taylorswift13"],
"getReplies": true,
"minReplyCount": 1000,
"maxItems": 2000
}5 × $0.016 + 70 × $0.0004=$0.11
What comes back
The reply record, The same shape as a tweet, with isReply true and conversationId tying it back.
{
"type": "tweet",
"isReply": true,
"conversationId": "1970912731290058851",
"text": "the bridge on track 9 is unreal",
"likeCount": 812,
"replyCount": 3,
"author": {
"userName": "example_fan",
"followers": 1204,
"isBlueVerified": false
}
}minReplyCount is prefilled at 0
Leave it there with getReplies on and every tweet carrying a single reply fires a $0.016 query. On a 200-tweet profile where 30 tweets qualify, that is $0.48 in reply queries against $0.016 for the profile itself, thirty times the base fee. Set the threshold to the engagement level you actually care about.
How do you scrape tweets from a specific date range?
Set start and end. The profile fee is unchanged, but you stop paying $0.0004 for every tweet outside the period. A single account’s launch week, around 80 tweets, costs $0.032.
Input
{
"twitterHandles": ["taylorswift13"],
"start": "2026-10-01",
"end": "2026-10-07_23:59:59_UTC",
"getReplies": false,
"maxItems": 1000
}$0.016 + 40 × $0.0004=$0.032
What comes back
The tweet record, Unchanged. createdAt is what the range filters on, in X’s own string format.
{
"type": "tweet",
"createdAt": "Wed Oct 01 18:06:27 +0000 2026",
"lang": "en",
"media": [
"https://pbs.twimg.com/media/G1oWrA9W0AA49ys.jpg"
],
"entities": {
"hashtags": [],
"urls": [],
"user_mentions": []
}
}The form arrives with 2025 already in the boxes
start and end are prefilled to 2025-01-01 and 2025-12-31. They are prefills rather than defaults, so an API call that omits them is unbounded while a run launched from the web form is quietly limited to 2025. Clear them or set them; do not assume they are empty.
Inside a tweet record
Tweets and replies share one shape. It carries more engagement counters than most X data sources expose, and with getAboutData on the author gains a nested metadata block.
7
The tweet
Always present
- id, url, twitterUrl
- text, fullText
- createdAt
- lang
- source, the posting client
6
Engagement
Six counters, not three
- likeCount, retweetCount
- replyCount, quoteCount
- viewCount
- bookmarkCount
5
The author
author, on every record
- author.userName, name, id
- author.description
- author.followers, following
- author.isVerified
- author.isBlueVerified
7
Thread and extras
Some conditional
- isReply, conversationId
- media[], image and video URLs
- entities{ hashtags, urls, user_mentions }
- author.about, with getAboutData
id · url · twitterUrl | Tweet ID and both the x.com and twitter.com links |
|---|---|
text · fullText | The tweet body, and the untruncated form |
source | Which client posted it, e.g. "Twitter for iPhone" |
createdAt | X’s own date string format, not ISO 8601 |
likeCount · retweetCount | The two headline counters |
replyCount | What minReplyCount is compared against |
quoteCount · bookmarkCount | Quote-tweets and saves, counted separately |
viewCount | Impressions where X exposes them |
isReply · conversationId | Whether this is a reply, and which thread it belongs to |
media | Array of image and video URLs |
entities | Parsed hashtags, urls and user_mentions |
author.followers · following | The author’s counts at run time |
author.isVerified · isBlueVerified | Legacy verification and X Premium, separately |
author.about.accountCreatedAt | With getAboutData: when the account was made |
author.about.usernameChangeCount | How many times the handle has changed, and when |
author.about.verifiedSince | When verification was granted |
conversationId is what stitches a run back together: every reply carries the ID of the tweet that started its thread, so one flat dataset rebuilds into conversations without a second pass.
Before you turn replies on
Five things decide what a run costs and what comes back. The first is responsible for almost every surprising invoice on this actor.
- 01
Each qualifying tweet is its own $0.016 query
getReplies does not fetch replies in bulk. It fires one reply query per tweet that clears minReplyCount, and minReplyCount is prefilled at 0. Thirty qualifying tweets is $0.48 before a single reply is billed.
- 02
The two free allowances are different
40 tweets come with a profile query; 36 replies come with a reply query. Using 36 where you meant 40 understates a five-profile budget by about 7%, which is exactly the slip in the listing’s own table.
- 03
start and end are prefilled, not empty
The web form arrives with 2025-01-01 and 2025-12-31 in place. An API call that omits them is unbounded, so the same input can behave differently depending on where you launched it.
- 04
Native retweets are excluded by default
What comes back is what the account wrote. includeNativeRetweets adds amplification, and the listing notes it only applies in some cases.
- 05
onlyImages applies to replies too
Switching it on filters both the tweets and the replies underneath them, which narrows a thread run more than people expect.
On a free Apify account: 5 runs a month, 10 items in each.
Profiles are cheap, threads are not
A profile run is $0.016 plus $0.0004 a tweet past the first 40. A thread run adds $0.016 for every tweet that clears your threshold. The gap between the two halves of this table is the whole cost story.
| Run | Method | Calculation | Cost |
|---|---|---|---|
| 40 tweets | 1 profile | $0.016 | $0.016 |
| 100 tweets | 1 profile | $0.016 + 60 × $0.0004 | $0.04 |
| 500 tweets | 1 profile | $0.016 + 460 × $0.0004 | $0.20 |
| 500 tweets | 5 profiles | 5 × $0.016 + 300 × $0.0004 | $0.20 |
| 2,000 tweets | 10 profiles | 10 × $0.016 + 1,600 × $0.0004 | $0.80 |
| 250 replies | 5 reply queries | 5 × $0.016 + 70 × $0.0004 | $0.11 |
| 1,000 replies | 10 reply queries | 10 × $0.016 + 640 × $0.0004 | $0.42 |
| 4,500 replies | 30 reply queries | 30 × $0.016 + 3,420 × $0.0004 | $1.85 |
The estimator prices one kind of query at a time; a real thread run adds a profile fee on top, as the listing’s combined examples show. Eleven of its thirteen worked examples reproduce exactly from the published event prices. Two do not: it prices ten profiles at 200 tweets each at $0.704 where its own formula gives $0.800, and five profiles at 60 tweets each at $0.128 where the formula gives $0.120, the second by allowing 36 free tweets instead of 40.
Who needs an account’s conversations?
Five kinds of work want the replies rather than just the posts: sentiment analysis, crisis monitoring, competitive intelligence, influencer vetting and campaign measurement.
Sentiment analysis
Their reply threads, high threshold
Read what people said back on the posts that actually landed, instead of scoring the brand’s own words
$0.11 per 5 threads
Crisis monitoring
Their reply threads, on a live account
Watch the conversation under a statement as it develops, where the replies are the story
$1.85 per 30 threads
Competitive intelligence
An account’s tweets, several handles
Track what competitors post and how it performs across six engagement counters
$0.80 per 10 accounts
Influencer vetting
An account’s tweets, with getAboutData
Check account age, username history and verification date before signing anyone
$0.018 per account
Campaign measurement
A campaign window
Bound the run to launch week and compare it against the same window last year
$0.032 per account per week
Calling it from a script
The actor is apidojo/twitter-profile-scraper. The parameter to think hardest about is minReplyCount, because it is the one that decides how many billable queries the run fires rather than how much data comes back.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
# minReplyCount is the throttle: only tweets past this get a $0.016
# reply query. Leaving it at 0 fires one for almost every tweet.
run = client.actor("apidojo/twitter-profile-scraper").call(run_input={
"twitterHandles": ["taylorswift13"],
"getReplies": True,
"minReplyCount": 1000,
"start": "2026-10-01",
"end": "2026-10-07_23:59:59_UTC",
"maxItems": 2000,
})
for item in client.dataset(run.default_dataset_id).iterate_items():
kind = "reply" if item["isReply"] else "tweet"
print(kind, item["conversationId"], item["likeCount"], item["text"][:60])import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('apidojo/twitter-profile-scraper').call({
twitterHandles: ['taylorswift13'],
getReplies: true,
minReplyCount: 1000,
maxItems: 2000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
// conversationId rebuilds threads from a flat dataset, no second pass.
const threads = Object.groupBy(items, (i) => i.conversationId);
for (const [id, posts] of Object.entries(threads)) {
const root = posts.find((p) => !p.isReply);
console.log(id, root?.likeCount ?? '-', posts.length - 1, 'replies');
}curl -X POST \
"https://api.apify.com/v2/acts/apidojo~twitter-profile-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"twitterHandles":["taylorswift13"],"getReplies":false,"maxItems":500}'An API call that omits start and end is unbounded, unlike the web form, which arrives with a 2025 range prefilled. State the window explicitly if the run is scheduled.
Twitter Profile Scraper FAQ
Why did turning on replies cost so much more?
Every tweet that clears minReplyCount fires its own $0.016 reply query. The threshold is prefilled at 0, so a tweet with one reply qualifies. Thirty qualifying tweets means $0.48 in query fees before any reply is billed.
How much does it cost to scrape 500 tweets from a profile?
$0.20, the $0.016 profile query with 40 tweets inside it, plus 460 tweets at $0.0004 each.
How many tweets and replies are included free?
Forty tweets come with a profile query and thirty-six replies come with a reply query. They are different numbers on purpose, and mixing them up understates a budget.
Can I limit the run to a date range?
Yes. start and end accept 2026-10-10, or 2026-11-06_07:00:59_UTC for hour precision. The profile fee is unchanged, but you stop paying for tweets outside the window.
Are retweets included?
Not by default. What comes back is what the account wrote. includeNativeRetweets adds them, and the listing notes it only applies in some cases.
How do I rebuild threads from the output?
Group on conversationId. Every reply carries the ID of the tweet that started its thread, and isReply tells you which record is the root.
What does getAboutData add?
For $0.002 a profile it nests an about block under the author: account creation date, username change history and count, verification date, account source and location accuracy.
Is there a free way to try it?
A free Apify account runs it in demo mode, 5 runs a month, 10 items each, no card.
Where Twitter Profile Scraper fits
Parent scraper
Twitter Scraper
Six Twitter scrapers, what each costs, and which to reach for. Several of them return an account’s tweets; this is the only one that will also walk down into the replies underneath each of them.
Sibling scrapers
Guides
- Choosing a minReplyCount that does not bankrupt a runComing soon
- Rebuilding X threads from conversationIdComing soon
- Bookmarks and quotes: the counters nobody reportsComing soon
Scrape one profile
A cent and a half, and the first forty tweets are in it.
twitterHandles: ["taylorswift13"] · getReplies: false
Apidojo is not affiliated with X Corp.