# Threads Scraper: Posts, Views, Replies, Profiles & Search (`quarra/threads-scraper`) Actor

Scrape public Threads posts, replies and profiles without login. Full post history with view counts on every post, keyword and account search, language and engagement filters, and a watch mode that returns only new posts. Errors and filtered rows are not charged.

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

## Pricing

from $1.75 / 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 Scraper** returns posts (text, likes, replies, reposts, quotes, **view count**, media, language), replies,
profiles (followers, bio, links, creator stats) and keyword results from **Meta Threads** (threads.com) **without login or
cookies**, at **$2.50 per 1,000 posts, replies or search results and $5 per 1,000 profiles**: the **full post history**
of any public account, every reply Threads serves, and posts and accounts found by keyword. Give it usernames, post URLs
or keywords, and download JSON, CSV or Excel, or read the results through the Apify API.

Each input either returns its data or gets a free `error` row that says why. You pay per result, and errors,
duplicates and rows removed by your filters are not charged.

### What you get

- **Full post history** back to an account's first post: in our tests, 226 posts of @zuck, back to July 2023, in 23
  seconds.
- **View counts on every post and search result**, at no extra charge, plus `engagementPerView`, `engagementRate` and
  `viewsPerHour` to rank posts by how they did for their reach.
- **Replies** to any post, newest or top first, with the coverage per post (Threads hides some replies from
  logged-out visitors; the run tells you how many you got against the counter).
- **Profiles and creator stats**: followers, bio, contact links and e-mails the creator made public in the bio, median
  engagement of recent posts, posting rhythm.
- **Only new posts on a schedule**: name a watch (`watchName`): the first run delivers a baseline, then each run returns and charges only what is new.

### How to scrape Threads

1. Pick a mode: `posts`, `postReplies`, `profiles`, `search`, `accountSearch`, `postDetails`, `accountReplies` or
   `accountReposts`.
2. Add usernames, post URLs (share links work) or keywords, and a `maxItems` per input (0 = no limit).
3. Optionally filter by language, likes, replies, views or followers. Filtered rows are not charged.
4. Run, then export the dataset or call it from the API, Make, Zapier, n8n or an AI agent through MCP.
5. To monitor accounts or keywords, set a `watchName` and add a schedule in Apify Console.

### Input examples

The 200 latest posts of two accounts:

```json
{ "mode": "posts", "usernames": ["zuck", "https://www.threads.com/@mosseri"], "maxItems": 200 }
```

All replies to a post:

```json
{ "mode": "postReplies", "postUrls": ["https://www.threads.com/@zuck/post/Dd1MqfcG0aH"], "maxItems": 0 }
```

English posts about a topic, with some traction:

```json
{ "mode": "search", "searchQueries": ["matcha", "#latteart"], "languages": ["en"], "minLikes": 5, "maxItems": 0 }
```

Coffee creators with at least 5,000 followers and their engagement:

```json
{ "mode": "accountSearch", "searchQueries": ["coffee roaster"], "minFollowers": 5000, "creatorStats": true }
```

New posts of two accounts, every day (schedule this input):

```json
{ "mode": "posts", "usernames": ["natgeo", "nasa"], "watchName": "space-and-nature", "maxItems": 50 }
```

### Output example

A real post (September 2026), with some fields left out:

```json
{
  "type": "post",
  "id": "3992880566219418771",
  "code": "Ddpj7hEEayT",
  "url": "https://www.threads.com/@zuck/post/Ddpj7hEEayT",
  "author": {
    "username": "zuck",
    "fullName": "Mark Zuckerberg",
    "isVerified": true,
    "followerCount": 5746814
  },
  "text": "Muse, your personal agent, now has voice and real-time video. ...",
  "createdAt": "2026-09-24T00:08:05Z",
  "likeCount": 1338,
  "replyCount": 117,
  "repostCount": 57,
  "quoteCount": 19,
  "shareCount": 52,
  "viewCount": 92115,
  "engagementCount": 1531,
  "engagementPerView": 0.016621,
  "engagementRate": 0.000266,
  "viewsPerHour": 302.51,
  "mediaType": "video",
  "mediaCount": 1
}
```

Every run also writes an `OUTPUT` record: results per input, the reason for each failed input, reply coverage per
post, how many rows each filter removed, and the number of charged events.

### What we measured

Measured between October 4 and 7, 2026, against the page threads.com shows a logged-out visitor.

- **Accuracy**: on 20 posts of @zuck, we compared seven values (likes, replies, reposts, quotes, shares, views, date)
  of three posts with the public page a minute after the run: **21 of 21 identical** (on Apify).
- **Speed**: on Apify, 20 posts with view counts in 9.4 to 13.1 seconds of run time, and 1,805 replies to a large post
  in 87 seconds.
- **Search reach**: Threads shows a logged-out visitor about 20 posts per wording. The Actor also searches close
  wordings and hashtags and merges them without duplicates: on "AI agents", 104 and 120 unique posts in two runs of
  our tests (October 6), against 31 and 33 for the exact wording alone.
- **Long posts**: a 2,200-character post folded by Threads into an attachment comes out complete, in `text` and in
  `attachmentText`.

### Compared with the most used Threads scraper in the top search results

The most used of the top Threads scraper search results on the Store (by monthly users, October 9, 2026) is a solid tool with more modes for
reposts and replies. Here is how the two differ, from its public Store page and README on October 9, 2026 and from
our runs of both on Apify on October 5 and 6, 2026. Other scrapers update often, so these figures are dated.

| | This Actor | Most used of the top search results |
|---|---|---|
| Price per post, Free plan | $2.50 / 1,000 | $2.50 / 1,000 |
| Run start on the Free plan | $0.005 (512 MB) | $0.08 (4 GB default, $0.02 per GB) |
| Run start on paid plans | $0.005 | $0.02 |
| View counts | on every post and search result | "views when available" |
| Only new items on scheduled runs | built in (`watchName`), already delivered items not charged again | scheduled searches sorted by recent |
| Language filter | detected on every post, every mode | preferred result language for search (beta) |
| 20 posts of one account, run time | 9.4 to 13.1 s | 14 and 19 s |

For 20 posts on the Free plan, that is **$0.055 here against $0.13**. A watch checked every hour that finds nothing
new costs $3.60 a month in run starts.

### How much does it cost to scrape Threads?

You pay per result, with lower prices on the Scale and Business plans:

| Event, per 1,000 | Free and Starter | Scale | Business and above |
|---|---|---|---|
| Post, view count included (account posts, replies tab, reposts tab, post by URL) | $2.50 | $2.00 | $1.75 |
| Search result, view count included | $2.50 | $2.00 | $1.75 |
| Reply to a post | $2.50 | $2.00 | $1.75 |
| Profile (by username or by account search), creator stats included | $5.00 | $4.00 | $3.50 |
| Actor start, per run | $0.005 | $0.005 | $0.005 |

Platform costs are included. Errors, duplicates, rows removed by a filter, private accounts and items already
delivered to a watch are not charged. You can set a maximum cost per run in the run options; the Actor stops
cleanly there and tells you. With the $5 of free monthly credit of the Apify Free plan, that is about 2,000 posts
with their view counts.

### Use cases

- **Brand and topic monitoring**: scheduled keyword searches that return only new posts.
- **Competitor and public figure tracking**: new posts every day, with engagement per view.
- **Audience research**: the replies to a product launch or an announcement, for sentiment analysis.
- **Creator discovery**: follower count, engagement rate, posting rhythm and the contact e-mails creators made public in the bio, by topic.
- **Research and AI datasets**: topic datasets filtered by language, for newsrooms, academics and AI models.
- **Automation**: dashboards, warehouses and AI agents through the Apify API, schedules, integrations and MCP.

### Limits

- Threads does not serve every reply it counts to a logged-out visitor (hidden, restricted or deleted ones). We
  measured 72% of the counter on a post with 2,502 replies. The Actor collects every reply Threads serves and reports
  the coverage per post.
- Keyword search is limited by Threads for logged-out visitors: no pagination, no date filter. Expanding the wording
  multiplies the results without making them exhaustive. For large studies, collect the accounts that matter with
  the `posts` mode.
- Account search returns up to about 100 accounts per keyword.
- Follower and following lists need a login, and this Actor does not log in. Private accounts are not scraped.
- A run takes up to 1,000 accounts, posts or keywords; split longer lists.

### FAQ

#### Is there an official Threads API?

Yes. Meta's Threads API lets an approved app publish, search public posts by keyword (up to 2,200 queries a day) and
look up public profiles, with app review and access tokens, and it returns no view counts in its documented search
fields. This Actor reads the public pages any logged-out visitor sees: no app, no token, no account, and view counts on
every post.

#### Is it legal to scrape Threads?

The Actor collects public data that anyone can see without logging in, and does not use an account. In January 2024,
a US federal district court held that Facebook's and Instagram's terms did not bar Bright Data's logged-out scraping of
public data (Meta v. Bright Data, N.D. Cal.); that ruling does not decide your case.
Meta's terms and privacy law apply to how you use the data: personal data is protected by the GDPR in the EU and by similar laws elsewhere.
Collect what you need for a legitimate purpose, and ask a lawyer if you are unsure.

#### Do I need a Threads or Instagram account or cookies?

No account and no cookies. Platform costs are included in the price.

#### Can I get only the new posts every day?

Yes. Set `watchName` and schedule the Actor. The first run delivers and charges a baseline (what Threads shows today); later runs return and charge only
what is new for that watch. A target added later gets its own baseline, charged as usual. Mode `profiles` has no
baseline: the first run returns every profile, later runs only the profiles that changed. A run with nothing new costs only the $0.005 start.

#### My run succeeded but returned no data. Why?

Every input that gave nothing has an `error` row and a line in the run status: the account does not exist or is
private, the keyword has no result, or your filters removed everything. You pay only the run start. A run is marked
failed only when Threads or the Actor failed, so the success rate on this page measures the scraper, not the inputs.

#### Can an AI agent use it?

Yes. Every input field says what it does and whether it changes the cost, common field names from other scrapers
(`limit`, `maxResults`, `query`, `urls`) are understood, unknown fields are reported instead of ignored, and the output
fields are typed in the dataset schema.

#### Something broke or a field is missing?

Open an issue in the Issues tab with the link to your run. We reply within two business days.

### More data tools from Quarra

| Actor | What it does |
|---|---|
| [Reddit Scraper](https://apify.com/quarra/reddit-scraper) | Posts, complete comment trees, search and users; threads as Markdown for LLMs |
| [Google Trends Scraper](https://apify.com/quarra/google-trends-scraper) | Interest over time, by region, related queries and the full Trending now list |

# Actor input Schema

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

posts = an account's posts (full history); profiles = profile by username; accountReplies / accountReposts = an account's Replies / Reposts tab; postDetails = posts by URL; postReplies = every reply to a post; search = posts by keyword; accountSearch = accounts matching a keyword. Each mode reads one list: usernames, postUrls or searchQueries. If left out, the mode follows the list you fill (usernames -> posts, postUrls -> postDetails, searchQueries -> search).

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

Modes posts, profiles, accountReplies, accountReposts. Any form works: zuck, @zuck, https://www.threads.com/@zuck, threads.com/zuck, a threads.net URL, an instagram.com/zuck URL (same username), a post URL (its author is used) or a threads.com/share/… link. Up to 1,000 per run.

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

Modes postDetails and postReplies. Any post link works: https://www.threads.com/@zuck/post/Dd1MqfcG0aH (with /media or ?xmt=… too), threads.net, /t/CODE, share links from the app (https://www.threads.com/share/…), the bare code Dd1MqfcG0aH, or the numeric post id (the id field of the output). Up to 1,000 per run.

## `searchQueries` (type: `array`):

Modes search and accountSearch. A word, a phrase or a #hashtag (e.g. matcha, AI agents, #nba), or a threads.com/search?q=… URL. Quotes and a leading @ are removed (Threads search has no operators); at least two letters or digits. Without login Threads shows about 20 posts per wording and search type, with no pagination and no date filter; expandQueries finds more by searching several wordings. Up to 1,000 per run.

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

Exact cap for EACH account, post or keyword (not per run); 0 = no limit (full history, every reply Threads serves). Left empty: 100. With watchName it caps the NEW results of each run. You pay only for the rows you receive. limit, maxResults, resultsLimit and count are read as maxItems.

## `since` (type: `string`):

Modes posts, accountReplies, accountReposts: stop at items older than this date (YYYY-MM-DD, UTC; not in the future). Pinned posts never stop the collection.

## `until` (type: `string`):

Modes posts, accountReplies, accountReposts: skip items published after this date (YYYY-MM-DD, UTC, the whole day included). With since, a date window.

## `languages` (type: `array`):

Keep only posts in these languages (ISO 639-1: en, es, fr, ja, zh, ko, pt…; three-letter codes, English names and "en,fr" are accepted; jp, cn, kr are read as ja, zh, ko). Uses the label Threads sends, otherwise a language detector on the text (field languageGuess). About 96% of real English posts are kept, under 0.4% of other languages let through. Posts with fewer than two words cannot be judged and are removed. Removed posts are not charged.

## `minLikes` (type: `integer`):

Keep only posts with at least this many likes (e.g. 1 removes the zero-engagement posts keyword search returns). Removed posts are not charged.

## `minReplies` (type: `integer`):

Keep only posts with at least this many replies. Removed posts are not charged.

## `minViews` (type: `integer`):

Keep only posts with at least this many views (turns view counts on). Posts whose view count Threads hides are removed. Not available for replies to a post. Removed posts are not charged. Each post needs a page read for its view count: a target stops after 100 posts in a row under the threshold, and a run stops when reading pages for posts that end up removed has cost more than the results can pay for (a less selective threshold, or other targets, avoids it).

## `minFollowers` (type: `integer`):

Modes profiles and accountSearch: keep only accounts with at least this many followers (e.g. 10000 for creators with reach). Removed accounts are not charged.

## `watchName` (type: `string`):

For scheduled runs (e.g. brand-mentions). The first run delivers and charges a baseline (what Threads shows today); later runs return and charge only what is new. A target added later gets its own baseline, charged as usual. Mode profiles has no baseline: the first run returns every profile, later runs only those that changed (bio, links, badge, privacy, followers moved 1% and 5+). One name per schedule.

## `searchMode` (type: `string`):

Mode search. all = the three result types of the site merged (Top, Popular, Topic tags), the most results. top = the Top tab (fresh on active topics); popular = all-time popular; tags = topic tags.

## `expandQueries` (type: `boolean`):

Mode search. On: each keyword is also searched in singular/plural, as one joined word and as a hashtag (AI agents -> AI agent, aiagents, #aiagents), then merged without duplicates. Measured on AI agents: 104 and 120 unique posts in two runs, against 31 and 33 for the exact wording. Off: exact text only. More searches, same price per result.

## `strictSearch` (type: `boolean`):

Mode search: keep only posts whose text contains every word of the keyword or of one of its expanded forms (case-insensitive, # and @ ignored). Threads also returns loosely related posts; removed ones are not charged.

## `replySort` (type: `string`):

Mode postReplies. RECENT (newest first) returns the longest list and is the one watchName follows over time; TOP follows the order of the site; ALL merges both without duplicates (about 1% more).

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

Mode postReplies: also return replies to replies that Threads shows in each thread (depth 2 and more).

## `includeViewCount` (type: `boolean`):

Adds the view count of every post (account posts, posts by URL, search results) and the per-view metrics. Included in the post price. Not for replies to a post. Turn off only for the fastest run.

## `creatorStats` (type: `boolean`):

Modes profiles and accountSearch: adds creatorStats from the latest posts on the account's first page (up to 15, pinned posts and reposts left out): median likes, replies, reposts and engagement, median engagement rate (per follower), posts per week, last post date. Included in the profile price; one extra request per account.

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

Keep the default (automatic). Costs are included in the price.

## Actor input object example

```json
{
  "mode": "posts",
  "usernames": [
    "zuck",
    "@nasa"
  ],
  "postUrls": [
    "https://www.threads.com/@zuck/post/Dd1MqfcG0aH"
  ],
  "searchQueries": [
    "matcha",
    "AI agents"
  ],
  "maxItems": 50,
  "since": "2026-09-01",
  "until": "2026-09-30",
  "languages": [
    "en"
  ],
  "minLikes": 10,
  "minReplies": 2,
  "minViews": 1000,
  "minFollowers": 10000,
  "watchName": "competitor-posts",
  "searchMode": "all",
  "expandQueries": true,
  "strictSearch": false,
  "replySort": "RECENT",
  "includeNestedReplies": false,
  "includeViewCount": true,
  "creatorStats": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Dataset items: posts, replies or profiles, one per row, same fields in every mode.

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

OUTPUT record: per-input status and errors, reply coverage, new vs already seen (watchName), removed by filters, charged events.

# 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": "posts",
    "usernames": [
        "zuck"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("quarra/threads-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": "posts",
    "usernames": ["zuck"],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("quarra/threads-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": "posts",
  "usernames": [
    "zuck"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call quarra/threads-scraper --silent --output-dataset

```

## MCP server setup

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