# Threads Scraper - Profiles, Posts & Search (`parsebird/threads-scraper`) Actor

Scrape public Threads user posts, search posts, and profile matches. Extract post text, profile data, engagement metrics, media URLs, contacts, hashtags, and mentions. Export JSON, CSV, Excel.

- **URL**: https://apify.com/parsebird/threads-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Categories:** Social media, Automation, Integrations
- **Stats:** 51 total users, 12 monthly users, 97.1% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.29 / 1,000 threads rows

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** extracts public Threads user posts, keyword search posts, and profile matches from [Threads](https://www.threads.com/). Use it to collect post text, profile data, public engagement metrics, media URLs, bio contacts, hashtags, mentions, and URLs, then export the results from Apify as JSON, CSV, or Excel.

<table><tr>
<td style="border-left:4px solid #000000;padding:12px 16px;font-weight:600">
This Actor works without a Threads login and only collects data that Threads exposes publicly at run time. Very new, deleted, private, restricted, or partially available content can return fewer rows or fewer fields.
</td>
</tr></table>

<br>

<table>
<tr>
<td colspan="3" style="padding:10px 14px;background:#000000;border:none;border-radius:4px 4px 0 0">
<span style="color:#FFFFFF;font-size:14px;font-weight:700;letter-spacing:0.5px">ParseBird Threads Suite</span>
<span style="color:#D6D3D1;font-size:13px">&nbsp;&nbsp;&bull;&nbsp;&nbsp;Posts, replies, profiles &amp; search</span>
</td>
</tr>
<tr>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:33%;background:#F5F5F4">
<a href="https://apify.com/parsebird/threads-scraper" style="color:#000000;text-decoration:none;font-weight:700;font-size:13px">Threads Scraper</a><br>
<span style="color:#000000;font-size:11px;font-weight:600">You are here</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-top:none;vertical-align:top;width:33%;background:#FFFFFF">
<a href="https://apify.com/parsebird/threads-search-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">Threads Search Scraper</a><br>
<span style="color:#78716C;font-size:11px">Search posts by keyword or hashtag</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-top:none;vertical-align:top;width:33%;background:#FFFFFF">
<a href="https://apify.com/parsebird/threads-posts-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">Threads Posts Scraper</a><br>
<span style="color:#78716C;font-size:11px">Single posts with their replies</span>
</td>
</tr>
<tr>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-radius:0 0 0 4px;border-right:none;border-top:none;vertical-align:top;width:33%;background:#FFFFFF">
<a href="https://apify.com/parsebird/threads-user-posts-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">Threads User Posts Scraper</a><br>
<span style="color:#78716C;font-size:11px">Full profile post history</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-top:none;vertical-align:top;width:33%;background:#FFFFFF">
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-radius:0 0 4px 0;border-top:none;vertical-align:top;width:33%;background:#FFFFFF">
</td>
</tr>
</table>

> Paste a Threads username, keyword, hashtag, or profile discovery query into your AI assistant and ask it to run this Actor through the Apify API. It can schedule monitoring, fetch fresh rows, and pass the dataset to your CRM, spreadsheet, or research workflow.

### Scrape Threads Profiles, User Posts, And Search Results

This Threads scraper supports three public-data workflows:

- User posts: scrape recent public posts from up to 20 Threads profiles.
- Search posts: search public Threads posts by keyword or hashtag with `top` or `recent` ordering.
- Find profiles: discover up to 10 public account matches per keyword from Threads search/profile results.

You can run the Actor manually, call it through the [Apify API](https://docs.apify.com/api/v2), run it on [Apify schedules](https://docs.apify.com/platform/schedules), connect it to [Apify integrations](https://docs.apify.com/platform/integrations), and export datasets from [Apify storage](https://docs.apify.com/platform/storage/dataset) in JSON, CSV, Excel, XML, RSS, or HTML formats. Apify also offers free trial credits where applicable on the platform.

### Threads Scraper Input

| Field | Type | Description |
| --- | --- | --- |
| `mode` | string | Scraping mode: `user`, `search`, or `profiles`. |
| `usernames` | array | Target usernames for user mode. Accepts `zuck`, `@nike`, or `https://threads.com/@meta`. Uses up to 20. |
| `keywords` | array | Keywords or hashtags for search/profiles modes. In user mode, optional keywords flag matching posts without filtering them out. Uses up to 20. |
| `search_filter` | string | Search mode only. `top` returns popular public posts; `recent` favors newer public matches. |
| `start_date` | string | Search mode only. Date from which to keep posts, using `YYYY-MM-DD` or relative values such as `7 days`. |
| `end_date` | string | Search mode only. Date up to which to keep posts, using `YYYY-MM-DD` or relative values such as `1 day`. |
| `max_posts` | integer | Results per user or search keyword. Find Profiles returns up to 10 profiles per keyword even when this value is higher. |

### How To Scrape Threads User Posts

1. Set `mode` to `user`.
2. Add one or more Threads usernames, handles, or profile URLs.
3. Set `max_posts` to the number of public posts to collect per profile.
4. Optionally add `keywords` to flag matching posts in `keyword_match`.
5. Run the Actor and open the dataset.

```json
{
  "mode": "user",
  "usernames": ["zuck"],
  "max_posts": 50
}
```

```json
{
  "mode": "user",
  "usernames": ["zuck", "instagram", "nike"],
  "keywords": ["AI"],
  "max_posts": 100
}
```

### How To Search Threads Posts By Keyword Or Hashtag

1. Set `mode` to `search`.
2. Add one or more `keywords`; the `#` symbol is optional for hashtags.
3. Choose `top` for notable public posts or `recent` for newer public matches.
4. Optionally add `start_date` and `end_date` for recent windows.
5. Export the dataset in JSON, CSV, or Excel.

```json
{
  "mode": "search",
  "keywords": ["artificial intelligence", "#startup"],
  "search_filter": "top",
  "max_posts": 50
}
```

```json
{
  "mode": "search",
  "keywords": ["AI"],
  "search_filter": "recent",
  "start_date": "7 days",
  "max_posts": 50
}
```

Date filtering applies to search mode only. Because the Actor runs without logging in, it keeps matching public posts inside your requested date range from the results Threads currently exposes. It is best for recent windows such as the last 7 or 30 days.

### How To Find Threads Profiles By Keyword

Use `profiles` mode to discover public account matches for a topic, business category, brand, or local query.

```json
{
  "mode": "profiles",
  "keywords": ["coffee roaster", "specialty coffee"],
  "max_posts": 10
}
```

For local account discovery, include the place name in the keyword, such as `Taipei restaurant` instead of only `restaurant`. Empty bio/contact fields mean the account did not publish that information or Threads did not expose it publicly.

### Threads Scraper Output Data Fields

Every row includes `record_type`: `post` for user/search post rows or `profile` for profile discovery rows.

| Field | Description |
| --- | --- |
| `record_type` | `post` or `profile`. |
| `post_url`, `post_code` | Direct post URL and Threads post identifier when available. |
| `text_content` | Public post text. |
| `created_at`, `created_at_display`, `created_at_timestamp` | Post timestamp formats when available. |
| `like_count`, `reply_count`, `repost_count`, `quote_count`, `share_count`, `view_count` | Public engagement metrics when exposed by Threads. |
| `view_count_status` | Whether public view count was available. |
| `has_media`, `media_type`, `media_url`, `media_urls`, `media_width`, `media_height`, `has_audio` | Public media fields when available. |
| `hashtags`, `mentions`, `urls`, `mentioned_users` | Entities parsed from post text and public metadata. |
| `is_pinned`, `is_edited`, `is_paid_partnership`, `is_reply`, `is_quote_post`, `is_repost` | Public post status flags when available. |
| `reply_to_username`, `reply_control`, `quoted_post_url`, `reposted_post_url` | Reply, quote, and repost context when available. |
| `language`, `topic_tag`, `location_name`, `location_id`, `link_title` | Public metadata when Threads exposes it. |
| `username`, `display_name`, `profile_url`, `is_verified` | Author or profile identity fields. |
| `followers_count`, `bio`, `profile_pic_url`, `profile_pic_hd_url` | Public profile fields when available. |
| `fediverse_enabled`, `external_links`, `emails`, `phones`, `bio_links`, `profile_tags` | Public profile/contact fields or values extracted from the public bio. |
| `podcast_name`, `podcast_url`, `podcast_platform` | Public podcast fields when available. |
| `search_filter`, `search_keyword`, `keyword_match` | Search or keyword-flagging context. |
| `scraped_at` | Timestamp when the row was collected. |

### Threads Scraper Output Example

```json
{
  "record_type": "post",
  "post_url": "https://www.threads.com/@example_creator/post/EXAMPLE01",
  "post_code": "EXAMPLE01",
  "text_content": "Launching a new research note today...",
  "created_at": "2026-01-12T18:00:30+00:00",
  "created_at_display": "2026-01-12 18:00 UTC",
  "created_at_timestamp": 1768240830,
  "like_count": 268,
  "reply_count": 81,
  "repost_count": 12,
  "quote_count": 4,
  "share_count": 22,
  "view_count": 41651,
  "view_count_status": "available",
  "has_media": false,
  "media_type": "text",
  "media_url": "",
  "media_urls": [],
  "hashtags": [],
  "mentions": [],
  "urls": [],
  "scraped_at": "2026-04-25T10:00:00+00:00",
  "username": "example_creator",
  "display_name": "Example Creator",
  "profile_url": "https://www.threads.com/@example_creator",
  "is_verified": true,
  "followers_count": 54000,
  "bio": "Research notes and product updates",
  "external_links": ["https://example.com"],
  "emails": [],
  "phones": [],
  "search_filter": null,
  "search_keyword": null,
  "keyword_match": null
}
```

### Use Threads Scraper With Python

Install the [Apify Python client](https://docs.apify.com/api/client/python/) and call the Actor:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("parsebird/threads-scraper").call(
    run_input={
        "mode": "search",
        "keywords": ["AI"],
        "search_filter": "recent",
        "max_posts": 30,
    }
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### Use Threads Scraper With JavaScript

Install the [Apify JavaScript client](https://docs.apify.com/api/client/js/) and call the Actor:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('parsebird/threads-scraper').call({
  mode: 'profiles',
  keywords: ['coffee roaster'],
  max_posts: 10,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### How Much Does Threads Scraper Cost?

**What is the pricing model?**\
This Actor uses pay per event pricing. You pay for each pushed Threads row.

| Plan | Price |
| --- | --- |
| Free, Bronze, Silver | $2.49 per 1,000 results |
| Gold | $2.29 per 1,000 results |

**Are platform features included?**\
The event price includes normal Apify platform usage for this Actor. You can still use scheduling, API access, integrations, and dataset exports.

### Is It Legal To Scrape Threads?

**Does this Actor collect private Threads data?**\
No. It is designed to collect only public data that Threads exposes without login.

**What should I check before using the data?**\
Review the [Threads](https://www.threads.com/) terms, applicable privacy laws, and your own use case. Do not use scraped data for spam, harassment, or unlawful profiling.

**Why are some fields empty?**\
Threads can change what it shows publicly over time. Some public posts may not expose every engagement, media, author, or profile field. Very new, deleted, private, restricted, or partially available posts may return incomplete fields. Search ranking may include broadly related posts, and a keyword can return fewer rows than requested when fewer matching public results are available.

### Related Threads And Social Media Actors

- [Threads Search Scraper](https://apify.com/parsebird/threads-search-scraper) for a focused keyword and hashtag search workflow.
- [YouTube Search Scraper](https://apify.com/parsebird/youtube-search-scraper) for YouTube search result collection.
- [Pinterest Search Scraper](https://apify.com/parsebird/pinterest-search-scraper) for Pinterest keyword discovery.
- [Truth Social Scraper](https://apify.com/parsebird/truth-social-scraper) for public Truth Social data.
- [Product Hunt Scraper](https://apify.com/parsebird/product-hunt-scraper) for Product Hunt product and launch research.

### FAQ

**Can I scrape multiple Threads users in one run?**\
Yes. User mode accepts up to 20 usernames, handles, or Threads profile URLs per run.

**Can I search both keywords and hashtags?**\
Yes. In search mode, `AI` and `#AI` are both accepted.

**Does `max_posts` raise the Find Profiles limit?**\
No. Profiles mode returns up to 10 account matches per keyword because Threads public profile discovery is capped by what the site exposes.

**Can I monitor Threads keywords periodically?**\
Yes. Use `mode: "search"` with `search_filter: "recent"` and run it with Apify schedules.

**Why did I get fewer rows than requested?**\
Threads may expose fewer public posts or profiles for a term at run time, especially for specific phrases, older content, private accounts, restricted content, or narrow date windows.

# Changelog

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

# Actor input Schema

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

Choose user to scrape posts from profiles, search to collect public posts by keyword or hashtag, or profiles to find matching public accounts.

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

Target usernames for user mode. Accepts bare usernames, @handles, or full Threads profile URLs. Up to 20 usernames are used per run.

## `keywords` (type: `array`):

Keywords or hashtags for search and profiles modes. In user mode, optional keywords only flag matching posts; they do not filter rows. Up to 20 keywords are used per run.

## `search_filter` (type: `string`):

Search mode only. Choose top for popular public posts or recent for newer matching public posts first.

## `start_date` (type: `string`):

Search mode only. Keep posts from this date onward. Use YYYY-MM-DD for clarity or a relative value such as 7 days.

## `end_date` (type: `string`):

Search mode only. Keep posts up to this date. Use YYYY-MM-DD for repeatable runs or a relative value such as 1 day.

## `max_posts` (type: `integer`):

Results per user or search keyword. Find profiles returns up to 10 account matches per keyword even when this value is higher.

## Actor input object example

```json
{
  "mode": "user",
  "usernames": [
    "zuck",
    "@nike",
    "https://threads.com/@meta"
  ],
  "keywords": [
    "AI",
    "tech"
  ],
  "search_filter": "top",
  "max_posts": 50
}
```

# Actor output Schema

## `dataset` (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 = {
    "mode": "user",
    "usernames": [
        "zuck",
        "@nike",
        "https://threads.com/@meta"
    ],
    "keywords": [
        "AI",
        "tech"
    ],
    "search_filter": "top",
    "max_posts": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/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": "user",
    "usernames": [
        "zuck",
        "@nike",
        "https://threads.com/@meta",
    ],
    "keywords": [
        "AI",
        "tech",
    ],
    "search_filter": "top",
    "max_posts": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/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": "user",
  "usernames": [
    "zuck",
    "@nike",
    "https://threads.com/@meta"
  ],
  "keywords": [
    "AI",
    "tech"
  ],
  "search_filter": "top",
  "max_posts": 50
}' |
apify call parsebird/threads-scraper --silent --output-dataset

```

## MCP server setup

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