# Threads Scraper — Search & Profiles (no login) (`charliemorrisondev/threads-profile-scraper`) Actor

Scrape public Threads by keyword search or by profile — no login. Search returns ~30 recent posts per query across all authors; profile mode returns full stats + latest posts. Resilient to Meta doc\_id/CSS rotation.

- **URL**: https://apify.com/charliemorrisondev/threads-profile-scraper.md
- **Developed by:** [Petro Pankov](https://apify.com/charliemorrisondev) (community)
- **Categories:** Social media, Lead generation, News
- **Stats:** 1 total users, 1 monthly users, 94.1% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Threads Scraper — Search & Profiles (no login)

Scrape public **Threads** (threads.com) by **keyword search** or by **profile** — no login, no cookies, no session tokens.

### Two modes

**🔍 Search** — give it keywords or hashtags, get back ~30 recent public posts per query, across all authors. Best for keyword/hashtag monitoring, brand & competitor tracking, lead-gen and trend research.

**👤 Profile** — give it handles, get full profile stats (followers, bio, verified) plus the latest posts. Note: without login Threads exposes only the most recent ~6 posts per profile, so profile mode is for monitoring, not bulk history.

You can pass either or both in one run.

### Why this one

Most Threads scrapers break every few weeks, for two predictable reasons:

1. **They hardcode a GraphQL `doc_id`.** Meta rotates it — the scraper returns nothing.
2. **They parse CSS class names.** Meta rotates those too, on basically every deploy.

This Actor does neither. Threads streams its post data into the page as inline `application/json` blobs. This Actor waits for that stream to finish and walks **every** JSON blob for the `thread_items` → `post` shape. It *also* captures any GraphQL/XHR responses seen during scrolling and runs them through the exact same parser, then unions the results.

Two independent data sources, one shape-based parser. If Meta moves the data from one channel to the other, this keeps working. The payload *shape* is the contract — far more stable than IDs or class names.

### Input

```json
{
  "searchQueries": ["ai agents", "#bitcoin", "black friday"],
  "maxPostsPerQuery": 30,
  "usernames": ["zuck", "@mosseri"],
  "maxPostsPerProfile": 25,
  "useApifyProxy": false
}
````

| Field | Type | Default | Notes |
|---|---|---|---|
| `searchQueries` | array | — | Keywords or hashtags. ~30 posts per query, all authors. |
| `maxPostsPerQuery` | integer | `30` | 1–200. |
| `usernames` | array | — | Handles, `@handles`, or full profile URLs. Public only. |
| `maxPostsPerProfile` | integer | `25` | 1–500. |
| `useApifyProxy` | boolean | `false` | Threads answers Apify directly. Enable only if you hit rate limits AND your plan routes residential proxy. |

Provide at least one of `searchQueries` or `usernames`.

### Output

One dataset item per post:

```json
{
  "id": "3937491905269768921",
  "searchQuery": "ai agents",
  "url": "https://www.threads.com/@kanji.low/post/DakyAavlKLZ",
  "username": "kanji.low",
  "text": "1. Claude (solve any problem) 2. Perplexity (research) ...",
  "takenAt": 1783491905,
  "likeCount": 3263,
  "replyCount": 88,
  "repostCount": 41,
  "quoteCount": 12,
  "images": ["https://..."],
  "videos": [],
  "isVerified": false
}
```

Profile-mode items additionally carry `profileFollowers`, `profileBio`, `profileFullName`. `searchQuery` is present on search-mode items only.

### Pricing

Pay per event — you pay for what you actually get:

- `actor-start` — once per run
- `search-scraped` — per search query resolved
- `profile-scraped` — per profile resolved
- `post-scraped` — per post returned

A query or profile that returns nothing is not charged as a scrape.

### Limits & honesty

- **Public data only.** No login path, and there won't be one. Private profiles return nothing.
- Search returns what Threads serves logged-out — roughly the 30 most recent public posts per query.
- Respect Threads' terms and applicable law. Scrape public data; don't build creepy things.

# Actor input Schema

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

Keywords or hashtags to search on Threads (e.g. bitcoin, #ai, "black friday"). Logged-out search returns ~30 recent public posts per query across all authors — best for topic/keyword monitoring, lead-gen and trend tracking.

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

Handles (zuck), @handles (@zuck) or full URLs (https://www.threads.com/@zuck). Public profiles only. Note: without login Threads exposes only the most recent ~6 posts per profile.

## `maxPostsPerQuery` (type: `integer`):

Upper bound on posts returned per search term. Logged-out search serves roughly 30 posts per query.

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

Upper bound on posts returned per profile. Without login Threads serves only the most recent ~6 posts per profile.

## `useApifyProxy` (type: `boolean`):

Off by default: Threads is reachable directly from Apify infrastructure, and residential proxy is not routable on the Free plan (navigation hangs). Turn on if you hit rate limits and your plan includes residential proxy.

## Actor input object example

```json
{
  "searchQueries": [
    "bitcoin"
  ],
  "usernames": [
    "zuck"
  ],
  "maxPostsPerQuery": 30,
  "maxPostsPerProfile": 25,
  "useApifyProxy": false
}
```

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

// Run the Actor and wait for it to finish
const run = await client.actor("charliemorrisondev/threads-profile-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 = {
    "searchQueries": ["ai agents"],
    "usernames": ["zuck"],
}

# Run the Actor and wait for it to finish
run = client.actor("charliemorrisondev/threads-profile-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "ai agents"
  ],
  "usernames": [
    "zuck"
  ]
}' |
apify call charliemorrisondev/threads-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=charliemorrisondev/threads-profile-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Threads Scraper — Search & Profiles (no login)",
        "description": "Scrape public Threads by keyword search or by profile — no login. Search returns ~30 recent posts per query across all authors; profile mode returns full stats + latest posts. Resilient to Meta doc_id/CSS rotation.",
        "version": "0.0",
        "x-build-id": "rhchA3WYmsdKZx5g9"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/charliemorrisondev~threads-profile-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-charliemorrisondev-threads-profile-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/charliemorrisondev~threads-profile-scraper/runs": {
            "post": {
                "operationId": "runs-sync-charliemorrisondev-threads-profile-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/charliemorrisondev~threads-profile-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-charliemorrisondev-threads-profile-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchQueries": {
                        "title": "Search terms / keywords",
                        "type": "array",
                        "description": "Keywords or hashtags to search on Threads (e.g. bitcoin, #ai, \"black friday\"). Logged-out search returns ~30 recent public posts per query across all authors — best for topic/keyword monitoring, lead-gen and trend tracking.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "usernames": {
                        "title": "Threads usernames or profile URLs",
                        "type": "array",
                        "description": "Handles (zuck), @handles (@zuck) or full URLs (https://www.threads.com/@zuck). Public profiles only. Note: without login Threads exposes only the most recent ~6 posts per profile.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxPostsPerQuery": {
                        "title": "Max posts per search query",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Upper bound on posts returned per search term. Logged-out search serves roughly 30 posts per query.",
                        "default": 30
                    },
                    "maxPostsPerProfile": {
                        "title": "Max posts per profile",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Upper bound on posts returned per profile. Without login Threads serves only the most recent ~6 posts per profile.",
                        "default": 25
                    },
                    "useApifyProxy": {
                        "title": "Use Apify Proxy",
                        "type": "boolean",
                        "description": "Off by default: Threads is reachable directly from Apify infrastructure, and residential proxy is not routable on the Free plan (navigation hangs). Turn on if you hit rate limits and your plan includes residential proxy.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
