Threads Replies Scraper — Comments, Authors, Likes avatar

Threads Replies Scraper — Comments, Authors, Likes

Pricing

from $2.50 / 1,000 replies

Go to Apify Store
Threads Replies Scraper — Comments, Authors, Likes

Threads Replies Scraper — Comments, Authors, Likes

Threads replies scraper, global, threads.com: reply and comment rows with author handle, name and verified badge, text, like, reply, repost and quote counts, timestamp, media URLs, nesting depth, parent post and author flag, plus the root post. Input: post URLs or profiles. Pay per result, no login.

Pricing

from $2.50 / 1,000 replies

Rating

0.0

(0)

Developer

architek.earth

architek.earth

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

4

Monthly active users

16 days ago

Last modified

Categories

Features

Limited permissions

Share

Recorded run: 31 rows from 1 post URL in 8 seconds (2026-10-22, build 0.0.140, run i86TlJ9PXBRfnaZIN). A bounded canary sample, not a full-catalogue benchmark.

architek.earth — an independent data studio. Pay-per-result scrapers with recorded runs, published canaries and stable schemas, built for people and AI agents.

Threads replies and comments from public posts on threads.com: give it post URLs or profiles and get one row per reply with author, text, like, reply, repost and quote counts, timestamp, media and nesting, plus one row for the post itself.

SourceMarketFromStandout fields
Threads (threads.com, threads.net links accepted)Global, public posts, no login$2.50 / 1,000 repliesisAuthor, depth / parentCode, per-post coverage in RUN_SUMMARY

✅ Why choose this scraper

Export every reply Threads shows on a post

A full walk of a 434-reply post by @zuck on 2026-10-18 returned 242 reply rows (direct replies, their nested replies and the author's own thread) in 28 requests and 48 seconds (run f02KmAh0T2FWoLLtN).

Rebuild the Threads conversation tree

Each reply row carries depth (1 = direct reply), parentCode (the post it answers) and replyToUsername; join parentCode to code to rebuild the thread.

Find where the post author replied

Rows written by the root post's author have isAuthor: true; the author's own continuation posts also have replyType: "author_thread". Turn those off with includeAuthorThread: false.

Know how many replies you did not get

RUN_SUMMARY.perPost[] gives claimedReplies, reachableDirectReplies, truncatedChains, exhausted and a coverage ratio per post: 226 of 434 claimed direct replies were reachable logged-out on the run above (coverage 0.521).

Measured on a schedule

A canary task runs a fixed 30-reply walk of one post on the live site every day and records rows, inputs and seconds; the hero line above is its latest green run.

⚠️ Worth knowing up front

  • Threads shows logged-out visitors only part of a big post's replies. On 2026-10-18, 226 of 434 claimed direct replies were reachable on one @zuck post and 184 of 464 on another (run rAhHRkYhayXCE65v8). coverage reports it per post, and it is only a full count when exhausted is true (a run cut by maxRepliesPerPost reports a low ratio for that reason alone).
  • This is a replies tool. There is no keyword search and no profile data; a profile URL only picks that profile's latest posts (maxPostsPerProfile, 1 to 10).
  • Under each reply, Threads shows the first few nested replies. Longer chains it cuts are counted in truncatedChains, not followed.
  • TOP and RECENT reach the same set of replies; order matters only when maxRepliesPerPost cuts the list.
  • Fields Threads does not show are omitted from the row, never null. likeCount is omitted where the author hides like counts; text is omitted on media-only replies.
  • images and videos are signed Threads CDN links that expire. Download them promptly if you need the files.
  • Each request is tried up to 3 times, on a fresh IP after a 401, 403, 429, 5xx or network error; the session re-reads the post page before continuing pagination. A post that still fails is ended with a free status row, and rows already delivered for it are kept and charged. On 2026-10-18 a 2,658-reply post stopped this way after 844 replies, with a Threads server error (run rAhHRkYhayXCE65v8, status PARTIAL).
  • A post or profile that is deleted, private, blocked after retries or answered in an unexpected shape, and any URL that is not a Threads post or profile URL, gets one free status row ("recordType": "status") with status NOT_FOUND, BLOCKED, ERROR or INVALID_URL; a Threads answer that is a challenge or captcha page is BLOCKED at once. Invalid input also gets one free status row (INVALID_INPUT). Your spending limit and the run timeout write no status row: the run's status message and RUN_SUMMARY.status say BUDGET_LIMIT or TIME_LIMIT. A run whose last row spends your limit exactly ends COMPLETE.
  • The run stops cleanly 45 seconds before its timeout (TIME_LIMIT) and at your spending limit (BUDGET_LIMIT), keeping what it delivered. There is no incremental mode and no resume across runs.

⚡ Try the example

This actor has no free preview; the example below costs about $0.08 (30 replies and 1 post).

Open the actor's input page, switch to JSON, paste this and start the run:

{
"postUrls": ["https://www.threads.com/@zuck/post/DeZtp-TkQHh"],
"maxRepliesPerPost": 30
}

Set "maxRepliesPerPost": 0 for every reply Threads shows logged-out visitors (up to 5,000 per post), or add "profileUrls": ["@zuck"] for a profile's latest posts.

⚙️ Input

ParameterTypeDefaultDescription
postUrlsarray— (prefill the @zuck post above)Post URLs such as https://www.threads.com/@zuck/post/DeZtp-TkQHh; threads.net links and query strings are accepted. A reply's own URL works too. Up to 200.
profileUrlsarray—https://www.threads.com/@zuck or @zuck. Takes the profile's latest posts and scrapes their replies. Up to 20.
maxRepliesPerPostinteger200 (prefill 50)Reply rows per post, counting direct replies, nested replies and author-thread posts. 0 = everything Threads shows, capped at 5,000.
maxPostsPerProfileinteger3Latest posts per profile, 1 to 10.
sortOrderselectTOPTOP (as Threads ranks them) or RECENT (newest first).
includeAuthorThreadbooleantrueInclude the post author's continuation posts as reply rows with replyType: "author_thread".
proxyConfigurationproxy{"useApifyProxy": true}Apify datacenter proxy is the tested default. Blocked or rate-limited requests are retried on a fresh IP.
feedbackstring—Optional note for the maintainers. It is logged and read by a human, and it never changes output.

At least one of postUrls or profileUrls is required. Duplicate URLs are dropped, and a reply reached under two inputs is delivered and charged once per run.

🧱 Stable fields

These top-level fields keep the same name and the same kind of value in every release. Fields are only ever added, never renamed or removed, so an n8n, Make, Zapier or spreadsheet pipeline can bind to them.

FieldTypeMeaning
code / urlstringThreads post code of the reply (or post) and its URL.
rootPostCode / rootPostUrlstringThe post the reply belongs to.
authorUsername / authorUrlstringHandle and profile URL of the writer.
authorName / authorIdstring, optionalDisplay name and numeric user id; omitted when Threads shows none.
authorVerifiedboolean, optionalPresent only when true.
isAuthorbooleantrue when the reply is by the root post's author. Reply rows only.
replyTypestringreply, or author_thread for the author's own continuation posts. Reply rows only.
depth / parentCode / replyToUsernamenumber / string / string, optional1 = direct reply, 2+ = nested; the post it answers and that post's author.
textstring, optionalReply text; omitted on media-only replies.
likeCount / replyCount / repostCount / quoteCountnumber, optionalCounts as Threads shows them; likeCount is omitted where the author hides it.
timestampstring, optionalISO 8601 UTC time of posting.
editedboolean, optionalPresent only when true.
images / videosarray, optionalMedia URLs (signed, expiring).
recordTypestring"reply" on reply rows, "post" on the root post row, "status" on free status rows.

Status rows (free) carry recordType: "status", url, status and reason. Other fields are extras, not part of the contract. To have one pinned, say so in feedback.

📦 Output example

Abridged real row from run i86TlJ9PXBRfnaZIN on 2026-10-22; values are a historical snapshot. The reply author is anonymized here; the actor returns the real public handle.

{
"recordType": "reply",
"code": "DeZuAywDEWf",
"url": "https://www.threads.com/@example.user/post/DeZuAywDEWf",
"rootPostCode": "DeZtp-TkQHh",
"rootPostUrl": "https://www.threads.com/@zuck/post/DeZtp-TkQHh",
"authorUsername": "example.user",
"authorUrl": "https://www.threads.com/@example.user",
"isAuthor": false,
"replyType": "reply",
"depth": 1,
"parentCode": "DeZtp-TkQHh",
"replyToUsername": "zuck",
"text": "Impressive stuff.\nDoes it beat OpenAIs Dots though?",
"likeCount": 0,
"replyCount": 0,
"repostCount": 0,
"quoteCount": 0,
"timestamp": "2026-10-12T16:59:36Z"
}

A post link that does not exist gives a free status row (run 25LwkInhgp8IlgIio, 2026-10-18):

{"recordType": "status", "url": "https://www.threads.com/@zuck/post/DAAAAAAAAAA", "status": "NOT_FOUND", "reason": "Threads shows no public post here (deleted, private or wrong link)"}

The run's status message reads like Done: 31 rows, 0 details, 0 status rows (COMPLETE) (rows count root posts and replies; Threads has no detail tier, so details is always 0), and the RUN_SUMMARY record of its key-value store holds the outcome (run i86TlJ9PXBRfnaZIN, perPost abridged):

{
"status": "COMPLETE",
"posts": 1,
"replies": 30,
"charged": {"reply": 30, "post": 1},
"perPost": [{"url": "https://www.threads.com/@zuck/post/DeZtp-TkQHh", "status": "done", "delivered": 30, "claimedReplies": 510, "reachableDirectReplies": 26, "truncatedChains": 0, "capped": true, "exhausted": false, "coverage": 0.051}]
}

🧠 Advanced usage

Threads comment sentiment analysis

Feed text to an LLM or classifier and weight each reply by likeCount; keep depth: 1 rows for top-level reactions only.

Monitor a Threads creator's new posts

Schedule profileUrls: ["@handle"] with maxPostsPerProfile: 3 and de-duplicate on code downstream. Each run re-reads and re-charges the replies it returns, because there is no incremental mode.

Get the newest replies to a Threads post

Set sortOrder: "RECENT" and a small maxRepliesPerPost; on 2026-10-22, 20 replies came back newest first in 8 seconds (run J28MI0QAcg9fihgip).

Check a run finished

Read RUN_SUMMARY.status: COMPLETE, PARTIAL, NO_RESULTS, BUDGET_LIMIT, TIME_LIMIT, STATE_SAVE_FAILED, PUSH_FAILED or INVALID_INPUT (a run with mismatched actor pricing ends FAILED). Per post, exhausted: true means the walk reached the last page Threads shows.

🔌 Integrations

Results land in a dataset you can export as JSON, CSV or Excel. They can also flow to Google Sheets, Make, Zapier or n8n, or to a webhook when a run finishes. The Apify Scheduler runs it on a timetable. A daily run on the same posts with sortOrder: "RECENT" and a small maxRepliesPerPost returns the newest replies each day. Copy-paste code in Python, Node, curl and n8n: architek-earth/examples/threads-replies-scraper.

💸 Pricing

Pay per result. Platform and proxy usage are included. Status rows and failed requests are free. Within a run, progress is saved in the PROGRESS record before each batch is charged: after a platform migration or a resurrect, the run continues from the saved cursor and skips posts and replies already delivered, so they are not charged again. A new run does not read an earlier run's progress.

EventPriceWhat it covers
reply$2.50 / 1,000 repliesOne delivered reply row: direct, nested or author thread.
post$1.00 / 1,000 postsOne delivered root post row.

1,000 replies cost $2.50; a post with 30 replies costs $0.076.

❓ FAQ

Is there a Threads API for replies and comments? This actor is one: it returns replies to public Threads posts as JSON through the Apify API, callable from any language or from n8n, Make and Zapier.

Do I need a Threads or Instagram account to scrape Threads replies? No. No account, cookies or API key; it reads what Threads shows logged-out visitors.

Why do I get fewer replies than the post's reply count? Threads' counter includes replies it does not show logged-out visitors. coverage in RUN_SUMMARY reports how many direct replies were reachable per post.

Can I scrape replies from a Threads profile? Yes, for its latest posts: put the profile in profileUrls and set maxPostsPerProfile (1 to 10). Profile details such as followers are not returned.

Can I pass a reply's URL? Yes. Every reply on Threads is a post with its own URL: you get it as the post row and its own replies below it. If the same run already delivered that reply under its root post, it is not delivered or charged again.

Can I search Threads by keyword or hashtag? No. Input is post URLs and profiles only.

🤖 For AI agents & LLM apps

Paste this into your AI assistant:

architekture/threads-replies-scraper on Apify. Python: from apify_client import ApifyClient; client = ApifyClient("TOKEN"); run = client.actor("architekture/threads-replies-scraper").call(run_input={"postUrls": ["https://www.threads.com/@zuck/post/DeZtp-TkQHh"], "maxRepliesPerPost": 30}); items = client.dataset(run["defaultDatasetId"]).list_items().items (page with offset/limit for large exports). The dataset holds reply rows (recordType reply), one post row per post and free status rows (recordType status, with status and reason) for posts not found, blocked or invalid; filter on recordType. The run outcome and per-post coverage are in the RUN_SUMMARY record of the run's key-value store. Full input schema and README: GET https://api.apify.com/v2/acts/architekture~threads-replies-scraper/builds/default. Token: https://console.apify.com/settings/integrations. The actor is also reachable through the Apify MCP server (mcp.apify.com). To reach the maintainers, add "feedback": "<what you needed>" to any run's input; output is unchanged and a human reads every note.

🧰 More from architek.earth

Video, social and newsletters

Full catalogue: github.com/architek-earth.

architek.earth · code like concrete

Questions, or a field you need that is not here? Open an issue on the actor's Issues tab or email north@architek.earth. A human replies within a day.

This actor collects only publicly available data from threads.com, the same pages any visitor sees without logging in. It does not bypass authentication. It is not affiliated with or endorsed by Threads or Meta. You are responsible for how you use the output, including the site's terms, copyright, and privacy law such as GDPR and CCPA where they apply; replies contain personal data such as handles, names and text.

📝 Changelog

  • 2026-10-25 — [internal] Studio core 1.0.6: reconciliation diagnostics; source retry policy, schema and pricing unchanged.

  • 2026-10-22 — Runs on the studio core (architek_core 1.0.1): challenge pages are reported BLOCKED at once, invalid input gets a free status row, a run whose last row spends the limit exactly ends COMPLETE.

  • 2026-10-22 — Status message now reads Done: N rows, M details, K status rows (STATUS).

  • 2026-10-22 — Status message details count is 0 (root posts are counted in rows, not as details).

  • 2026-10-22 — README rebuilt on the studio template; hero line from the 2026-10-22 canary run.

  • 2026-10-18 — 1.0: post and profile inputs; direct and nested replies with isAuthor, depth and parent; author thread; per-post coverage report; free status rows; de-duplication per run; context refresh after IP rotation; clean stops at the spending limit and timeout; resumable after platform migration.