# Threads Scraper (Profiles, Posts, Search) (`juliob.rangel/threads-scraper-fast`) Actor

Get Threads posts from any public profile or keyword search, without login: text, likes, replies, reposts, quotes, date, images and author, plus the profile's followers and bio. Export to Excel, CSV or JSON.

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

## Pricing

from $1.40 / 1,000 post scrapeds

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 (Profiles, Posts, Search)

Threads Scraper gets posts from public Threads profiles and keyword searches, with no login and no cookies: text, likes, replies, reposts, quotes, shares, date, images, video and author. Profile runs also return the account's followers and bio. It is made for social media managers, marketers, brand monitoring and researchers who need a Threads scraper to export Threads posts to Excel, CSV or JSON, or to track what people say about a topic on Meta's Threads app.

### What does Threads Scraper do?

You can use two kinds of input, alone or together:

- **Profiles**: a username such as `zuck`, `@mosseri`, or a profile link such as `https://www.threads.com/@mosseri` (old `threads.net` links work too). The scraper returns the latest posts of that profile, plus the profile's follower count, bio and full name on each row.
- **Search keywords**: words, phrases or hashtags such as `AI agents`. The scraper returns the top posts, the recent posts, or both, for each keyword.

Threads shows a limited first page of posts to visitors who are not logged in, and that page is what the scraper reads: the latest posts of a profile, and the first page of top and recent results of a search. Each post becomes one row with its text, engagement counts, date, media type, first image or video link and author details.

On profile runs, only posts written by that profile are kept, so the table stays clean.

### What data can you extract?

| Field | What it means | Example |
|---|---|---|
| `source` | `profile` or `search` | `profile` |
| `input` | The username or keyword the post came from | `zuck` |
| `postId` | Threads post ID | `3996155940894885511` |
| `url` | Link to the post | `https://www.threads.com/@zuck/post/Dd1MqfcG0aH` |
| `text` | Post text | `We believe superintelligence will create…` |
| `likes` | Number of likes | `2698` |
| `replies` | Number of direct replies | `2619` |
| `reposts` | Number of reposts | `170` |
| `quotes` | Number of quote posts | `156` |
| `shares` | Number of shares | `179` |
| `postedAt` | Post date (ISO 8601) | `2026-09-28T12:35:32.000Z` |
| `isReply` | `true` when the post is a reply to another post | `false` |
| `mediaType` | `text`, `image`, `video` or `carousel` | `carousel` |
| `imageUrl` | First image of the post (or of the carousel) | `https://scontent-ord5-1.cdninstagram.com/…` |
| `videoUrl` | Video link for video posts | `null` |
| `username` | Author's username | `zuck` |
| `authorName` | Author's display name | `Mark Zuckerberg` |
| `authorVerified` | `true` when the author has the verified badge | `true` |
| `authorPic` | Author's profile picture URL | `https://scontent-ord5-2.cdninstagram.com/…` |
| `followers` | Follower count of the profile (profile rows only) | `5745159` |
| `bio` | Profile bio (profile rows only) | `Mostly superintelligence and MMA takes` |
| `authorFullName` | Profile full name (profile rows only) | `Mark Zuckerberg` |
| `scrapedAt` | When the post was scraped (ISO 8601) | `2026-10-10T20:21:05.367Z` |
| `error` | Only on error rows: why no posts came back | `Private profile` |
| `profile` | Only on some error rows: the profile details that were found (username, fullName, followers, bio, isVerified, isPrivate, profilePic, profileUrl) | `{"username": "…", "isPrivate": true, …}` |

Search rows do not have `followers`, `bio` or `authorFullName`; use `username` to look up authors with a profile run.

### How to use Threads Scraper

1. Open Threads Scraper in Apify Console.
2. Add usernames or profile links to **Profiles**, one per line. Clear the list if you only want a search.
3. Add words or hashtags to **Search keywords**. Clear the list if you only want profiles.
4. For searches, choose **Search results**: top and recent, top only, or recent only.
5. Set **Max posts per profile or keyword** (default 50).
6. Click **Start** and wait for the run to finish.
7. Open the **Output** tab and export the posts as JSON, CSV, Excel or HTML.

To monitor a brand or topic, save the input as a task and schedule it daily.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `usernames` | list of text | `["zuck"]` | Threads usernames or profile URLs, for example `zuck` or `https://www.threads.com/@mosseri`. Returns the profile's latest posts with followers and bio. |
| `searchQueries` | list of text | empty (the form shows `apify` as an example) | Keywords or hashtags to search on Threads, for example `AI agents`. |
| `searchMode` | text | `both` | Which search results to read: `both` (top and recent), `top` or `recent`. |
| `maxPostsPerSource` | integer | `50` | Maximum posts for each profile or keyword, from 1 to 100. Threads shows about 10 to 25 posts per page without login, so you usually get fewer. |
| `proxy` | object | `{ "useApifyProxy": true }` | Apify Proxy settings. The default works for most runs. |

Example input for profiles and a search:

```json
{
  "usernames": ["zuck", "https://www.threads.com/@mosseri"],
  "searchQueries": ["AI agents"],
  "searchMode": "both",
  "maxPostsPerSource": 50,
  "proxy": { "useApifyProxy": true }
}
```

Note for API users: `usernames` has the default `["zuck"]`, so if you only want a search, send `"usernames": []`. `searchQueries` is empty unless you send it. For example, a search-only run:

```json
{
  "usernames": [],
  "searchQueries": ["AI agents"]
}
```

### Output example

One real post from a recent profile run (the picture link is trimmed):

```json
{
  "source": "profile",
  "input": "zuck",
  "postId": "3996155940894885511",
  "url": "https://www.threads.com/@zuck/post/Dd1MqfcG0aH",
  "text": "We believe superintelligence will create significant new opportunities for all people and businesses. Meta already serves billions of people at scale and helps hundreds of millions of businesses reach customers…",
  "likes": 2698,
  "replies": 2619,
  "reposts": 170,
  "quotes": 156,
  "shares": 179,
  "postedAt": "2026-09-28T12:35:32.000Z",
  "isReply": false,
  "mediaType": "text",
  "imageUrl": null,
  "videoUrl": null,
  "username": "zuck",
  "authorName": "Mark Zuckerberg",
  "authorVerified": true,
  "authorPic": "https://scontent-ord5-2.cdninstagram.com/v/t51.82787-19/825322135_17989325280103224_1252773933700107438_n.jpg…",
  "followers": 5745159,
  "bio": "Mostly superintelligence and MMA takes",
  "authorFullName": "Mark Zuckerberg",
  "scrapedAt": "2026-10-10T20:21:05.367Z"
}
```

### How much does it cost?

Threads Scraper uses pay-per-event pricing. You pay **$2.00 per 1,000 posts** ($0.002 per post) on the Free plan. Apify platform usage is included in the price, and the follower and bio data on profile rows does not cost extra.

| Plan | Price per 1,000 posts |
|---|---|
| Free | $2.00 |
| Bronze (-10%) | $1.80 |
| Silver (-20%) | $1.60 |
| Gold and higher (-30%) | $1.40 |

Worked examples on the Free plan:

- 10 posts from one profile = **$0.02**
- 2,000 posts from a list of creators = **$4.00**
- 10,000 posts from daily brand searches over a few months = **$20.00**

What you are not charged for:

- Error rows: profiles or searches that could not be loaded, private profiles and sources with no posts.
- Posts by other accounts that appear on a profile page (they are filtered out).
- Duplicate posts: when top and recent results share a post, it is returned once for that keyword.

### Use cases

- **Brand monitoring**: search your brand or product name every day and collect what people post about it.
- **Competitor tracking**: follow the latest posts and engagement of competing brands and founders.
- **Influencer research**: compare likes, replies and reposts of creators before a campaign, with followers on every profile row.
- **Trend and topic research**: search hashtags or phrases and see the top and recent posts about them.
- **Content ideas**: find the posts with the most replies and quotes in your niche.
- **Sentiment analysis**: send post text to an AI model or a spreadsheet for tagging.
- **Reporting**: track your own account's follower count and post engagement over time.

### Tips and limits

- **About 10 to 25 posts per page**: without login, Threads shows one page of posts. The scraper reads one page per profile and one page per search mode, so a profile usually gives 10 to 25 posts and a search with `both` can give up to about twice that. In the run used for the example above, the profile `zuck` returned 10 posts and the search `apify` returned 20. A higher limit does not load older posts.
- **Type usernames as they appear in the profile link** (in lowercase, like `zuck`). Posts are matched to the profile by exact username.
- **Replies in threads**: when a creator writes a chain of posts, the follow-up posts have `isReply: true`. Filter on `isReply` if you only want the first post of each chain.
- **Media**: `imageUrl` is the first image only (the first slide for carousels), and `videoUrl` is one video link. Media links point to Meta's servers and can expire, so download them soon if you need them.
- **Private profiles** return an error row and no posts. When Threads still shows the profile details, the row says `Private profile` and includes them in `profile`.
- **Proxies**: the scraper retries a page with your proxy settings and, if that fails, tries once more through Apify residential proxy when your account has access to it.
- **Enter each source once**: duplicates are not merged, so the same username or keyword entered twice is scraped (and charged) twice.
- **Error rows**: `Profile not found`, `Search could not be loaded`, `Private profile` and `No posts found`. Each has `source`, `input` and `error`, and none is charged.

### Use it from the API, Python or JavaScript

You can run the scraper and read the posts with the official Apify clients. Replace `YOUR_TOKEN` with your Apify API token.

JavaScript (Node.js):

```javascript
const { ApifyClient } = require('apify-client');

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const input = { usernames: ['zuck'], searchQueries: ['AI agents'], searchMode: 'recent' };

const run = await client.actor('juliob.rangel/threads-scraper-fast').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_TOKEN')
input = {'usernames': ['zuck'], 'searchQueries': ['AI agents'], 'searchMode': 'recent'}

run = client.actor('juliob.rangel/threads-scraper-fast').call(run_input=input)
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

The scraper also works with Make, Zapier and n8n, can export results to Google Sheets, can call your webhook when a run finishes, and can be used by AI agents through the Apify MCP server.

### FAQ

**Do I need a Threads or Instagram login?**
No. The scraper reads the pages Threads shows to visitors who are not logged in. No cookies or accounts are used.

**Can I export Threads posts to Excel or CSV?**
Yes. Open the Output tab after the run and download the dataset as Excel, CSV, JSON or HTML, or send it to Google Sheets.

**How many posts can I get per profile?**
Usually 10 to 25, the posts Threads shows on the first page without login. For more data, run the scraper on a schedule and collect new posts over time.

**Can I get the replies under a post?**
No. You get the reply count (`replies`), not the reply texts. A profile's own follow-up posts in a chain can appear as rows with `isReply: true`.

**Can I scrape private profiles?**
No. Private profiles return an error row and are not charged.

**Is it legal to scrape Threads?**
The scraper only collects publicly available data. You are responsible for complying with Threads' terms and with privacy laws such as GDPR and LGPD. Posts and profiles of people are personal data, so you need a legitimate reason to collect and use them.

**Why did I get an error row?**
The profile does not exist or is private, the search page could not be loaded, or no posts were found. Error rows are not charged; check the username spelling and try again later.

### Related scrapers

- [Instagram Posts Scraper (Reels, Likes, Views, Captions)](https://apify.com/juliob.rangel/instagram-posts-scraper-fast)
- [Instagram Profile Stats Scraper (Followers, Bio, Posts)](https://apify.com/juliob.rangel/instagram-profile-stats)
- [TikTok Video Scraper (Views, Likes, Comments, Shares)](https://apify.com/juliob.rangel/tiktok-video-scraper-fast)
- [Telegram Channel Scraper (Posts, Views, Reactions)](https://apify.com/juliob.rangel/telegram-channel-scraper-fast)
- [Substack Scraper (Posts, Likes, Comments, Full Text)](https://apify.com/juliob.rangel/substack-scraper-fast)

***

## Extrator do Threads (PT-BR)

Receba posts do Threads de perfis públicos ou buscas por palavra-chave, sem login: texto, curtidas, respostas, reposts, data, imagens e autor, além de seguidores e bio do perfil. Você paga só por post retornado.

# Actor input Schema

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

Threads usernames or profile URLs, e.g. zuck or https://www.threads.com/@mosseri. Returns the profile's latest posts with followers and bio.

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

Keywords or hashtags to search on Threads, e.g. "AI agents".

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

Top posts, recent posts, or both.

## `maxPostsPerSource` (type: `integer`):

Threads shows about 10 to 25 posts per page without login.

## `proxy` (type: `object`):

Apify Proxy settings.

## Actor input object example

```json
{
  "usernames": [
    "zuck"
  ],
  "searchQueries": [
    "apify"
  ],
  "searchMode": "both",
  "maxPostsPerSource": 50,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# 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 = {
    "usernames": [
        "zuck"
    ],
    "searchQueries": [
        "apify"
    ],
    "maxPostsPerSource": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("juliob.rangel/threads-scraper-fast").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 = {
    "usernames": ["zuck"],
    "searchQueries": ["apify"],
    "maxPostsPerSource": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("juliob.rangel/threads-scraper-fast").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 '{
  "usernames": [
    "zuck"
  ],
  "searchQueries": [
    "apify"
  ],
  "maxPostsPerSource": 50
}' |
apify call juliob.rangel/threads-scraper-fast --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,juliob.rangel/threads-scraper-fast"
        }
    }
}
```

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/qkehkuhMi5HueJUM6/builds/njGhBUQlieJNyUnv2/openapi.json
