SFOLN

Catalogue / Social media data

Tweet Replies Scraper (X / Twitter)

sfoln/x-post-replies · Social media, News, Lead generation On request

Scrape the replies to any public X (Twitter) post: text, date, author, likes, reposts, views, media, hashtags and links, one JSON row per reply. Paste post URLs or IDs; 20–200 newest replies per post. $0.70 per 1,000 replies; posts without replies are free.

About

What it does

Tweet Replies Scraper (X / Twitter) gets the replies to any public X (Twitter) post as clean, flat records: reply text, timestamp, author (handle, name, followers, blue check), likes, reposts, replies, quotes, views, bookmarks, media links, hashtags, mentions and links. Paste post URLs or IDs and receive one dataset row per reply: ideal for audience sentiment, customer-feedback mining, community management, campaign monitoring and LLM training/evaluation sets.

Price

Price per delivered record

EventPricePer 1,000Charged for
X reply
x-reply
$0.0007$0.70 / 1,000Charged once per reply delivered to the dataset. Per-post summary rows are free.

Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.

Run

Call it from code, an agent or the Console

This API is private on Apify for now. Email us and we will publish it for you, usually within two working days. The calls below work once it is public. contact@sfoln.com

curl · synchronous run, rows in the response
curl -X POST "https://api.apify.com/v2/actors/sfoln~x-post-replies/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"posts":["1846987139428634858"]}'
mcp.json · hosted Apify MCP server
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/x-post-replies"
    }
  }
}
asynchronous run · for large batches
POST https://api.apify.com/v2/actors/sfoln~x-post-replies/runs?maxTotalChargeUsd=1
GET  https://api.apify.com/v2/actor-runs/{runId}            # until status is SUCCEEDED
GET  https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json

Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: Get the 100 newest replies to https://x.com/jack/status/20 and summarize the overall sentiment and the most common themes.

Input

Input fields

Paste X (Twitter) post URLs or ids. The Actor returns the replies to each post (newest first), one dataset record per reply, plus one summary record per post.

FieldTypeDefaultMeaning
posts *arrayrequiredPost URLs or ids
x.com / twitter.com status URLs or numeric post ids, one per line. Use the first post of a thread (the upstream returns replies to thread roots). Accounts on the Apify free plan can process up to 10 posts per run.
maxRepliesPerPostinteger20Max replies per post
How many of the most recent replies to return per post (20–200). Replies are fetched in pages of ~20, so the minimum is one page. Range 20–200.
maxItemsinteger1000Max posts
Safety cap on the number of posts processed in this run. Range 1–10000.
concurrencyinteger3Concurrency
Posts processed in parallel (1–5). Range 1–5.
itemTimeoutSecsinteger300Per-post time limit (seconds)
Stop paginating a post after this long; rows already delivered are kept. Range 30–1800.
includeRawbooleanfalseInclude raw upstream response
Attach the unmodified TwitterAPI.io payload to each record under `raw` (larger output).
Example input
{
  "posts": [
    "1846987139428634858"
  ]
}

Output

One record per input item

Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.

FieldTypeMeaning
inputstring | objectInput
The input item this record corresponds to.
statusstringStatus
ok | not_found | error | skipped_invalid | skipped_budget | skipped_free_plan (result rows are always ok) e.g. "ok"
chargedbooleanCharged
Whether this record incurred a pay-per-event charge.
chargedEventstringCharged event
Pay-per-event event charged for this record.
sourcestringSource
Upstream data source (twitterapi = TwitterAPI.io).
fetchedAtstringFetched at
ISO timestamp.
errorobjectError
code / message when status is not ok.
warningsarrayWarnings
Non-fatal notes (e.g. stopped early).
recordTypestringRow type
reply (one per reply, charged) | post-summary (one per input post, free).
parentTweetIdstring | nullParent post id
The input post these replies belong to.
idstring | nullPost id
Numeric post (tweet) id as a string.
urlstring | nullURL
Link to the post on x.com.
textstring | nullText
Full post text.
createdAtstring | nullCreated at
ISO 8601 creation time.
langstring | nullLanguage
Language code detected by X.
postedViastring | nullPosted via
Client app used to post.
authorHandlestring | nullAuthor handle
Author's handle without @.
authorIdstring | nullAuthor id
Author's numeric user id.
authorNamestring | nullAuthor name
Author display name.
authorFollowersinteger | nullAuthor followers
Author follower count at fetch time.
authorIsBlueVerifiedboolean | nullAuthor blue verified
Author has a blue check.
likesinteger | nullLikes
Like count.
retweetsinteger | nullReposts
Repost (retweet) count.
repliesinteger | nullReplies
Reply count.
quotesinteger | nullQuotes
Quote count.
viewsinteger | nullViews
View count (null when X does not report it).
bookmarksinteger | nullBookmarks
Bookmark count.
isReplybooleanIs reply
Post is a reply.
inReplyToIdstring | nullIn reply to post
Parent post id.
inReplyToUserIdstring | nullIn reply to user id
Parent author id.
inReplyToHandlestring | nullIn reply to handle
Parent author handle.
conversationIdstring | nullConversation id
Root post id of the thread.
isRetweetbooleanIs repost
Post is a repost.
retweetedTweetIdstring | nullReposted post id
Original post id for reposts.
isQuotebooleanIs quote
Post quotes another post.
quotedTweetIdstring | nullQuoted post id
Quoted post id.
hashtagsarrayHashtags
Hashtags without #.
mentionsarrayMentions
Mentioned handles without @.
urlsarrayLinks
Expanded links in the post.
mediaarrayMedia
Photos / videos: type, url, videoUrl (best MP4), expandedUrl.
mediaCountintegerMedia count
Number of attached media items.
tweetIdstring | nullInput post id
Parsed post id (summary rows).
repliesReturnedinteger | nullReplies returned
Replies delivered for this post (summary rows).
pagesFetchedinteger | nullPages fetched
Upstream pages fetched (summary rows).
stopReasonstring | nullStop reason
limit | end | budget | deadline | empty_pages | max_pages | error (summary rows).
Example record
{
  "input": "https://x.com/elonmusk/status/1846987139428634858",
  "recordType": "reply",
  "parentTweetId": "1846987139428634858",
  "id": "1846990000000000001",
  "url": "https://x.com/jane_dev/status/1846990000000000001",
  "text": "@elonmusk great point #space",
  "createdAt": "2024-10-18T09:30:00.000Z",
  "lang": "en",
  "postedVia": "Twitter for iPhone",
  "authorHandle": "jane_dev",
  "authorId": "1458000000000000000",
  "authorName": "Jane",
  "authorFollowers": 812,
  "authorIsBlueVerified": false,
  "likes": 4,
  "retweets": 0,
  "replies": 1,
  "quotes": 0,
  "views": 230,
  "bookmarks": 0,
  "isReply": true,
  "inReplyToId": "1846987139428634858",
  "inReplyToUserId": "44196397",
  "inReplyToHandle": "elonmusk",
  "conversationId": "1846987139428634858",
  "isRetweet": false,
  "retweetedTweetId": null,
  "isQuote": false,
  "quotedTweetId": null,
  "hashtags": [
    "space"
  ],
  "mentions": [
    "elonmusk"
  ],
  "urls": [],
  "media": [],
  "mediaCount": 0,
  "status": "ok",
  "charged": true,
  "chargedEvent": "x-reply",
  "source": "twitterapi",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}

Machine-readable

This page for agents