X Twitter Post Replies Scraper avatar

X Twitter Post Replies Scraper

Pricing

from $0.14 / 1,000 item extracteds

Go to Apify Store
X Twitter Post Replies Scraper

X Twitter Post Replies Scraper

Export direct and nested public X replies with authors, text, engagement, media, timestamps, and parent-child conversation relationships.

Pricing

from $0.14 / 1,000 item extracteds

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

0

Monthly active users

5 days ago

Last modified

Categories

Share

Export the public replies X surfaces for supplied post URLs as clean, relationship-ready records.

X Twitter Post Replies Scraper collects direct and nested X Twitter post replies with author details, text, timestamps, engagement counts, media, parent post IDs, conversation IDs, and reply depth. Use it for conversation analysis, community research, engagement review, and repeatable data exports without maintaining a browser workflow.

The Actor accepts public x.com or twitter.com status URLs. It follows the reply records exposed to logged-out visitors and recursively opens surfaced child replies up to your chosen depth.

What does this X replies scraper do?

For each supplied post URL, the Actor:

  1. validates and canonicalizes the X URL;
  2. reads X's public logged-out conversation data;
  3. identifies replies whose parent is the current focal post;
  4. emits a typed record for each unique reply;
  5. follows surfaced child replies when maxDepth is greater than 1;
  6. stops at maxItems, maxDepth, or the end of surfaced data.

The default dataset contains reply records only. The supplied focal post is represented by sourcePostId and sourcePostUrl, not billed as an item.

Who is it for?

  • Social media analysts mapping how a public discussion branches.
  • Brand and community teams reviewing visible responses to announcements.
  • Researchers creating reply-author and engagement datasets.
  • Data engineers loading normalized X reply records into warehouses or notebooks.
  • Developers who need parent-child IDs without writing a fragile page parser.

Choose this Actor when you already know the post URLs. It does not search X by keyword or discover posts from profiles.

Why use this Actor?

  • No X login or user cookie is required.
  • Both direct and nested reply relationships are represented.
  • Records include useful author, media, timestamp, and engagement fields.
  • Invalid, private, deleted, or unsupported pages fail visibly instead of returning misleading empty success.
  • Limits, depth, retries, and request delay are bounded.
  • The default dataset works with Apify exports, webhooks, integrations, and API clients.

What X reply data can I extract?

FieldMeaning
postIdStable X ID of the reply
postUrlCanonical public URL of the reply
sourcePostIdID from the supplied source URL
sourcePostUrlCanonical supplied source URL
conversationIdHighest conversation ancestor exposed on the source page
parentPostIdID of the post this record replies to
depthRelationship depth from the supplied source post
isDirectReplytrue when depth is 1
textPublic reply text
createdAtReply timestamp when exposed
authorIdPublic X author ID when exposed
authorUsernameAuthor handle
authorNameDisplay name when exposed
authorProfileUrlCanonical author profile URL
authorAvatarUrlPublic avatar URL when exposed
authorFollowersVisible follower count when exposed
authorVerifiedVisible X verification state when exposed
replyCountVisible reply count
repostCountVisible repost count
likeCountVisible like count
quoteCountVisible quote count
viewCountVisible view count
bookmarkCountVisible bookmark count
mediaUrlsPublic image or best available video URLs
mediaTypesMedia types aligned with mediaUrls
scrapedAtUTC extraction timestamp

Fields that X does not expose for a particular record are omitted rather than invented.

How to get started

  1. Open the Actor input page.
  2. Paste one or more public X post URLs into X post URLs.
  3. Set Maximum replies for the total output cap.
  4. Use depth 1 for direct replies or 25 for nested relationships.
  5. Start the run.
  6. Open the Reply conversation dataset view.
  7. Export JSON, CSV, Excel, XML, or RSS, or consume the dataset through the API.

A small direct-replies input is:

{
"startUrls": [
{ "url": "https://x.com/elonmusk/status/1675187969420828672" }
],
"maxItems": 2,
"maxDepth": 1,
"requestDelayMs": 250
}

Input parameters

startUrls

Required array of public x.com or twitter.com post URLs. URL fragments and alternate Twitter hostnames are normalized. Profile URLs, searches, lists, and non-X URLs are rejected.

maxItems

Maximum unique reply records across all supplied URLs. Default: 50. Range: 1500.

maxDepth

Number of parent-child levels to follow from every supplied post. Default: 2. Range: 15.

Depth 1 returns only replies whose parent is the supplied post. Higher values request surfaced child pages and can produce nested records.

requestDelayMs

Delay between public X page requests. Default: 250 milliseconds. Range: 010000. Increase it when running a larger nested crawl repeatedly.

The Actor does not enable a paid proxy fallback. Direct public requests currently provide the product data at lower cost.

Output example

A current reply record has this shape:

{
"recordType": "reply",
"postId": "1675189603911827457",
"postUrl": "https://x.com/losxbt/status/1675189603911827457",
"sourcePostId": "1675187969420828672",
"sourcePostUrl": "https://x.com/elonmusk/status/1675187969420828672",
"conversationId": "1675187969420828672",
"parentPostId": "1675187969420828672",
"depth": 1,
"isDirectReply": true,
"text": "@elonmusk Bro wtf is this 💀 https://t.co/UNmXAKbmst",
"createdAt": "2023-07-01T17:08:19.000Z",
"authorUsername": "losxbt",
"authorProfileUrl": "https://x.com/losxbt",
"replyCount": 216,
"likeCount": 96265,
"viewCount": 5387003,
"mediaUrls": ["https://pbs.twimg.com/media/Fz94ENmWIAAt3Z9.jpg"],
"mediaTypes": ["photo"],
"scrapedAt": "2026-08-30T20:10:00.000Z"
}

Engagement values can change after extraction. Use scrapedAt to identify the observation time.

How much does it cost to extract X post replies?

Pricing uses one start event plus one item event per reply saved to the default dataset. The focal source post is not charged as an item.

Apify shows the applicable price before every run. The launch pricing contract is:

  • Start: $0.001 per run.
  • BRONZE item: $0.00024 per delivered reply.
  • Lower per-item tiers apply on SILVER through DIAMOND plans.

Example Actor charges at the BRONZE rate are approximately:

Delivered repliesActor charge
1$0.00124
10$0.0034
100$0.025

Apify displays the applicable plan tier and maximum charge controls. These prices were checked against measured current-build runtime and exact X reply competitors.

Direct replies and nested thread mapping

Use maxDepth: 1 when the job is a flat engagement export around one source post.

Use a higher depth when you need:

  • parent-child edges for a conversation graph;
  • direct versus nested classification;
  • branch-level author or engagement analysis;
  • downstream thread reconstruction.

Sort by depth and join parentPostId to postId to rebuild the surfaced tree. Keep sourcePostId in the join key when one dataset contains several source URLs.

Integrations and workflow ideas

  • Send completed datasets to Google Sheets with an Apify integration.
  • Trigger a webhook and load records into BigQuery or Snowflake.
  • Schedule recurring runs and compare reply IDs in your own storage.
  • Build a parent-child graph in NetworkX, Neo4j, or a BI tool.
  • Run language or sentiment classification downstream.
  • Join reply authors with another authorized public-profile dataset.

The Actor returns current observations. It does not maintain a change-history database or send alerts by itself.

API usage

Replace <APIFY_TOKEN> with your Apify API token.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~x-post-replies-conversation-threads/runs?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"startUrls":[{"url":"https://x.com/elonmusk/status/1675187969420828672"}],"maxItems":6,"maxDepth":2}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/x-post-replies-conversation-threads').call({
startUrls: [{ url: 'https://x.com/elonmusk/status/1675187969420828672' }],
maxItems: 6,
maxDepth: 2,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("automation-lab/x-post-replies-conversation-threads").call(
run_input={
"startUrls": [{"url": "https://x.com/elonmusk/status/1675187969420828672"}],
"maxItems": 6,
"maxDepth": 2,
}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

For synchronous API calls, use the Actor run-sync endpoint and keep the input small enough for the client timeout.

Use with Apify MCP

Add the Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/x-post-replies-conversation-threads"

Claude Desktop, Cursor, and VS Code MCP setup

Use this equivalent JSON configuration in Claude Desktop, Cursor, or VS Code:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/x-post-replies-conversation-threads"
}
}
}

Example prompts:

  • “Run the X replies Actor on this public post and return direct replies only.”
  • “Export up to 50 surfaced replies with depth 3, then group authors by branch.”
  • “Map each reply ID to its parent post ID from this run.”

Coverage and limitations

X controls which replies are visible to logged-out visitors. The Actor exports that ranked, surfaced subset; it does not promise every reply from conversations with hundreds or thousands of responses.

Other limitations:

  • Private, deleted, suspended, age-restricted, or login-only posts are unsupported.
  • Reply ranking and visible engagement can change between runs.
  • A page can expose fewer records than maxItems.
  • The Actor does not search by keyword, scrape profiles, or authenticate to X.
  • The Actor does not bypass access controls or CAPTCHA challenges.
  • Changes to X's public Relay data shape can temporarily cause explicit run failures.
  • Deep crawls make more source requests and take longer than direct-only runs.

A successful run with fewer rows than requested means X exhausted the surfaced branch, not that the Actor silently invented pagination.

Reliability tips

  • Start with depth 1 or 2 and a small item cap.
  • Keep the default request delay for recurring jobs.
  • Increase requestDelayMs if X responds with temporary rate limits.
  • Use multiple runs rather than one unbounded input batch.
  • Inspect the failed URL in logs when a post was deleted or made private.
  • Store postId and scrapedAt for reliable downstream deduplication.

Transient network, HTTP 429, and temporary 5xx failures receive a bounded retry. Stable invalid-input and unavailable-page failures do not loop indefinitely.

Troubleshooting

The run returned fewer replies than maxItems

maxItems is a cap, not a promise. X may surface only a small ranked set for that post or branch. Increase depth only when nested replies are useful; it does not create unavailable rows.

The run says the page has no public conversation data

Confirm that the URL opens publicly while logged out, contains /status/<numeric-id>, and is not deleted, private, suspended, or age-restricted. Retry later only when the page is temporarily unavailable.

A URL is rejected before extraction

Use a complete URL such as https://x.com/username/status/1234567890. Search URLs, profile URLs, and shortened links are intentionally rejected.

Engagement differs from a prior export

Counts are current source observations and can change. Compare records using postId and observation time using scrapedAt.

Responsible use and legality

Use this Actor only for public information you are authorized to collect and process.

You are responsible for:

  • complying with applicable laws and contractual obligations;
  • respecting privacy, data-protection, intellectual-property, and platform rules;
  • minimizing personal data collection;
  • securing exports and controlling retention;
  • avoiding harassment, surveillance, discrimination, spam, or harmful profiling.

The Actor does not authenticate as a user or access private posts. Public availability does not remove your responsibility to use the data lawfully.

These products solve different discovery jobs. Use this Actor when the starting point is a known post URL and reply relationships are the required output.

FAQ

Does it require an X account or cookies?

No. The Actor uses data X currently exposes to logged-out visitors.

Does it return every reply?

No. It returns the direct and nested replies surfaced on public logged-out pages. Large conversations are commonly partial.

Can it collect only direct replies?

Yes. Set maxDepth to 1.

Can it process several post URLs?

Yes. Add several entries to startUrls; maxItems applies across the full run.

Are nested relationships preserved?

Yes. Use parentPostId, depth, isDirectReply, and conversationId.

Are media files downloaded?

No. Public media URLs and types are included. The Actor does not download or store the media bytes.

Can I schedule monitoring?

You can schedule recurring Actor runs, but comparison, alerts, and historical retention belong in your downstream workflow.

Is the source post included as a charged dataset item?

No. The default dataset contains reply records. The source is referenced by sourcePostId and sourcePostUrl on every row.