Threads Replies Scraper — Comments, Authors, Likes
Pricing
from $2.50 / 1,000 replies
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
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
4
Monthly active users
16 days ago
Last modified
Categories
Features
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.
| Source | Market | From | Standout fields |
|---|---|---|---|
| Threads (threads.com, threads.net links accepted) | Global, public posts, no login | $2.50 / 1,000 replies | isAuthor, 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).coveragereports it per post, and it is only a full count whenexhaustedistrue(a run cut bymaxRepliesPerPostreports 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. TOPandRECENTreach the same set of replies; order matters only whenmaxRepliesPerPostcuts the list.- Fields Threads does not show are omitted from the row, never
null.likeCountis omitted where the author hides like counts;textis omitted on media-only replies. imagesandvideosare 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, statusPARTIAL). - 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") withstatusNOT_FOUND,BLOCKED,ERRORorINVALID_URL; a Threads answer that is a challenge or captcha page isBLOCKEDat 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 andRUN_SUMMARY.statussayBUDGET_LIMITorTIME_LIMIT. A run whose last row spends your limit exactly endsCOMPLETE. - 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
| Parameter | Type | Default | Description |
|---|---|---|---|
postUrls | array | — (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. |
profileUrls | array | — | https://www.threads.com/@zuck or @zuck. Takes the profile's latest posts and scrapes their replies. Up to 20. |
maxRepliesPerPost | integer | 200 (prefill 50) | Reply rows per post, counting direct replies, nested replies and author-thread posts. 0 = everything Threads shows, capped at 5,000. |
maxPostsPerProfile | integer | 3 | Latest posts per profile, 1 to 10. |
sortOrder | select | TOP | TOP (as Threads ranks them) or RECENT (newest first). |
includeAuthorThread | boolean | true | Include the post author's continuation posts as reply rows with replyType: "author_thread". |
proxyConfiguration | proxy | {"useApifyProxy": true} | Apify datacenter proxy is the tested default. Blocked or rate-limited requests are retried on a fresh IP. |
feedback | string | — | 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.
| Field | Type | Meaning |
|---|---|---|
code / url | string | Threads post code of the reply (or post) and its URL. |
rootPostCode / rootPostUrl | string | The post the reply belongs to. |
authorUsername / authorUrl | string | Handle and profile URL of the writer. |
authorName / authorId | string, optional | Display name and numeric user id; omitted when Threads shows none. |
authorVerified | boolean, optional | Present only when true. |
isAuthor | boolean | true when the reply is by the root post's author. Reply rows only. |
replyType | string | reply, or author_thread for the author's own continuation posts. Reply rows only. |
depth / parentCode / replyToUsername | number / string / string, optional | 1 = direct reply, 2+ = nested; the post it answers and that post's author. |
text | string, optional | Reply text; omitted on media-only replies. |
likeCount / replyCount / repostCount / quoteCount | number, optional | Counts as Threads shows them; likeCount is omitted where the author hides it. |
timestamp | string, optional | ISO 8601 UTC time of posting. |
edited | boolean, optional | Present only when true. |
images / videos | array, optional | Media URLs (signed, expiring). |
recordType | string | "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.
| Event | Price | What it covers |
|---|---|---|
reply | $2.50 / 1,000 replies | One delivered reply row: direct, nested or author thread. |
post | $1.00 / 1,000 posts | One 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
- Substack Scraper — posts, authors, likes, comments
- YouTube Transcript Scraper — transcripts, translations, timestamps
- Unified Video Transcript API — YouTube and TikTok transcripts in one batch
- Threads Replies Scraper — you are here
- Ad Intelligence Watchlist — new and changed Meta ads by advertiser
Full catalogue: github.com/architek-earth.
architek.earth · code like concrete
🙋 Support & legal
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
BLOCKEDat once, invalid input gets a free status row, a run whose last row spends the limit exactly endsCOMPLETE. -
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.