Threads Replies Scraper API avatar

Threads Replies Scraper API

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Threads Replies Scraper API

Threads Replies Scraper API

Fetch replies from Threads posts. Get reply text, engagement metrics, author info, and media details. Requires a Threads Session ID.

Pricing

from $1.00 / 1,000 results

Rating

5.0

(1)

Developer

Rush

Rush

Maintained by Community

Actor stats

3

Bookmarked

170

Total users

44

Monthly active users

6 days ago

Last modified

Share

Collect the replies under a Threads post — with each reply's author, engagement, media and place in the conversation.

What does Threads Replies Scraper API do?

Give it the links to up to 50 posts and your Threads Session ID (how to get one), and it returns a row for every reply it collects, ready to open in a spreadsheet or feed into your own tools.

What can you use it for?

  • Read what people actually said under a post, instead of only how many replied
  • Follow how a discussion developed, level by level, using each row's place in the conversation
  • Put the replies to several posts side by side in one table
  • Keep a copy of a conversation as it stood, before it changes

Features

  • Up to 50 posts per run. Paste post links one per line; share links and short links work too. A link that is not a post is named in the log and skipped, and a post listed twice is collected once.
  • Nested replies, level by level. Turn on Include Nested Replies to also collect replies to replies. Every row says how deep it sits, and nested rows name the reply they answer.
  • Top or Recent order. Collect replies in the order Threads ranks them, or newest first.
  • A limit, or everything Threads serves. Set Max Replies Per Post, or leave it at 0 to collect as many replies as Threads serves.
  • Results as they arrive. Rows are saved while the run works, so you can open the dataset before it finishes.
  • A run summary you can automate on. Each run says how it ended, whether anything is missing, and what stopped it when it did not finish.
  • Resurrect continues a stopped run. A run that stops early picks up from its last saved point instead of starting over. Two cases need a different step: a Session ID Threads no longer accepts, and a run that reached the maximum cost set for it; the FAQ says what to do for each.

What you get

One row for the item you submitted, then one row for each reply collected under it. If the submitted item cannot be read or saved, its row is missing and the log says so. Every row carries the same columns:

  • Content — full text, its link, shortcode, hashtags, mentions, every link the row carries (the ones Threads recognised and linked, the ones written plainly in the text, and the destination behind an attached link card), the title of that card, the accounts Threads itself recognised in the text (with their account identifiers), and the language Threads read the text in
  • Author — username, display name, user ID, profile link, profile picture, verified badge, and whether the account is private
  • Engagement — likes, replies, reposts, quotes, and shares where Threads reports them
  • Media — type (text, photo, video, carousel or gif; blank when Threads uses a format this Actor does not recognise), a GIF flag, whether the author hid the media behind a spoiler cover, the main media link, every media link (in slide order for a carousel), pixel size, whether Threads reports audio, and the image description Threads provides where there is one. Photo, video and profile picture links are time-limited by Threads, so download anything you want to keep soon after the run; a GIF's link points to the service that hosts the GIF
  • Timing — when it was posted (as a date and as seconds, so you can sort or join without parsing), when it was collected, and whether the text has been edited
  • Conversation — who it is replying to, how deep it sits in the thread, whether the author of the thread's original post liked it, whether the author of the post above pinned it, who the author allows to reply, and whether the row quotes another post along with a link to the post it quotes. Nested rows also name the reply they answer

Replies also carry their position in the results. The submitted item is marked item_type: "post" and everything else item_type: "reply", so you can filter by type.

Because the two row types describe different things, some columns belong to one or the other: postId and postUrl are filled on the post row, replyId and replyUrl on reply rows, and postCode is always the shortcode of whatever that row itself is.

sourceUrl names the post you submitted, written in its standard form — https://www.threads.com/@handle/post/SHORTCODE. A link that carries tracking parameters on the end, or that uses the other Threads address, comes back tidied to that form, so join your own list on the post's handle and shortcode rather than on the exact text you pasted. It is also what the run log names. The author columns describe whoever actually wrote the item, which is not always the handle in the link: Threads finds a post by its shortcode, so a link built with an old or different handle still works and still reaches the right post. Where the two differ, postUrl gives the post's own address.

Several columns carry what Threads itself states about a row, and stay empty when it states nothing rather than being filled in with a guess. language is given for some posts and not others, so an empty value means Threads named no language — not that the text has none. hasAudio, authorIsPrivate, isPinnedByAuthor and isSpoiler work the same way. A detail Threads sends in a form this Actor does not recognise is left empty too, and the run's log says so; isVerified, isEdited and isLikedByAuthor read false instead. mentionedAccounts lists the handles Threads recognised and links, each with its account identifier, while mentions lists every @handle written in the text including any Threads did not link — so the two are read together rather than one instead of the other. authorIsPrivate is true when Threads marks the author's account as private. Threads shows a private account's posts and replies only to the followers it approves, so take care before sharing those rows. quotedPostUrl is empty when a row quotes nothing, and also when the quoted post is no longer available, in which case isQuotePost is still true.

How to Use

  1. Get your Session ID — the steps are just below.
  2. Paste your post links into Post URLs, one per line, and your Session ID into Session ID.
  3. If you like, set Max Replies Per Post, Sort Replies By and Include Nested Replies.
  4. Click Start. Rows appear in the run's dataset as they are collected, and the last line of the log says how the run ended.
  5. Open the results from the run's Output tab, or export the dataset in the format you need.

How to get your Session ID

This Actor requires a Threads Session ID for authentication. Here's how to get it:

Option 1: Browser Developer Tools

  1. Open threads.com in your browser and log in
  2. Press F12 to open Developer Tools
  3. Go to Application → Cookies → https://www.threads.com
  4. Find the cookie named sessionid and copy its value
  5. Paste it into the Session ID field in the Actor input

You can also use a browser extension like Cookie-Editor to quickly view and copy cookies. Simply install the extension, visit threads.com, and search for the sessionid cookie.

Disclaimer: Cookie-Editor is a third-party extension not affiliated with this Actor. As with any browser extension that accesses cookie data, please review its permissions and use at your own discretion.

Important notes

  • Use a secondary account. Automated access may cause Threads to flag your account or temporarily restrict it. We strongly recommend using a secondary account rather than your primary one.
  • Session IDs have no guaranteed lifetime. Logging out of the browser you copied one from ends it, and Threads can end one at any time. If a run says Threads did not accept your Session ID, copy a fresh one.
  • The reply count on a post is not a target. It counts direct replies only. On a busy post, Threads lists only part of the replies it counts — in Top order and in Recent order alike — and a run ends where Threads' own list ends. When a post is collected in full, Max Replies did not stop it, and Threads' list ends before the number the post shows, the post's last line in the log says how many direct replies Threads listed against that number. A run can also save more rows than the number, when nested replies come along.
  • Busy accounts. Threads limits how much can be read in a short period, so a very large job on an account that is already busy may be cut short.

Input example

{
"postUrls": [
"https://www.threads.com/@zuck/post/DTa3-B1EbTp"
],
"sessionId": "your-session-id-here",
"maxReplies": 0,
"sortOrder": "top",
"includeChildReplies": false
}
FieldTypeDescription
postUrlsArrayThreads post links to collect replies from, one link per entry; a run collects up to 50 posts, and a longer list stops the run as it starts. threads.net links work too, and so do share links (threads.com/share/…) and short links (threads.com/t/…): each is opened to find the post it leads to, and counts as one of the 50 posts
sessionIdStringYour Threads sessionid cookie
maxRepliesNumberMax replies per post (0 = no limit, default: 0). Every reply counts toward it, including nested replies that appear with includeChildReplies off; the row for the item you submitted does not count toward it
sortOrderStringReply order: "top" (Threads' own ranking, default) or "recent" (newest first)
includeChildRepliesBooleanAlso collect nested replies (replies to replies). Each nested reply carries a depth (2+), and names the reply it answers in parentReplyId wherever Threads identifies it. With it off, some nested replies can still appear — the answers Threads shows directly under a reply in the list — labelled the same way. Default: false

Output example

Long values are shortened with ... in these examples; the dataset holds every value in full. The reply comes from a different submitted post than the post row, which is why its sourceUrl differs; its author, text and identifiers are placeholders.

The item you submitted (item_type: "post"):

{
"item_type": "post",
"sourceUrl": "https://www.threads.com/@mosseri/post/DalA5HOFvaC",
"postId": "3937557373968119426",
"replyId": null,
"postCode": "DalA5HOFvaC",
"postUrl": "https://www.threads.com/@mosseri/post/DalA5HOFvaC",
"replyUrl": null,
"text": "Excited about this launch. I've been really impressed with how quickly t...",
"hashtags": [],
"mentions": [],
"mentionedAccounts": [],
"urls": [],
"linkTitle": null,
"language": null,
"username": "mosseri",
"userId": "63482099442",
"profileUrl": "https://www.threads.com/@mosseri",
"profilePicUrl": "https://scontent.cdninstagram.com/...",
"isVerified": true,
"authorIsPrivate": false,
"displayName": "Adam Mosseri",
"timestamp": "2026-07-09T16:10:38.000Z",
"timestampUnix": 1783613438,
"isEdited": false,
"replyControl": "everyone",
"isQuotePost": true,
"quotedPostUrl": "https://www.threads.com/@zuck/post/DakyAavlKLZ",
"likeCount": 223,
"replyCount": 143,
"repostCount": 31,
"quoteCount": 0,
"shareCount": 12,
"isLikedByAuthor": false,
"isPinnedByAuthor": false,
"replyToUsername": null,
"depth": 0,
"parentReplyId": null,
"mediaType": "text",
"isGif": false,
"isSpoiler": false,
"mediaUrl": null,
"mediaUrls": [],
"mediaWidth": null,
"mediaHeight": null,
"hasAudio": null,
"accessibilityCaption": null,
"index": null,
"scrapedAt": "2026-08-30T06:57:42.089Z"
}

A reply (item_type: "reply"):

{
"item_type": "reply",
"sourceUrl": "https://www.threads.com/@mosseri/post/DZ5UXU0G-DX",
"postId": null,
"replyId": "1234567890123456789",
"postCode": "REPLYCODE01",
"postUrl": null,
"replyUrl": "https://www.threads.com/@example_user/post/REPLYCODE01",
"text": "@meta.ai 可以幫我把這段公告翻成中文嗎?",
"hashtags": [],
"mentions": [
"@meta.ai"
],
"mentionedAccounts": [
{
"username": "meta.ai",
"userId": "27463547647"
}
],
"urls": [],
"linkTitle": null,
"language": "zh_TW",
"username": "example_user",
"userId": "1234567890",
"profileUrl": "https://www.threads.com/@example_user",
"profilePicUrl": "https://scontent.cdninstagram.com/...",
"isVerified": true,
"authorIsPrivate": false,
"displayName": "Example User",
"timestamp": "2026-06-22T17:41:49.000Z",
"timestampUnix": 1782150109,
"isEdited": false,
"replyControl": "everyone",
"isQuotePost": false,
"quotedPostUrl": null,
"likeCount": 0,
"replyCount": 1,
"repostCount": 0,
"quoteCount": 0,
"shareCount": null,
"isLikedByAuthor": false,
"isPinnedByAuthor": false,
"replyToUsername": "mosseri",
"depth": 1,
"parentReplyId": null,
"mediaType": "text",
"isGif": false,
"isSpoiler": false,
"mediaUrl": null,
"mediaUrls": [],
"mediaWidth": null,
"mediaHeight": null,
"hasAudio": null,
"accessibilityCaption": null,
"index": 14,
"scrapedAt": "2026-08-30T07:04:28.469Z"
}

After a run

  • Results appear as they are collected. You do not have to wait for the run to finish before opening the dataset, and whatever has been collected is kept even if a run is interrupted.
  • Check the last line of the log. It says how the run ended. A run that finishes, or stops early on its own, says how many replies were collected and how many rows were saved; a run that fails, or that is stopped with a graceful abort (in the API, gracefully=true), says why, and when it had saved rows first, its run summary (below) has the counts. An abort that is not graceful — the API's default — ends the run at once: the rows saved so far are kept, but there is no closing line and no new run summary, and the same goes for a run its timeout cuts off before it can stand down on its own. If the run stopped early, or if any post could not be collected in full, could not be opened, was not found when read again or was not read, it says so there instead of reporting the job complete — so you know when there is more to collect.
  • Stopped early? Open that run and choose Resurrect to continue where it stopped: it picks up from its last saved point, and a post the run had already finished short is not asked for again. If this Actor has been updated since the run started, choose the latest build when you resurrect. Starting a new run begins from the beginning and collects the replies already saved a second time. There are two exceptions. One is a Session ID Threads no longer accepts, below. The other is a run that reached the maximum cost set for it: start a new run with a higher maximum cost and only the posts that run did not finish (the log marks each finished post "done"). A plain Resurrect keeps that maximum cost, but through the Apify API a Resurrect can be given a higher one, and then it continues from its last saved point instead.
  • Finished, but a post could not be collected in full? Resurrect does not continue a run that finished: it finds the job done and collects nothing more. To try for the rest of that post, start a new run with it later, as the last line says; the new run collects that post from the start, so the replies already saved for it are collected again.
  • Automating? Read the run summary instead. Each run saves a short summary you can open from the Run Summary link on the run's Output tab: how many posts you submitted (each post counted once, plus any entry that is not a post link), how many were collected, how many replies and rows were saved, and whether anything is missing. It says how the run ended in a form a schedule or a spreadsheet sync can act on. When a run does not finish normally the summary also carries a short, stable name for what stopped it, so an automation can tell the endings apart without reading the log. A run cut off before it could write its summary has none; its dataset and log still show what was saved. If the summary cannot be saved at the end of a run, the run's last line says so, and the dataset still holds every saved row. A run that continues from its saved progress — one you resurrected, or one the platform moved to another server — keeps its summary current while it runs: stopped early, with no name for an ending yet, counting what was saved at its last saved point — so if it is cut off, the summary still shows those counts.

Frequently Asked Questions

Why does this Actor need a Session ID?

This Actor reads replies as a signed-in viewer, which is why it needs your Session ID. It will not start without one. If you would rather not use one, Threads Replies Scraper needs no Session ID and collects the replies Threads shows to visitors who are not signed in.

Is it safe to enter my Session ID?

It is treated as a secret — stored encrypted as part of your run's private input, used only to make authenticated requests to Threads, and never written to logs or shared with anyone else. It still grants access to whichever account it came from, which is why a secondary account is the safer one to use.

I'm seeing authentication errors — what should I do?

If the run says Threads did not accept, or stopped accepting, your Session ID, copy a fresh one by following How to get your Session ID. Replies already collected stay in that run's results, so start a new run with only the posts that run did not finish — the log marks each finished post "done" — and the finished posts are not collected a second time. A post the run was part-way through is collected again from its start, so its own row and its earlier replies appear in both runs; match them on sourceUrl and replyId. (Resurrect would present the same Session ID again.) If the run says Threads is asking the account to confirm something, a fresh Session ID alone will not help: open threads.com in a browser while signed in to that account, do what it asks, then copy a fresh Session ID and start the new run the same way. If the run instead says Threads would not let it sign in, follow the steps in that message.

What does item_type mean in the output?

Each link you submit produces one row marked "item_type": "post" — the item you asked for — and one row for each reply collected under it, marked "item_type": "reply". Filtering on that column separates the two. If the submitted item itself cannot be read, its post row is missing and the log names the link.

What is the difference between "Top" and "Recent" sort?

"Top" lists replies in the order Threads ranks them — the view Threads shows by default. "Recent" lists the newest replies first.

The two views can return a different set of replies, not only a different order. Nested replies may not follow date order, so for a strict date order, sort the saved rows by timestamp.

Can I paste the link to a reply instead of a post?

Yes. On Threads a reply has its own link in the same shape as a post link, and either one works here: you get the replies underneath whatever you paste, not the wider thread it belongs to.

The item_type: "post" row is always the item you asked for. When that item is itself a reply it still carries depth: 0, and replyToUsername tells you who it was answering.

Can I scrape replies from multiple posts at once?

Yes. A run collects up to 50 posts; a post listed twice is collected once. Results are kept separate per post, and every result is labeled with the sourceUrl that produced it — the standard https://www.threads.com/@user/post/CODE form of the link you submitted — making it easy to filter and compare by post. If you submit both a post and one of its replies, a reply that belongs to both can be listed under each link, with its depth counted from that link, so use sourceUrl together with replyId as a row's key.

Can I also get replies to replies (nested threads)?

Yes. Turn on Include Nested Replies to follow each reply thread and collect the nested replies beneath it, around five levels below the item you submitted — a conversation that runs on inside one thread can go deeper, and each row's depth tells you exactly where it sits. Each row includes a depth (0 = the item you submitted, 1 = a direct reply to it, 2+ = nested). Rows at depth 2 and below also name the reply they answer in parentReplyId; a direct reply answers the item_type: "post" row itself, so its parentReplyId is empty — as it is when Threads does not identify the parent. Select direct replies with depth = 1 rather than by an empty parent. Together they let you reconstruct the conversation tree.

Include Nested Replies asks Threads for each reply conversation separately, so it makes more requests on your account. Leave it off when the direct replies are all you need.

Some nested replies arrive even with the option off, because Threads writes part of a conversation into the reply feed itself; how many depends entirely on the post. They are labelled with their real depth and parent rather than being passed off as direct replies, and they count toward Max Replies Per Post like any other reply. Turning the option on is what makes them deliberate rather than incidental.

Integrations

Connect Threads Replies Scraper API with other apps and services using Apify integrations. Export data to Google Sheets, Slack, Zapier, Make, and many more.

More scrapers

  • Threads Replies Scraper — collects replies without a Session ID, from what Threads shows to visitors who are not signed in.

Explore more social media and web scrapers on our Apify profile.

Disclaimer

This Actor is intended for learning, research, and personal use. You are responsible for using it responsibly and ethically, and for ensuring your use complies with the laws and regulations that apply to you.

Threads may update its platform at any time, which could temporarily affect this Actor's functionality. While we actively maintain compatibility, occasional disruptions are possible.

Using a Session ID involves providing authentication credentials to the Actor. We strongly recommend using a secondary account, as automated access may result in account restrictions or temporary bans. You are solely responsible for how you use this tool and any consequences that may arise from its use.


Threads replies scraper, Threads comments scraper, Threads reply API, Threads reply extractor, Threads post replies, social media scraper, Threads analytics, Threads engagement analysis, Threads reply tracker, Apify actor, Claude Code, OpenClaw, Gemini, Antigravity, Codex, ChatGPT