# Threads Replies Scraper (`khadinakbar/threads-replies-scraper`) Actor

Extract public Threads replies from post URLs: reply text, author, likes, nested reply counts, and parent post context. Provider-backed, cookieless, MCP-ready.

- **URL**: https://apify.com/khadinakbar/threads-replies-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 public reply scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

Extract **public replies** from Threads post URLs into one dataset row per visible reply: author handle, profile URL, reply text, likes, nested reply count, and parent post context. Built for community, social-listening, and lead-gen teams that already have a post URL and need the people talking under it. Cookieless and MCP-ready — no Threads login, cookies, or session IDs.

This Actor is the **get-replies-by-post-URL** sibling in the Threads cluster.

### Best fit for this Actor

- You already have a public Threads `/@user/post/CODE` URL and want the visible reply layer as structured rows.
- You need reply author identity fields (`authorUsername`, `authorProfileUrl`) next to text and likes for listening or outreach lists.
- You want a cookieless, MCP-ready reply tool rather than a post-search or profile-feed crawl.

Start with a single post URL for agent calls. Continue with a compact batch when you are archiving known viral posts. Pair it with [Threads Search Scraper](https://apify.com/khadinakbar/threads-search-scraper) when the next step is discovering posts by keyword first.

### Sibling routing

- Keyword / topic discovery → [Threads Search Scraper](https://apify.com/khadinakbar/threads-search-scraper)
- Post rows from search or feeds → [Threads Posts Scraper](https://apify.com/khadinakbar/threads-posts-scraper)
- Profile feed collection → [Meta Threads Profile Posts Scraper](https://apify.com/khadinakbar/meta-threads-profile-posts-scraper)
- After you have post URLs, continue with this Actor for the public reply preview

### Workflow story: from a pasted post URL to a reply shortlist

A community lead pastes a competitor’s viral Threads post URL, sets `maxRepliesPerPost` to bound cost, and starts the Actor. Each dataset row carries the reply author, text, likes, and profile URL. They export CSV, keep high-signal authors for a reply-first outreach list, and schedule the same input so fresh visible replies keep feeding the CRM.

### Quick start input

```json
{
  "postUrls": ["https://www.threads.com/@zuck/post/DdCYWl7GktV"],
  "maxRepliesPerPost": 10,
  "providerOrder": "scrapecreators-first"
}
```

`postUrls` (or `startUrls`) is required. Accepts `threads.com` and `threads.net` post URLs. Unique post codes are processed up to fifty URLs per run.

### Input reference

| Field | Type | What it controls |
|---|---|---|
| `postUrls` | array | Public Threads post URLs |
| `startUrls` | array | Alternative Apify request-list input |
| `maxRepliesPerPost` | integer | Cap reply rows saved per URL |
| `providerOrder` | enum | Managed provider priority (`scrapecreators-first` default) |
| `includeRawData` | boolean | Attach raw provider payload when debugging |

### What data you receive

One dataset item represents **one public Threads reply** from the provider preview.

| Field | What it answers |
|---|---|
| `authorUsername` + `authorProfileUrl` | **Who** replied |
| `text` + `likeCount` + `publishedAt` | **What** they said, traction, and when |
| `replyUrl` + `replyId` | Canonical reply permalink and id |
| `parentPostUrl` + `parentReplyCount` | Which post, and how many replies Threads reports upstream |
| `childReplyCount` + `replyToUsername` | Nested activity signals on that reply |
| `provider` + `scrapedAt` | Provenance |

```json
{
  "recordType": "reply",
  "provider": "scrapecreators",
  "parentPostUrl": "https://www.threads.com/@zuck/post/DdCYWl7GktV",
  "parentPostCode": "DdCYWl7GktV",
  "parentReplyCount": 12,
  "replyId": "3981870302313911160",
  "replyUrl": "https://www.threads.com/@demo_user/post/DdCcfFvGRN4",
  "text": "Great point",
  "authorUsername": "demo_user",
  "authorProfileUrl": "https://www.threads.com/@demo_user",
  "likeCount": 4,
  "childReplyCount": 2,
  "replyToUsername": "zuck",
  "publishedAt": "2023-11-14T22:13:20.000Z",
  "scrapedAt": "2026-09-15T12:00:00.000Z"
}
```

Download the dataset as JSON, CSV, Excel, or HTML. Every terminal run also writes `OUTPUT` and `RUN_SUMMARY` with `outcome` (`COMPLETE` / `PARTIAL` / `VALID_EMPTY` / `INVALID_INPUT` / `UPSTREAM_FAILED` / `CONFIG_ERROR`). Inspect that outcome, then read the dataset. Each row keeps `parentPostUrl`, `provider`, and `scrapedAt` as provenance.

**Scope:** public reply previews returned with each post by the managed providers. Treat `parentReplyCount` as an upstream total; saved rows are the preview sample capped by `maxRepliesPerPost`.

### Best results guidance

- Provide a public Threads post URL you can open while logged out.
- Start with one URL for agent calls; schedule a compact batch of known post URLs for listening jobs.
- Confirm the source is a `/post/` URL. Profile and search URLs belong on the sibling scrapers above.
- Validate `OUTPUT.outcome` before treating an empty dataset as a product issue: empty public previews report `VALID_EMPTY` with zero `reply-scraped` charges.
- Cap cost with `maxRepliesPerPost` when agents paste large URL lists.

### Why AI agents and MCP clients choose this Actor

- **Post URL in, reply rows out.** One clear job for agents that already have Threads post links.
- **Predictable cost.** Saved replies use the `reply-scraped` Pay per event unit; see the live Pricing tab.
- **Structured output.** Stable keys plus a published dataset schema.
- **Honest outcomes.** Inspect `OUTPUT` for `INVALID_INPUT`, `VALID_EMPTY`, `PARTIAL`, or `UPSTREAM_FAILED`, then read the dataset.

> Use `apify--threads-replies-scraper` with `postUrls` set to public Threads post URLs. Cap with `maxRepliesPerPost`. Expect one row per visible reply preview; treat `parentReplyCount` as an upstream total for context. After the call, read the dataset and keep `parentPostUrl` / `provider` / `scrapedAt`.

MCP tool name: `apify--threads-replies-scraper`. Hosted setup lives at [mcp.apify.com](https://mcp.apify.com).

### Pricing — Pay per event + platform usage

| Event | Charged when |
|---|---|
| Actor start | Once per run |
| `reply-scraped` | One validated public reply row saved to the dataset |

Pay per event plus Apify platform usage. When you need current event amounts, open the live [Pricing tab](https://apify.com/khadinakbar/threads-replies-scraper/pricing). Empty public previews and invalid input skip the reply event. A bounded ten-reply job is about ten `reply-scraped` events plus the start event and a small usage component.

### Use through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~threads-replies-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"postUrls":["https://www.threads.com/@zuck/post/DdCYWl7GktV"],"maxRepliesPerPost":10}'
```

### Integrations and chaining

- Discover then replies: [Threads Search Scraper](https://apify.com/khadinakbar/threads-search-scraper) or [Threads Posts Scraper](https://apify.com/khadinakbar/threads-posts-scraper) to collect post URLs, then pass those URLs here.
- Profile then replies: [Meta Threads Profile Posts Scraper](https://apify.com/khadinakbar/meta-threads-profile-posts-scraper) for feed posts, then this Actor for each post’s reply preview.

### Scope, data boundary, and recovery

Public, logged-out visible reply previews only. Nested reply trees deeper than the provider preview, private accounts, and login-only insights stay outside this contract. Dual-provider fallback uses owner-managed ScrapeCreators then SociaVault. Owner secrets, never caller API keys. Duplicate `.com` / `.net` variants of the same post are merged before fetch so PPE stays predictable.

### Builder's note

I built this after probing both public-data providers on live Threads post URLs. Both return a public `comments` array with the parent post — so this SKU is intentionally reply-focused rather than a second post scraper. I found that SociaVault sometimes returns that array as a numeric-key object; the runtime unwraps it the same way as other social Actors in this portfolio. Deduplicating `.com` / `.net` variants before fetch keeps PPE predictable when agents paste messy URL lists.

### FAQ

**Are liker identities included?** Like counts are public totals on each reply. This Actor returns reply authors, not likers.

**Is Threads login required?** Public post reply previews work without login or cookies.

**What happens when a post has no visible replies?** The Actor reports `VALID_EMPTY` with zero `reply-scraped` charges when every URL returns an empty preview.

**What about mixed valid and invalid URLs?** Valid posts still save reply rows; profile or junk URLs surface as warnings and the run outcome is `PARTIAL`.

### Legal

This Actor retrieves publicly available data. You are responsible for complying with Threads / Meta Terms of Service, applicable data-protection laws (GDPR/CCPA), and Apify's [Exclusion Policy](https://apify.com/terms/exclusion-policy) when using the results.

Threads is a trademark of its owner. This independent Actor is not affiliated with, associated with, or endorsed by Threads or Meta.

# Actor input Schema

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

Public Threads post URLs to extract replies from. Accepts https://www.threads.com/@user/post/CODE and https://www.threads.net/@user/post/CODE. Up to 50 URLs per run. Not for profile URLs, search queries, private posts, or login-only content.

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

Alternative Apify request-list input for Threads post URLs. Use when another actor or agent passes request objects. Not for usernames, profile pages, or search URLs.

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

Maximum reply rows to save per post URL. Default 25. Range 1 to 200. Caps output volume and cost. Public provider routes typically return a preview sample (often ~20-30 replies) even when the parent post shows a higher reply count.

## `providerOrder` (type: `string`):

Which managed public-data API is tried first. ScrapeCreators is the recommended primary and SociaVault is the fallback. Use single-provider modes only when debugging. This setting never accepts user cookies or credentials.

## `includeRawData` (type: `boolean`):

Attach the raw provider reply object to each dataset row for debugging custom fields. Defaults to false because raw payloads increase dataset size and token usage.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.threads.com/@zuck/post/DdCYWl7GktV"
  ],
  "startUrls": [
    {
      "url": "https://www.threads.com/@zuck/post/DdCYWl7GktV"
    }
  ],
  "maxRepliesPerPost": 10,
  "providerOrder": "scrapecreators-first",
  "includeRawData": false
}
```

# Actor output Schema

## `output` (type: `string`):

Terminal outcome envelope.

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

Dataset API URL for saved Threads reply rows.

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

Per-target status summary and provider diagnostics.

# 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/DdCYWl7GktV"
    ],
    "startUrls": [
        {
            "url": "https://www.threads.com/@zuck/post/DdCYWl7GktV"
        }
    ],
    "maxRepliesPerPost": 10,
    "includeRawData": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/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/DdCYWl7GktV"],
    "startUrls": [{ "url": "https://www.threads.com/@zuck/post/DdCYWl7GktV" }],
    "maxRepliesPerPost": 10,
    "includeRawData": False,
}

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

```

## MCP server setup

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