# Threads Replies Scraper — Comments, Authors, Likes (No Login) (`architekture/threads-replies-scraper`) Actor

Export accessible replies to public Threads posts without logging in: text, authors, likes and nesting, plus root posts. Per-post coverage reports show what was reachable; Threads may expose fewer replies than its displayed count.

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

## Pricing

from $2.50 / 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.

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 — Comments, Authors, Likes (No Login)

**Recorded 18 Oct 2026 from Apify datacenter IPs, no login, no cookies: a 433-reply post by @zuck walked end to end in 27 page requests. That reached 225 direct replies, 241 reply posts in all including nested replies and the author's own thread. With forced IP rotations mid-walk it still reached all 225, and every run's coverage is reported, not hidden.**

From **Architekture**, makers of the YouTube, Reddit, Substack and retail scrapers.

🤖 **Built for AI workflows.** Every row is deterministic, schema-stable JSON — feed it straight to LLM apps, RAG pipelines, sentiment models or agent tool calls via the Apify API, the Apify MCP server (`mcp.apify.com`), or AI coding agents like Claude Code and Cursor.

| 🌐 Platform | 📍 Access | 📦 Recorded run | 💰 From | 🔑 Standout fields |
|---|---|---|---|---|
| Threads (threads.com / threads.net) | Public posts, no login 🌍 | 433-reply post → 241 reply rows in ~35 s | $2.50 / 1,000 replies | `isAuthor`, nesting `depth` / `parentCode`, per-post `coverage` |

Give it Threads post URLs (or profiles, for their latest posts) and get one clean JSON row per reply:

- reply author handle, name, profile URL, id and verified badge
- reply text, like / reply / repost / quote counts, timestamp, image and video URLs
- `isAuthor` for the thread starter's own replies (Threads' "Author" label)
- nesting: `depth`, `parentCode` and `replyToUsername`, so you can rebuild the conversation tree

The post itself comes back as its own `recordType: "post"` row.

### 🚀 Why choose this actor

- ✅ **An honest coverage report.** Threads shows logged-out visitors only part of a big post's replies (about half on the post above). `RUN_SUMMARY` lists each post's claimed reply count, how many direct replies were actually reachable, and a `coverage` ratio, so you know exactly what you got.
- 🔗 **The whole conversation, not just the first layer.** Each direct reply comes with the nested replies Threads shows under it, each linked to its parent.
- 🗂️ **Author replies flagged.** The thread starter's continuation posts and replies have `isAuthor: true`. Turn them off with `includeAuthorThread: false`.
- 🔎 **De-duplicated per run.** A reply that appears on several pages, or under two input URLs, is delivered and charged once.
- 🆓 **Never pay for misses.** A deleted, private or wrong link gets one free `recordType: "status"` row (`NOT_FOUND`, `BLOCKED`, `ERROR`, `INVALID_URL`).
- 📈 **Resumable.** After a platform migration or a resurrect, the run continues where it stopped, without duplicate or re-charged rows.

### ⚠️ Worth knowing up front

| Question | Answer |
|---|---|
| Do I need a Threads account or cookies? | ❌ No. Everything comes from what Threads shows logged-out visitors. |
| Will I get every reply a post claims? | Not on big posts. Threads hides part of them from logged-out visitors (225 of 433 on our test post). `coverage` reports it per post. |
| Does `RECENT` order reach more replies? | ❌ No. In our test both orders reached the same set. Order matters only when `maxRepliesPerPost` cuts the list. |
| Very long nested chains? | Threads shows the first few replies under each reply. Chains it cuts are counted in `truncatedChains`, not followed. |
| Profile scraping or search? | ❌ No. This is a replies tool. A profile URL only picks that profile's latest posts. |
| Do media URLs last? | They are signed Threads CDN links that expire. Download promptly if you need the files. |

### ⚡ Try the example

```json
{
  "postUrls": ["https://www.threads.com/@zuck/post/DeZtp-TkQHh"],
  "maxRepliesPerPost": 100
}
```

Set `"maxRepliesPerPost": 0` for everything Threads shows, or add `"profileUrls": ["@zuck"]` for a profile's latest posts.

### ⚙️ Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `postUrls` | array | — | Post URLs, e.g. `https://www.threads.com/@zuck/post/DeZtp-TkQHh` (`threads.net` and query strings accepted). Up to 200. |
| `profileUrls` | array | — | `https://www.threads.com/@zuck` or `@zuck`. Uses the profile's latest posts. Up to 20. |
| `maxRepliesPerPost` | integer | `200` | Reply rows per post (direct, nested and author thread). `0` = everything Threads shows (hard cap 5,000). |
| `maxPostsPerProfile` | integer | `3` | Latest posts per profile, 1–10 (the profile page lists a handful). |
| `sortOrder` | select | `TOP` | `TOP` or `RECENT`. Matters only when `maxRepliesPerPost` cuts the list. |
| `includeAuthorThread` | boolean | `true` | The post author's continuation posts as reply rows with `isAuthor: true`. |
| `proxyConfiguration` | proxy | Apify datacenter | Blocked or rate-limited requests are retried on a fresh IP. The session re-reads the post page first, so pagination continues where it stopped. |
| `feedback` | string | — | A note to the maintainers. Read by a human. |

### 🧱 Stable fields for automations

Reply rows have `recordType: "reply"`; the post has `recordType: "post"`; misses have `recordType: "status"`. Fields are **omitted, never `null`**, when Threads does not show them. New fields are only ever added.

| Field | Meaning |
|---|---|
| `recordType`, `code`, `url` | `reply` / `post`; Threads post code; its URL. |
| `rootPostCode`, `rootPostUrl` | The post the reply belongs to. |
| `authorUsername`, `authorName`, `authorUrl`, `authorId`, `authorVerified` | Who wrote it. `authorVerified` appears only when `true`. |
| `isAuthor` | `true` when the reply is by the root post's author. |
| `replyType` | `reply`, or `author_thread` for the author's own continuation posts. |
| `depth`, `parentCode`, `replyToUsername` | `1` = direct reply; `2+` = nested. `parentCode` is the post it answers. |
| `text` | Reply text (omitted for media-only replies). |
| `likeCount`, `replyCount`, `repostCount`, `quoteCount` | As shown on Threads. `likeCount` is omitted where the author hides it. |
| `timestamp`, `edited` | ISO 8601 UTC; `edited: true` when the text was edited. |
| `images`, `videos` | Media URLs (signed, expiring). |
| Status rows: `url`, `status`, `reason` | `NOT_FOUND`, `BLOCKED`, `ERROR` or `INVALID_URL`, and why. |

### 📦 Output example

Recorded 18 Oct 2026. The reply author is anonymized here; the actor returns the real public handle.

```json
{
  "recordType": "reply",
  "code": "DeZuMBkmOKg",
  "url": "https://www.threads.com/@example.user/post/DeZuMBkmOKg",
  "rootPostCode": "DeZtp-TkQHh",
  "rootPostUrl": "https://www.threads.com/@zuck/post/DeZtp-TkQHh",
  "authorUsername": "example.user",
  "authorUrl": "https://www.threads.com/@example.user",
  "authorId": "14722763243",
  "authorVerified": true,
  "isAuthor": false,
  "replyType": "reply",
  "depth": 1,
  "parentCode": "DeZtp-TkQHh",
  "replyToUsername": "zuck",
  "text": "Will it be integrated with Muse Charm?",
  "likeCount": 0,
  "replyCount": 0,
  "repostCount": 0,
  "quoteCount": 0,
  "timestamp": "2026-10-12T17:01:08Z"
}
```

The author's own continuation post:

```json
{ "recordType": "reply", "code": "DeZtp7KER52", "authorUsername": "zuck", "isAuthor": true, "replyType": "author_thread", "depth": 2, "parentCode": "DeZtrvAEfEr", "likeCount": 90, "replyCount": 11, "timestamp": "2026-10-12T16:56:28Z" }
```

A link that doesn't exist:

```json
{ "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)" }
```

### 🧠 Advanced usage

- 📈 **Sentiment and topic analysis:** feed `text` to an LLM or classifier and weight by `likeCount`.
- 🔗 **Rebuild the conversation tree:** join `parentCode` to `code`; `depth` gives the level.
- 🗂️ **Creator engagement:** filter `isAuthor: true` to see where the author joined the discussion.
- 🗺️ **Monitor a creator:** schedule `profileUrls: ["@handle"]` with `maxPostsPerProfile: 3` and diff on `code`.
- ✅ **Completion check:** read `RUN_SUMMARY`. It has `status` (`COMPLETE`, `PARTIAL`, `NO_RESULTS`, `BUDGET_LIMIT`, `TIME_LIMIT`, `STATE_SAVE_FAILED`, `PUSH_FAILED`, `INVALID_INPUT`, `NOT_CONFIGURED`), `posts`, `replies`, `charged` and `perPost[]`. Each `perPost[]` entry has `status`, `delivered`, `claimedReplies`, `reachableDirectReplies`, `truncatedChains`, `coverage`, `coverageNote` and `exhausted`.

### 🔌 Integrations

Export as JSON, CSV or Excel; push to Google Sheets; trigger from Make, Zapier or n8n; get a webhook when a run finishes; schedule with the Apify Scheduler.

### 💸 How much does it cost?

1,000 replies ≈ **$2.50**. The 433-reply test post (241 reachable reply rows plus the post) ≈ **$0.60**. 100 posts with 10 replies each ≈ **$2.60**. Platform usage is included, and there is no start fee.

### 💰 Pricing

| Event | Price | Covers |
|---|---|---|
| `reply` | $2.50 / 1,000 | One reply row (direct, nested or author thread) |
| `post` | $1.00 / 1,000 | One root post row |

Platform usage is included. Status rows are free, and nothing is charged for failed requests or replies Threads doesn't show. A run stops cleanly at your spending limit, with charges equal to rows delivered.

### ❓ FAQ

**Why is `coverage` below 1?** Threads' reply counter includes replies it doesn't show logged-out visitors (hidden, restricted or filtered ones). We report what was reachable rather than pad the number.

**Can I pass a reply's URL?** Yes. Every reply on Threads is a post with its own URL. You get that reply 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) a second time, so it gets no separate `post` row.

### 🤖 For AI agents & LLM apps

`architekture/threads-replies-scraper` returns replies to public Threads posts as deterministic, schema-stable JSON: one object per reply, plus one per post. Each object has the author handle and URL, text, like/reply/repost counts, ISO timestamp, the `isAuthor` flag and nesting (`depth`, `parentCode`). Invoke it from any agentic workflow via the Apify API or the Apify MCP server (`mcp.apify.com`) as a tool call. Its cost is bounded before it starts: $2.50 per 1,000 replies. `maxRepliesPerPost` caps each post, and a spending limit stops the run cleanly. Every post gets a machine-readable status and coverage ratio in `RUN_SUMMARY`, and misses come back as free `recordType: "status"` rows. Honest limits: logged-out visibility only (about half the replies on very large posts), no login, no search, no profile data.

Works out of the box with LangChain, LlamaIndex and AI coding agents — call it as a tool from Claude Code, Cursor, or any MCP client via `mcp.apify.com`.

### 🧰 More Architekture scrapers

- 🎬 **Social & video:** Threads Replies (you are here) · [YouTube](https://apify.com/architekture) · [Reddit](https://apify.com/architekture) · [Substack](https://apify.com/architekture)
- 🇪🇺 **Retail:** [Mercadona Spain](https://apify.com/architekture/mercadona-es-scraper) · [ALDI Ireland](https://apify.com/architekture/aldi-ie-scraper) · [Dunnes Stores Ireland](https://apify.com/architekture/dunnes-ie-scraper)

### 🙋 Support

Open an Issue on this actor's page; a human replies within a day.

### ⚖️ Legal compliance

This actor reads only what Threads shows logged-out visitors on public posts, without an account. Replies contain personal data (handles, names, text). You are responsible for having a lawful basis to process it (e.g. GDPR, CCPA), for Threads' and Meta's terms, and for how you store and use the data. Not affiliated with Threads or Meta.

### 📝 Changelog

- **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.

# Actor input Schema

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

Posts whose replies you want, e.g. https://www.threads.com/@zuck/post/DeZtp-TkQHh (threads.net links work too). Each post gives one root-post row plus one row per reply. Up to 200.

## `profileUrls` (type: `array`):

Profiles such as https://www.threads.com/@zuck or @zuck. The actor takes the latest posts shown on the profile (up to maxPostsPerProfile) and scrapes their replies. Up to 20.

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

Stop each post after this many reply rows (direct replies, their nested chain and the author's own thread posts). 0 = everything Threads shows logged-out visitors (up to 5,000).

## `maxPostsPerProfile` (type: `integer`):

How many of a profile's latest posts to scrape (the profile page lists a handful).

## `sortOrder` (type: `string`):

Matters when maxRepliesPerPost cuts the list. Both orders reach the same set of replies.

## `includeAuthorThread` (type: `boolean`):

The post author's continuation posts (labelled Author on Threads) as reply rows with isAuthor: true.

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

Apify datacenter proxy is the tested default. Blocked or rate-limited requests are retried on a fresh IP.

## `feedback` (type: `string`):

Tell the maintainers what you needed and did not get. Read by a human; does not change the output.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.threads.com/@zuck/post/DeZtp-TkQHh"
  ],
  "maxRepliesPerPost": 50,
  "maxPostsPerProfile": 3,
  "sortOrder": "TOP",
  "includeAuthorThread": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per reply plus one recordType: post row per post; misses add one free recordType: status row.

## `summary` (type: `string`):

RUN_SUMMARY: per-post status, delivered vs claimed replies and coverage.

# 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/DeZtp-TkQHh"
    ],
    "maxRepliesPerPost": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("architekture/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/DeZtp-TkQHh"],
    "maxRepliesPerPost": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("architekture/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/DeZtp-TkQHh"
  ],
  "maxRepliesPerPost": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call architekture/threads-replies-scraper --silent --output-dataset

```

## MCP server setup

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