# Threads Replies Scraper — Conversations & Comments (`lergassy/threads-replies-scraper`) Actor

The replies side of Threads as rows: every reply an account wrote with the post it answered, every reply under a post URL, and reposts. Text, author, time, engagement, media, links and reply context on each row. No login, no browser.

- **URL**: https://apify.com/lergassy/threads-replies-scraper.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Social media, Agents, MCP servers
- **Features:** Limited permissions
- **Stats:** 88 total users, 29 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.40 / 1,000 posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**Threads Replies Scraper** covers the conversation side of Meta Threads: every reply an account wrote, each carrying the post it answered; every reply under a post URL you give it; and the posts an account reposted. Each row has text, author, time, likes, replies, reposts and quotes, images and videos, links, mentions and the reply context. No login, no cookies, no browser.

**$2 per 1,000 posts** on the Apify free plan — you pay for delivered rows, nothing else. Higher Apify plans pay less, down to $1.4.

![One run of Threads Replies Scraper: replies with their parent posts, authors and engagement.](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/threads-scraper/threads-scraper-output-table.png)

Paste usernames or post URLs, click Start, export as JSON, CSV or Excel — or call it from the API and from AI agents.

### Tested head-to-head — 26 September 2026

![Threads Replies Scraper tested against the six most-used Threads reply scrapers: 20 replies plus the post, 0% failed runs](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/benchmarks/threadsreplies-tested-2026-09-26.png)

The same request went to this Actor and to the six most-used Threads reply scrapers on the Apify Store, from an ordinary paying account: one post by @zuck, 20 replies.

| | This Actor | The six others |
|---|---|---|
| Replies returned (20 asked) | **20, plus the post itself** | 10–20; one packs everything into a single nested row |
| Failed runs, last 30 days (Apify Store stats) | **0%** | 0–20.8% — three of six above 10% |
| Charged for this run | $0.042 | $0.008–0.081 |

Two scrapers cost less for this request, and both returned 10–15 replies instead of 20.

### What is it for?

Reading what a community actually answers under a post, support and reputation monitoring, sentiment work that needs the comments and not only the original post, conversation datasets for model training, and AI agents asked "what did people reply to this".

| Mode | You give | You get |
|---|---|---|
| **Replies** | usernames | replies the account wrote, each with the post it answered |
| **Thread** | post URLs | the post with its self-thread and all its replies |
| **Reposts** | usernames | posts the account reposted, with the original inline |

### What data does it return?

| Field | Example |
|---|---|
| `id`, `code`, `url` | 3977518562965884838 · Dcy_A8pGo-m · https://www.threads.net/@zuck/post/Dcy_A8pGo-m |
| `text`, `language`, `createdAt` | "totally agree, the latency is the hard part" · en · 2026-09-02T19:26:23.000Z |
| `username`, `userId`, `fullName`, `isVerified`, `profileUrl` | who wrote the reply |
| `likeCount`, `replyCount`, `repostCount`, `quoteCount`, `shareCount` | engagement on the reply itself |
| `viewCount` | the views Threads prints under the post, read from its own page; `null` while not public yet |
| `isReply`, `replyToUsername`, `replyToUserId`, `rootPostUsername` | who is being answered |
| `parentPostId`, `parentPostUrl`, `threadId`, `positionInThread`, `threadLength` | where the reply sits in the conversation |
| `mediaType`, `imageUrl`, `videoUrl`, `images[]`, `videos[]` | media attached to the reply |
| `hashtags`, `mentions`, `urls`, `linkPreview` | \["ai"] · \["natgeo"] · \["https://…"] |
| `isRepost`, `repostedPost`, `repostedBy` | the original post behind a repost |
| `source` | replies · reply-context · thread · reposts |

### How much does it cost?

Pay per row, no start fee, and error rows are free. There is no browser here, so platform usage is close to zero.

| Row | Price |
|---|---|
| Post or reply row | $0.002 — 1,000 replies for $2 |
| Profile (when `includeProfile` is on) | $0.004 |

Larger monthly plans get 10–30 % off.

#### Bulk export: what 50,000 posts actually cost

This Actor is built for bulk jobs — put hundreds of inputs into one run, or call it from the API on
a schedule. There is **no fee per run, no fee per page and no proxy charge**: you pay for the rows
you keep, and error rows are free. That is what decides the bill once you pull a whole market
rather than a single account.

| Job | This Actor | Most-used Actor in this category |
|---|---|---|
| 50,000 posts across 100 runs | **$100** | $127 |

Checked on the Apify Store on 21 September 2026 against the Actor with the most monthly users in
this category; its per-run fee is counted in, as ours would be if we charged one. Some Actors here
ask less per row — this table compares against the one buyers actually use most.

### How to scrape Threads replies

1. Choose **🧭 What to get**: *replies* (what an account replies to others), *reposts* (what it amplifies) or *thread* (the full conversation under a post).
2. For replies and reposts, put accounts in **👤 Usernames**. For thread mode, paste the post links into **🔗 Post URLs**.
3. Set **💬 Replies per post** in thread mode — a busy post can carry thousands, and you are billed per row.
4. Click **Start**, then export as JSON, CSV or Excel, or read the dataset from the API.

### ⬇️ Input

```json
{
  "mode": "thread",
  "postUrls": ["https://www.threads.net/@mkbhd/post/DdFHeWKimvY"],
  "maxRepliesPerPost": 200
}
```

What an account replies to elsewhere:

```json
{ "mode": "replies", "usernames": ["zuck"], "maxPosts": 100 }
```

Complaints only, from a brand's replies:

```json
{ "mode": "replies", "usernames": ["nike"], "maxPosts": 200, "filterKeywords": ["refund", "shipping"] }
```

#### Every input field

| Field | What it does |
|---|---|
| `mode` | `replies`, `reposts` or `thread` — the account's replies, its reposts, or a post's conversation. |
| `usernames` | Accounts for replies and reposts mode. |
| `postUrls` | Post links for thread mode (`/@user/post/CODE` or a share link `threads.com/share/CODE`). A profile link is not a post link. |
| `startUrls` | Mixed Threads links; post URLs are routed to thread mode automatically. |
| `maxPosts` | Rows per account in replies and reposts mode. |
| `maxRepliesPerPost` | How deep to read one conversation. |
| `postedAfter` | Keep only rows newer than this date. |
| `filterKeywords` | Keep only rows whose text contains one of these words. Applied before billing. |
| `includeProfile` | Add a profile row for each author — followers, bio, contacts. |
| `includeProfileDetails` | Open each author's profile page for the full set of fields. |
| `includeViews` | Fill `viewCount` from each post's page (on by default, no extra charge). Turn off for the fastest bulk runs. |
| `maxItems` | Ceiling on rows for the whole run. |

### ⬆️ Output

```json
{
  "type": "post",
  "id": "3712...",
  "code": "DdFHeWKimvY",
  "url": "https://www.threads.net/@someone/post/DdFHeWKimvY",
  "username": "someone",
  "text": "This is exactly what I meant…",
  "createdAt": "2026-09-14T19:02:44.000Z",
  "isReply": true,
  "replyToUsername": "mkbhd",
  "rootPostUrl": "https://www.threads.net/@mkbhd/post/DdFHeWKimvY",
  "likeCount": 120,
  "replyCount": 3,
  "repostCount": 0,
  "imageUrls": [],
  "scrapedAt": "2026-09-15T09:00:00.000Z"
}
```

Reposts carry the original author and text, so you can tell an account's own words from what it amplified. Failures arrive as `type: "error"` rows and are free.

### Use cases

#### Customer complaints and support

Read a brand's replies with `filterKeywords` set to `refund`, `broken`, `delay` — the complaints arrive as a table instead of a scroll.

#### Community and conversation analysis

Thread mode returns a whole discussion under one post, with each reply's author and engagement, ready for sentiment work.

#### Finding engaged people

Reply authors are the active part of an audience. Add `includeProfile` and you get their follower counts and contacts alongside.

#### Competitor listening

Reposts show what a competitor chooses to amplify — often a better signal of strategy than what they write themselves.

#### AI agents

An agent asked "what did people say under this post" gets the conversation as rows, with no browser and no login.

### 🤖 For AI agents and LLM apps

Compact reference for agents calling this Actor through the [Apify MCP server](https://mcp.apify.com) or the API (`lergassy/threads-replies-scraper`).

**Purpose:** read the conversation layer of Threads — replies under a post, an account's replies elsewhere, and its reposts.

**Minimal input:**

```json
{ "mode": "thread", "postUrls": ["https://www.threads.net/@user/post/CODE"], "maxRepliesPerPost": 100 }
```

**Behaviours an agent should know:**

- Thread mode needs a **post** URL (`/@user/post/CODE`, or the app's share link `threads.com/share/CODE`). A profile URL will not do — use replies mode for an account.
- `maxRepliesPerPost` is the real cost lever: a popular post can carry thousands of replies, each one a billed row.
- `isReply`, `replyToUsername` and `rootPostUrl` place every row in the conversation without a second lookup.
- Deleted or hidden replies are simply absent; Threads does not serve them to a visitor.
- `filterKeywords` runs before billing, so a narrow question costs less than a broad one.
- Error rows are free — check `type` before reading text fields.

### Use via API

Run this Actor from your own code or pipeline. Get your token in Apify Console → Settings → API & Integrations. Every input field below has the same name as in the JSON tab of the input form.

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lergassy/threads-replies-scraper").call(run_input={
    "mode": "replies",
    "usernames": [
        "zuck"
    ],
    "maxPosts": 50,
    "maxRepliesPerPost": 100
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lergassy/threads-replies-scraper').call({
    "mode": "replies",
    "usernames": [
        "zuck"
    ],
    "maxPosts": 50,
    "maxRepliesPerPost": 100
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**cURL** (runs the Actor and returns the results in one call)

```bash
curl -X POST "https://api.apify.com/v2/acts/lergassy~threads-replies-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"mode": "replies", "usernames": ["zuck"], "maxPosts": 50, "maxRepliesPerPost": 100}'
```

### Limitations, stated plainly

- **A logged-out visitor's view.** Threads paginates replies and does not show everything under very large posts; the Actor reads what is served.
- **No reply search.** You cannot ask for "all replies mentioning X across Threads" — start from an account or a post, then filter.
- **Private accounts contribute nothing.** Their replies are not public.
- **Keyword and hashtag search lives elsewhere** — see [Threads Search Scraper](https://apify.com/lergassy/threads-search-scraper).
- **Refusals.** When Threads refuses a request, it is retried on a new address and then once through a residential address at our cost. If Threads keeps refusing most of a run, the Actor pauses once, then stops instead of grinding: the posts and accounts it did not get to are listed in the `NOT_ATTEMPTED` record and in the status message (not charged — run them again later). Rows of a large conversation are written as they arrive, so a stopped run keeps everything it was charged for.

### Run health

When a run ends with many error rows, the Actor sends its developer the counts (rows delivered, error types, run ID) so the cause gets fixed fast; your input and results are never sent.

### Integrations

Runs from the Apify API, the Python and JavaScript clients, and from **n8n**, **Make** or **Zapier** through the Apify app. Schedule it, send rows to **Google Sheets**, a Slack channel or a webhook, or let an agent call it through the Apify MCP server.

### ❓ FAQ

#### Do I need a Threads account?

No. Everything here is public and read without logging in.

#### What is the difference between replies mode and thread mode?

Replies mode starts from an account and returns what it wrote under other people's posts. Thread mode starts from a post and returns the conversation under it.

#### Why does my profile URL not work in thread mode?

Because a thread is a post. Use the `/@user/post/CODE` link, or switch to replies mode and pass the username.

#### Can I get every reply of a huge post?

You get what Threads serves to a visitor, up to `maxRepliesPerPost`. Very large threads are paginated and the tail is not always public.

#### How do I keep only complaints?

Put your words in `filterKeywords`. Rows that do not contain them are dropped before you are charged.

#### Are reposts billed like replies?

Yes, one row each, at the same post price. The row carries the original author so you can separate them afterwards.

#### Can I get the profile of everyone who replied?

Turn on `includeProfile`. That adds one profile row per author at the profile price.

#### Is scraping Threads replies legal?

The Actor reads public pages at a normal rate without logging in, which is ordinary public-data collection. Replies are personal data, so how you store and use them is your responsibility.

### You might also like

| Actor | What it does |
|---|---|
| [Threads Scraper](https://apify.com/lergassy/threads-scraper) | Search, posts, replies and profiles in one Actor |
| [Threads Search Scraper](https://apify.com/lergassy/threads-search-scraper) | Keyword and hashtag search with filters |
| [Threads Profile Scraper](https://apify.com/lergassy/threads-profile-scraper) | Full profiles with followers, bio and contacts |
| [YouTube Comments Scraper](https://apify.com/lergassy/youtube-comments-scraper) | The same conversation layer for YouTube |

### Also known as

People look for this Actor as a Threads replies scraper, Threads comments scraper, Threads conversation API, Threads thread scraper, Threads reposts scraper and a Threads community analysis tool.

### Notes

Public conversations only. How deep a thread goes is Threads' decision: `maxRepliesPerPost` caps how many replies are read under one post, and `maxPosts` caps the run.

Need an account's own posts, its profile and contacts, or posts by keyword? Those live in **Threads Profile Scraper**, **Threads Search Scraper** and the all-in-one **Threads Scraper**.

# Changelog

This Actor's version history is a separate document: https://apify.com/lergassy/threads-replies-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

<b>Posts</b> — an account's own posts, as many as you ask for. <b>Replies</b> / <b>Reposts</b> — what an account answered or boosted. <b>Profile</b> — followers, bio, links and contacts. <b>Search</b> — public posts for keywords and hashtags. <b>Thread</b> — one post with its replies. <b>Accounts</b> — people and brands matching a keyword.

## `usernames` (type: `array`):

For Posts, Replies, Reposts and Profile. Bare name, with @, or the profile URL: <code>zuck</code>, <code>@natgeo</code>, <code>https://www.threads.net/@nasa</code>.

## `postUrls` (type: `array`):

For Thread mode: <code>https://www.threads.net/@zuck/post/Dcy_A8pGo-m</code>. Share links from the app (<code>https://www.threads.com/share/CODE</code>) work too. In Posts mode these are fetched too.

## `startUrls` (type: `array`):

Post URLs (threads.com/@user/post/…) for mode "thread", and profile URLs (threads.com/@username) for modes "replies" and "reposts". Search and tag links are not read by this Actor: use Threads Search Scraper for keywords.

## `maxPosts` (type: `integer`):

Cap per username or keyword, not per run. Posts mode pages through the whole profile; Search returns what Threads shows a logged-out visitor (usually 20–60 posts per keyword across the top, recent and tag pages).

## `maxRepliesPerPost` (type: `integer`):

Threads shows a logged-out visitor the first ~25 replies of a post.

## `postedAfter` (type: `string`):

<code>YYYY-MM-DD</code>. Older posts are dropped and Posts mode stops paging once it reaches them.

## `filterKeywords` (type: `array`):

Case-insensitive words or phrases; a post is kept when it contains any of them. Empty = keep everything.

## `includeProfile` (type: `boolean`):

Posts, Replies and Reposts modes: also save the account's profile (followers, bio, links, contacts).

## `includeProfileDetails` (type: `boolean`):

Accounts mode: open each account's page for follower count, bio links and contacts (one extra request per account).

## `includeViews` (type: `boolean`):

Fill viewCount on every post (the number Threads shows under a post, e.g. "134K views"). Read from each post's own page: one extra request per post, no extra charge. Turn off for the fastest possible bulk runs.

## `maxItems` (type: `integer`):

Stop after this many rows in the run.

## `concurrency` (type: `integer`):

How many accounts or keywords are processed at once.

## `proxyConfiguration` (type: `object`):

Apify datacenter proxies work for Threads. If runs end with rate-limit error rows, switch to Residential.

## Actor input object example

```json
{
  "mode": "replies",
  "usernames": [
    "zuck"
  ],
  "maxPosts": 50,
  "maxRepliesPerPost": 100,
  "includeProfile": false,
  "includeProfileDetails": true,
  "includeViews": true,
  "maxItems": 10000,
  "concurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `rows` (type: `string`):

One row per post (text, author, time, likes, replies, reposts, quotes, shares, media URLs, links, mentions, hashtags, quoted or reposted post, reply context) or per profile / account (followers, bio, links, emails, phones).

## `runSummary` (type: `string`):

JSON counters for the run: rows delivered, filtered out, errors and request statistics.

## `notAttempted` (type: `string`):

JSON list of inputs the run did not reach (time limit or "Max cost per run"). Not charged — pass them as input to a new run to continue. Present only when the run stopped early.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "replies",
    "usernames": [
        "zuck"
    ],
    "maxPosts": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/threads-replies-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "replies",
    "usernames": ["zuck"],
    "maxPosts": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("lergassy/threads-replies-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "replies",
  "usernames": [
    "zuck"
  ],
  "maxPosts": 50
}' |
apify call lergassy/threads-replies-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/threads-replies-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qtsTulpEBIjd3wcLg/builds/aYnQhV5UhPjjpxwXh/openapi.json
