# Threads Scraper $1/1k Posts Likes Replies Bio & Followers (`makework36/threads-scraper`) Actor

Extract Threads (Meta) profiles & posts: likes, replies, reposts, bio, followers, profile pic, post images. $1/1K. Perfect for social media analytics.

- **URL**: https://apify.com/makework36/threads-scraper.md
- **Developed by:** [deusex machine](https://apify.com/makework36) (community)
- **Categories:** Social media
- **Features:** Limited permissions
- **Stats:** 42 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

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 Scraper — Extract Posts, Profiles, Likes, Replies & Reposts from Meta Threads

> ⭐ **Useful?** [Leave a review](https://apify.com/makework36/threads-scraper/reviews) — it takes 10 seconds and is the single biggest thing that helps other social-media researchers find this Threads scraper.

A reliable **Threads scraper** for Meta's Threads platform that pulls posts, profile metadata, follower counts, engagement stats (likes, replies, reposts) and author handles from any public Threads profile. No Threads login, no Meta API token, no Instagram linking required — just clean JSON or CSV output. Built for social-listening teams, influencer-marketing platforms, brand-monitoring dashboards, content researchers, trend analysts, growth marketers and anyone doing Threads competitive analysis at scale.

### ✨ Why use this scraper

Given a list of [Threads](https://www.threads.net/) usernames (like `zuck`, `instagram`, `mosseri`, or any public handle) and an optional post cap, this scraper navigates each profile page, waits for lazy-loaded content, scrolls to pull the long tail of posts, and returns two kinds of records: a **profile record** for each account and a **post record** for each post it finds.

Every run pulls fresh data — engagement counts change by the minute on active accounts, so the scraper hits Threads live each time. Export the dataset as **JSON**, **CSV**, **Excel**, or **XML** directly from the Apify console or via the Apify API.

Threads doesn't have a public API for developers, and Meta hasn't exposed Threads data through the Instagram Graph API either. That leaves three options: build your own Puppeteer stack (expensive to maintain against frequent DOM changes), pay for an enterprise social-listening suite, or use this scraper. This Threads scraper handles the browser stealth setup, proxy rotation, scroll automation, DOM parsing and multiple fallback selectors so you don't have to.

### 📤 Output fields

#### Profile records (`type: "profile"`)

| Field | Type | Description |
|-------|------|-------------|
| `username` | string | Threads handle without the `@` |
| `displayName` | string | Profile display name (e.g. `"Mark Zuckerberg"`) |
| `followers` | string | Follower count in human-readable format (`"5.4M"`, `"970K"`) |
| `following` | string|null | Following count (Threads exposes this only for some profiles) |
| `bio` | string|null | Profile bio text |
| `verified` | boolean | Whether the profile has a verified badge |
| `profilePicUrl` | string|null | URL of the profile picture (CDN) |
| `externalUrl` | string|null | External link in profile bio (if any) |
| `url` | string | Canonical profile URL on threads.com |
| `type` | string | Always `"profile"` for profile records |
| `scrapedAt` | string | ISO 8601 timestamp |

#### Post records (`type: "post"`)

| Field | Type | Description |
|-------|------|-------------|
| `username` | string | Author's Threads handle |
| `profileUrl` | string | Direct link to the author's profile |
| `postUrl` | string|null | Permalink to the individual post |
| `text` | string | Post body (truncated to 2,000 characters) |
| `date` | string | Post date — relative (`"2h"`, `"3d"`) or absolute (`"03/15/26"`) |
| `likes` | string|null | Like count (`"7.3K"`, `"1.4K"`, `"190"`) |
| `replies` | string|null | Reply count |
| `reposts` | string|null | Repost count |
| `shares` | string|null | Share count (when available) |
| `imageUrls` | string\[] | Image URLs attached to the post |
| `type` | string | Always `"post"` for post records |
| `scrapedAt` | string | ISO 8601 timestamp |

### 🎯 Use cases

- **Brand monitoring on Threads** — track what your brand's own accounts publish and how audiences engage post-by-post.
- **Influencer discovery and vetting** — compare engagement rates (likes/replies per post) across a list of creators before partnership.
- **Competitor content analysis** — snapshot your top three competitors' Threads feeds weekly to spot their tentpole content and posting cadence.
- **Trend detection** — aggregate posts from 50+ industry thought leaders and surface the topics gaining momentum.
- **Social listening for PR and crisis response** — pre-configure a watchlist of public figures and sync their Threads posts into Slack.
- **Content idea generation** — feed high-engagement Threads posts into a ChatGPT prompt to brainstorm variations for your own channel.
- **Academic research on Meta's newest social platform** — build reproducible datasets for studies on post format evolution, network effects, and migration from X/Twitter.
- **Dataset enrichment for LLM fine-tuning** — curate Threads content as conversational training data (be mindful of Meta's terms).

### 🚀 How to use

#### Scrape posts from a single profile

```json
{
  "profiles": ["zuck"],
  "maxPosts": 30
}
```

#### Scrape multiple Threads profiles in one run

```json
{
  "profiles": ["zuck", "instagram", "mosseri", "threads"],
  "maxPosts": 20
}
```

#### Deep-scrape a single profile

```json
{
  "profiles": ["maboroshi"],
  "maxPosts": 100
}
```

Note: Threads profiles vary wildly in how many posts their DOM exposes. Accounts with heavy reposts or quote-posts may hit a natural cap below `maxPosts`.

### 📥 Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `profiles` | array<string> | — | Threads usernames to scrape. Don't include the `@` prefix. |
| `maxPosts` | integer | `20` | Max posts to collect per profile (1–200). |

### 📋 Output example

#### Profile record

```json
{
  "type": "profile",
  "username": "zuck",
  "displayName": "Mark Zuckerberg",
  "followers": "14.2M",
  "bio": null,
  "url": "https://www.threads.net/@zuck",
  "scrapedAt": "2026-04-22T10:30:00.000Z"
}
```

#### Post record

```json
{
  "type": "post",
  "username": "zuck",
  "profileUrl": "https://www.threads.net/@zuck",
  "text": "Threads just hit 200 million monthly actives. Grateful for this community.",
  "date": "03/12/25",
  "likes": "142538",
  "replies": "8924",
  "reposts": "3201",
  "scrapedAt": "2026-04-22T10:30:00.000Z"
}
```

Export the full dataset as CSV directly from the Apify console, or programmatically via the Apify API.

### 💻 Code examples

#### From the Apify API (curl)

```bash
curl -X POST 'https://api.apify.com/v2/acts/makework36~threads-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "profiles": ["zuck", "mosseri"],
    "maxPosts": 25
  }'
```

#### From Python (apify-client)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("makework36/threads-scraper").call(run_input={
    "profiles": ["zuck", "instagram", "threads"],
    "maxPosts": 30,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["type"] == "post":
        print(item["username"], "→", item["text"][:80], "|", item["likes"], "likes")
```

#### From Node.js (apify-client)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('makework36/threads-scraper').call({
  profiles: ['maboroshi', 'polygondotio'],
  maxPosts: 40,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const posts = items.filter((i) => i.type === 'post');
console.table(posts.map((p) => ({
  user: p.username,
  likes: p.likes,
  replies: p.replies,
  text: p.text.slice(0, 60),
})));
```

#### Export to CSV

From the console run page → *Export* → *CSV*. Or via API:

```
https://api.apify.com/v2/datasets/DATASET_ID/items?format=csv&token=YOUR_TOKEN
```

### ⚡ Performance

- **~30–60 seconds per profile** depending on `maxPosts`
- Uses Puppeteer with the stealth plugin — heavier compute than pure HTTP scrapers, but necessary to render Threads' client-side React app
- **Concurrency = 1** by design. Running multiple profiles in parallel triggers Threads' bot-detection layer; serial execution is the reliable path.
- 5 retries per request with exponential backoff
- Apify Proxy rotates residential IPs automatically

### 📊 Comparison

Threads is a young platform and dedicated scrapers are few. Here's how ours stacks up against the closest alternatives.

| Feature | This Threads scraper | Generic "Meta scraper" with residential proxy | Custom Puppeteer stack (DIY) | Social-listening enterprise suite |
|---------|----------------------|-----------------------------------------------|------------------------------|-----------------------------------|
| Fields per post | **6+ (text, date, likes, replies, reposts)** | 3–4 | Depends on you | 10+ but behind paywall |
| Fields per profile | **6** (displayName, followers, bio, URL) | 2–3 | Depends | 6+ |
| Stealth plugin / bot evasion | **Yes** | Sometimes | Manual setup | N/A (licensed API) |
| Infinite scroll support | **Yes** | Partial | DIY | Yes |
| Residential proxy rotation | **Yes** (via Apify Proxy) | Yes | Buy separately | Yes |
| Handles Threads' DOM changes | **Yes** (maintained) | Often broken | You fix it | Yes |
| Typical cost per 1K posts | **~$2.00–3.00** | $3–$5 | Hosting + dev time | $500+/month |
| Setup time | **30 seconds** | Minutes | Hours to days | Weeks (sales cycle) |

The honest take: if you already operate a Puppeteer + proxy stack, you can build this yourself — but maintaining DOM parsers against Meta's weekly frontend changes is a surprising amount of work. If Threads data is a side-need, this scraper saves you the plumbing.

### 💵 Pricing

Pay-per-result model:

- **~$0.003 per post + profile record** (exact pricing in the actor console)
- Apify gives every new user a $5 free trial → ~1,500 records to evaluate the scraper
- No subscription, no minimum, no egress fees

### ❓ FAQ

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

No. This Threads scraper reads publicly visible profile pages — the same view any unauthenticated browser visitor sees. No login, no Instagram linking, no Meta app review.

#### Is scraping Threads legal?

This actor accesses only public profile pages. Meta's terms restrict automated access; most jurisdictions treat public-page scraping as permissible for research, journalism and market analysis. For commercial products, consult legal counsel and minimize personal data retention under [GDPR](https://gdpr.eu/).

#### Can I scrape by hashtag or search query?

Not in v1. The scraper is profile-driven: you provide usernames and it collects their posts. Hashtag and search support is on the roadmap — leave a review requesting it to bump priority.

#### Can I scrape replies to a post?

Only top-level posts are extracted. Individual reply threads aren't supported yet. The `replies` field tells you how many replies a post has.

#### Why is the scraper limited to one concurrent browser?

Running Puppeteer with concurrency > 1 against Threads consistently triggers Meta's bot-detection heuristics and leads to empty results across the whole batch. Running serially with the stealth plugin has a much higher success rate.

#### Does Threads enforce rate limits?

Yes, implicitly. Scraping 20+ profiles in rapid succession can trigger a challenge page. The scraper's built-in pacing and 5-retry logic handle most cases, but for very large runs (100+ profiles) consider splitting into several scheduled runs spaced 10–15 minutes apart.

#### Can I scrape posts with media attachments (images, videos)?

The scraper captures post text and engagement metrics. Media URL extraction is on the roadmap — for now, you can visit the post's individual URL manually if needed.

#### Does this work for non-English Threads accounts?

Yes. The scraper is locale-agnostic — it parses DOM structure, not translated labels. Profiles and posts in Spanish, Portuguese, Japanese, Korean, Arabic and other scripts all work.

#### Can I scrape multiple languages in one run?

Yes. Mix any public handles from any language into the `profiles` array.

### 📝 Changelog

- **v1.1** (2026-04-22) — Full SEO rewrite, added Python / Node / curl examples, anonymized comparison table, advanced usage patterns, categorized field list.
- **v1.0** (2026-03-20) — Initial release with profile + post extraction, stealth Puppeteer, residential-proxy rotation and fallback text parsers.

### 🔗 Related actors

- [Facebook Comments Scraper](https://apify.com/makework36/facebook-comments-scraper) — extract comments and reactions from public Facebook posts
- [Reddit Scraper](https://apify.com/makework36/reddit-scraper) — threads, comments and karma from Reddit
- [Fast Airbnb Price Scraper](https://apify.com/makework36/fast-airbnb-price-scraper) — Airbnb listings, prices, ratings and GPS
- [VRBO Scraper](https://apify.com/makework36/vrbo-scraper) — vacation-rental marketplace data
- [Website Email & Contact Finder](https://apify.com/makework36/email-finder-scraper) — emails, phones and socials from company websites

# Changelog

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

# Actor input Schema

## `profiles` (type: `array`):

Threads usernames (e.g. zuck, instagram)

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

Maximum posts per profile

## Actor input object example

```json
{
  "profiles": [
    "zuck"
  ],
  "maxPosts": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

All scraped items in the default dataset (JSON).

## `csv` (type: `string`):

Default dataset formatted as CSV for spreadsheets (Google Sheets, Excel).

# 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 = {
    "profiles": [
        "zuck"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("makework36/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 = { "profiles": ["zuck"] }

# Run the Actor and wait for it to finish
run = client.actor("makework36/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 '{
  "profiles": [
    "zuck"
  ]
}' |
apify call makework36/threads-scraper --silent --output-dataset

```

## MCP server setup

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