# Threads Replies Scraper: Post Replies, Likes & Authors (`xmolodtsov/threads-replies-scraper`) Actor

Scrape public Threads post replies with text, likes, authors, media and inline nested replies. Choose top or recent order and export one row per reply. No login; public subset only.

- **URL**: https://apify.com/xmolodtsov/threads-replies-scraper.md
- **Developed by:** [GoFetch](https://apify.com/xmolodtsov) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.10 / 1,000 replies

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

Get replies from public Threads posts as structured rows. **Threads Replies Scraper: Post Replies, Likes & Authors** collects reply text, public author handles and display names, verification, likes, reply counts, timestamps, media URLs and the nested replies already included in the public response. Supply post URLs; each saved reply becomes one dataset row. No login or account cookies are needed.

![Threads replies avatar](https://api.apify.com/v2/key-value-stores/2DxCOvbMjhvK3S1qP/records/threads-replies-scraper-avatar.png)

Use it to review public conversations, compare reactions across supplied posts, or feed a research workflow. It collects public replies to the supplied posts; it does not search profiles or enrich authors.

### Quick start

1. Paste one or more public post links in `postUrls`. Both `threads.com` and `threads.net` links work.
2. Choose the per-post limit and reply order. Start with 20 replies on one post.
3. Run the actor and open the dataset. Export JSON, CSV, Excel or JSONL, or read it through the Apify API.

```json
{
  "postUrls": ["https://www.threads.com/@zuck/post/DTa3-B1EbTp"],
  "maxRepliesPerPost": 20,
  "sort": "top",
  "includeNestedReplies": true,
  "maxItems": 1000,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

Run synchronously through the API using your own token:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/xmolodtsov~threads-replies-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"postUrls":["https://www.threads.com/@zuck/post/DTa3-B1EbTp"],"maxRepliesPerPost":20}'
```

For larger jobs, start an asynchronous actor run, wait for it to finish, then read its default dataset. Avoid embedding tokens in shared URLs or exported workflow definitions.

### Inputs

| Field | Default | What it controls |
|---|---|---|
| `postUrls` | Required | 1–100 public `/@user/post/<code>` links. Query strings and trailing slashes are accepted; canonical URLs are deduplicated. Invalid entries are skipped with a warning when some links are valid. No valid links means `FAILED invalid:`. |
| `maxRepliesPerPost` | 100 | Saved rows per source post, including inline nested replies when enabled. `0` requests all reachable replies, bounded by `maxItems`, time and budget. |
| `sort` | `top` | `top` follows public web ranking; `recent` starts the recent-replies connection. |
| `includeNestedReplies` | `true` | Include child replies already inlined by the public response. |
| `maxItems` | 1000 | Run-wide saved-row cap, 1–100000. Free-plan cap: 100 results/run and 20 runs/UTC calendar month. |
| `proxyConfiguration` | Apify datacenter | Residential is optional. Explicit choices do not silently fall back. Free-plan runs use only Apify Proxy; custom/direct settings are ignored. |

### Output

![Saved replies with placeholder author identities](https://api.apify.com/v2/key-value-stores/2DxCOvbMjhvK3S1qP/records/threads-replies-scraper-output-preview.png)

This example uses a row from a private proof run, with the replier’s identity and permalink replaced by placeholders. Dataset IDs are strings so exports and downstream applications can preserve their exact values.

```json
{
  "postUrl": "https://www.threads.com/@zuck/post/DTa3-B1EbTp",
  "postId": "3808602590024938729",
  "replyId": "1234567890123456789",
  "replyCode": "EXAMPLE_REPLY",
  "replyUrl": "https://www.threads.com/@example_user/post/EXAMPLE_REPLY",
  "text": "Thanks for the reminder to unfollow",
  "createdAt": "2026-01-12T18:01:46.000Z",
  "authorUsername": "example_user",
  "authorName": "Example User",
  "authorVerified": false,
  "authorProfilePicUrl": "https://example.com/profile-picture.png",
  "likeCount": 6,
  "replyCount": 1,
  "repostCount": 0,
  "quoteCount": 0,
  "media": [],
  "level": 0,
  "parentReplyId": null,
  "scrapedAt": "2026-10-21T20:34:53.839Z"
}
```

| Fields | Meaning |
|---|---|
| `postUrl`, `postId` | Canonical input post URL and exact string post ID. |
| `replyId`, `replyCode`, `replyUrl` | Exact reply ID, public shortcode and permalink. Deduplication uses the reply ID within each source post. |
| `text`, `createdAt` | Reply text and ISO publication time. Missing values are `null`. |
| `authorUsername`, `authorName` | Public author handle and display name. |
| `authorVerified`, `authorProfilePicUrl` | Public verification flag and profile picture URL when supplied. |
| `likeCount`, `replyCount`, `repostCount`, `quoteCount` | Public engagement counts, each nullable. A missing count is not replaced with zero. |
| `media` | Array of `{ "type": "image" or "video", "url": "…" }`; empty when no media is returned. |
| `level`, `parentReplyId` | `0` is a direct reply; larger levels are inline children. Parent ID is set only when resolved in the same public thread segment; otherwise `null`. |
| `scrapedAt` | ISO collection time. |

Quoted and embedded posts are excluded from reply rows. Media links can expire. No contact fields or profile enrichment are added.

### Pricing

Only saved reply rows use the `apify-default-dataset-item` event, titled **Reply**. There are no actor-start or add-on events. The run and per-post limits count saved rows across direct and included nested replies.

| Apify plan | Price per 1,000 saved replies |
|---|---:|
| FREE | $2.00 |
| BRONZE | $1.80 |
| SILVER | $1.50 |
| GOLD | $1.10 |
| PLATINUM / DIAMOND | $1.10 |

Example result charges, excluding any separate Apify platform or proxy charges:

| Saved rows | BRONZE | GOLD |
|---|---:|---:|
| 100 | $0.18 | $0.11 |
| 300 | $0.54 | $0.33 |
| 2,000 | $3.60 | $2.20 |

#### Is it free?

On the Apify free plan, this developer allows **100 results per run × 20 runs per UTC calendar month**. These are developer limits, not Apify's general platform limits. Free-plan actor result events are subject to Apify's free-plan billing rules; platform credits and proxy usage still follow your Apify plan. The FREE row is the published event ladder, not a promise of unlimited free platform usage.

The monthly allowance resets on the first day of the month. A run above the allowance exits `SUCCEEDED`, saves zero rows and makes zero requests to Threads, with an explanatory quota message. Paid Apify plans are not subject to the developer's 100/20 cap. The developer owner and Apify TEST runs are exempt for health checks.

### Coverage and failure guarantees

- **Public subset per sort.** The post's displayed reply total can include replies unavailable to anonymous readers. `top` and `recent` expose different sets. In local checks, top reached 939 on a post reporting 6,552 replies. After fixing source field error handling, recent saved 5,509 and exhausted the public connection on the same post, then reporting 6,551 replies (previously it stopped at 3,733). These are observations, not promised counts or coverage percentages. `0` requests continued pagination, not a guarantee of every reported reply.
- **Inline nested replies only.** Included children carry source-derived level and nullable parent links. Anonymous separate child expansion is unavailable and is never called. Disabling nested replies keeps direct replies only.
- **Cursor guards.** Pagination stops on exhaustion, an empty cursor, a repeated cursor, a result cap, deadline or run budget. Empty/repeated cursors and deep source errors mark the input truncated and the run partial; exhaustion and result caps remain complete successes. `STATISTICS` records each input's reported total, saved count, sort, exhaustion and truncation flags.
- **Operation changes fail loudly.** The actor discovers the GraphQL operation from the page, with CDN-bundle fallback. A critical error on a post’s first GraphQL page triggers one shared rediscovery and retry. Persistent first-page failure or missing post state without a positive not-found signal is `outdated:`; the run fails only when nothing was saved. Usable reply connections survive source field errors, which are counted in `STATISTICS.sourceFieldErrors`. A critical source error at a deep cursor ends coverage for that post, marks it `truncated` with `coverageStop: "source_error"`, and continues with later inputs as a partial success.
- **Unavailable posts are skipped.** An HTTP 404 or the source’s explicit not-found page state marks the input `notFound: true`, logs a warning with its URL and continues. This counts as a confirmed empty input. Missing post state alone is an error.
- **Saved rows survive.** Later operation, network, block or time errors produce a partial success when rows were saved. Zero rows with errors fail with `blocked:`, `network:`, `timeout:`, `invalid:`, `quota:` or `outdated:`. A confirmed valid empty response succeeds as no results. Infrastructure quota errors fail closed; an exhausted monthly allowance is a graceful successful refusal.
- **Budgets and restarts.** Writes are serialized and bounded; a charge limit ends successfully with `run budget reached`. Finite run deadlines stop requests early to save data. After reboot or migration, saved dataset IDs seed deduplication and limits so existing replies are not pushed again.

For reproducibility, keep your input, sort, run ID and dataset. Public replies and ranking can change between runs, and a new run can return a different subset.

### Integrations

Use Apify datasets, schedules, webhooks and API clients in your own workflows. n8n and Make can start the actor and consume dataset rows. For spreadsheet analysis, export CSV or Excel and preserve `postId`, `replyId` and `parentReplyId` as text. Your workflow can join rows by `postUrl` or `postId` and group replies by author handle without fetching additional profile data.

### Support

Open the actor's Issues tab with the run ID, a public post URL, reply order and expected behavior. Do not include tokens, private accounts or account cookies.

### More scrapers from this developer

**TikTok:** [TikTok Search Scraper](https://apify.com/xmolodtsov/tiktok-search-scraper): videos and creators for any keyword, pay per result · [TikTok Profile Scraper (Pay Per Result)](https://apify.com/xmolodtsov/tiktok-profile-scraper): profiles, followers and latest posts by username · [TikTok Comments Scraper](https://apify.com/xmolodtsov/tiktok-comments-scraper): comments and full reply threads from any video · [TikTok Hashtag Scraper](https://apify.com/xmolodtsov/tiktok-hashtag-scraper): videos for any hashtag, with views, likes and music · [TikTok Sound & Music Scraper](https://apify.com/xmolodtsov/tiktok-sound-scraper): videos that use a sound or song · [TikTok Top Ads Scraper](https://apify.com/xmolodtsov/tiktok-top-ads-scraper): public Creative Center ad rankings, engagement, media and landing pages

**Social & news:** [Reddit Search Scraper](https://apify.com/xmolodtsov/reddit-scraper): posts by keyword, subreddit or author · [Google News Scraper](https://apify.com/xmolodtsov/google-news-scraper): Google News results as clean full-text articles

**Instagram:** [Instagram Reel Scraper](https://apify.com/xmolodtsov/instagram-reel-scraper): public profile reels, plays, captions, music and media URLs · [Instagram Comment Scraper](https://apify.com/xmolodtsov/instagram-comment-scraper): public post and reel comments, likes, timestamps and usernames

**E-commerce:** [Prom.ua Product Search Scraper](https://apify.com/xmolodtsov/prom-ua): Prom.ua product search results, no browser needed · [Amazon Product Search & Bestsellers Scraper](https://apify.com/xmolodtsov/amazon-search-scraper): search results, Best Sellers and product details from Amazon · [AliExpress Search Scraper](https://apify.com/xmolodtsov/aliexpress-search-scraper): aliExpress products by keyword with prices, orders and shipping · [AliExpress Product Reviews Scraper](https://apify.com/xmolodtsov/aliexpress-reviews-scraper): public product reviews, ratings, buyer photos and follow-up feedback

**Maps & leads:** [Google Maps Scraper](https://apify.com/xmolodtsov/google-maps-scraper): places, leads and emails from Google Maps

**Ads:** [Facebook Ad Library Scraper (Meta Ads Library)](https://apify.com/xmolodtsov/facebook-ads-library-scraper): ads from the Meta Ad Library, with EU reach and payers · [Google Ads Transparency Scraper](https://apify.com/xmolodtsov/google-ads-transparency-scraper): Google ad creatives by advertiser or domain, with regional details

**Video:** [YouTube Transcript Scraper](https://apify.com/xmolodtsov/youtube-transcript-scraper): transcripts, subtitles and captions from YouTube videos · [YouTube Shorts Scraper](https://apify.com/xmolodtsov/youtube-shorts-scraper): Shorts of any channel with exact views, likes and duration · [YouTube Channel Scraper](https://apify.com/xmolodtsov/youtube-channel-scraper): every video of a channel, with channel stats · [YouTube Search Scraper](https://apify.com/xmolodtsov/youtube-search-scraper): search results and videos for any keyword · [YouTube Comments Scraper](https://apify.com/xmolodtsov/youtube-comments-scraper): comments, replies and likes from any video · [Bilibili Comments Scraper](https://apify.com/xmolodtsov/bilibili-comments-scraper): public hot comments and reply threads by video or keyword

**Jobs:** [SEEK Job Listings Scraper](https://apify.com/xmolodtsov/seek-jobs-scraper): public AU/NZ job listings, salaries and redacted descriptions

### FAQ

#### Why are there fewer rows than the post's reply count?

Anonymous public responses expose a subset. Sorting, visibility, removed replies, source errors and the chosen caps affect coverage. Try recent order when you need a deeper public set. Compare saved counts with reported totals in `STATISTICS`; neither sort promises completeness.

#### Does it need a Threads account?

No. Only public post pages and their anonymous reply endpoint are requested. Private content and authenticated child expansion are outside its scope.

#### Is it legal to scrape Threads replies?

This actor accesses public posts and public author handles/display names without login and does not add contact data. Public content can still contain personal data. Assess your purpose, applicable terms, lawful basis, retention and deletion obligations, and GDPR/CCPA requirements where applicable. Minimize what you retain and respect privacy and data-subject requests. This description is not legal advice.

# Changelog

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

# Actor input Schema

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

1–100 public Threads post URLs from threads.com or threads.net. Invalid entries are skipped when at least one URL is valid; canonical URLs are deduplicated.

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

Maximum saved replies for each post, including inline children when enabled. 0 returns all reachable public replies, bounded by maxItems and the run budget.

## `sort` (type: `string`):

Top follows the public web ranking. Recent starts a separate chronological connection and often reaches deeper. Neither sort guarantees the reported total.

## `includeNestedReplies` (type: `boolean`):

Include child replies already in the public response, with level and nullable parentReplyId. Separate child expansion is unavailable anonymously and is never requested.

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

Run-wide saved reply limit across all posts. On the Apify free plan: 100 results/run and 20 runs/calendar month (UTC), limits set by the developer. Paid plans can request up to 100000.

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

Apify datacenter by default; residential is optional. Explicit proxy choices never fall back. Free-plan runs use only Apify Proxy and ignore direct/custom proxy settings.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.threads.com/@zuck/post/DTa3-B1EbTp"
  ],
  "maxRepliesPerPost": 20,
  "sort": "top",
  "includeNestedReplies": true,
  "maxItems": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Public replies, one row per reply: exact string IDs, text, author handle/name/verified/photo, nullable counts, media, source relationships and timestamps. Quoted posts are excluded.

# 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 = {
    "postUrls": [
        "https://www.threads.com/@zuck/post/DTa3-B1EbTp"
    ],
    "maxRepliesPerPost": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("xmolodtsov/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 = {
    "postUrls": ["https://www.threads.com/@zuck/post/DTa3-B1EbTp"],
    "maxRepliesPerPost": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("xmolodtsov/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 '{
  "postUrls": [
    "https://www.threads.com/@zuck/post/DTa3-B1EbTp"
  ],
  "maxRepliesPerPost": 20
}' |
apify call xmolodtsov/threads-replies-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xmolodtsov/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/Ws5Rh3S6G8xKUl9mi/builds/bRu5FuO7MSXLOhZef/openapi.json
