# Threads Search Scraper & API: Posts & Accounts by Keyword (`quarra/threads-search-scraper`) Actor

Threads posts and accounts found by keyword or #hashtag, without login: text, likes, replies, reposts, view count, media, author. Each keyword is searched in several wordings to find more. Language and engagement filters, new posts only on a schedule.

- **URL**: https://apify.com/quarra/threads-search-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 search results

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 Search Scraper: Posts & Accounts by Keyword

Type keywords or #hashtags and get the Threads posts (or accounts) that match them: text, author, likes, replies,
reposts, quotes, **view count**, media, language and position in the search. No login, no cookies, no account. Export
as JSON, CSV or Excel, or read it through the Apify API.

- **More than one wording per keyword**: Threads shows a logged-out visitor about 20 posts per wording. The Actor also
  searches close wordings and the hashtag (`AI agents` → `AI agent`, `aiagents`, `#aiagents`) and merges them without
  duplicates: 104 and 120 unique posts for "AI agents" in two of our runs, against 31 and 33 for the exact wording alone.
- **View counts on search results**, at no extra charge, plus `engagementPerView` to rank posts by how they did for
  their reach.
- **Accounts by keyword**: followers, bio, links, and creator stats if you want them.
- **Only new posts on a schedule**: name a watch (`watchName`) and each scheduled run returns and charges only the posts
  it has not delivered before.

**$2.50 per 1,000 posts, $5 per 1,000 accounts**, less on the Scale and Business plans, plus $0.005 per run. Keywords
with no result, duplicates and posts removed by your filters are not charged.

### Quick start

1. Type keywords into **Search keywords**, one per line (`matcha`, `AI agents`, `#nba`), or paste a
   `threads.com/search?q=…` link.
2. Choose **Posts** or **Accounts** and a **Max results per keyword**.
3. Click **Start** and read the results in the run's **Output** tab.

Through the API:

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

Coffee creators with at least 5,000 followers:

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

Like any Apify Actor, it can be scheduled, connected to webhooks, Make, Zapier, n8n, or called by AI agents through
Apify's MCP server.

### Output

One record per post. A real search result (October 11, 2026, some fields left out):

```json
{
  "type": "post",
  "id": "3749600636976469213",
  "code": "DQJQenAj5Td",
  "url": "https://www.threads.com/@edcutie_mf/post/DQJQenAj5Td",
  "author": { "username": "edcutie_mf", "fullName": "", "isVerified": false },
  "text": "Matcha isn't that bad. Some of ya’ll hate it because social media tells you to.",
  "createdAt": "2025-10-23T08:14:09Z",
  "likeCount": 80,
  "replyCount": 11,
  "repostCount": 18,
  "quoteCount": 2,
  "viewCount": 3375,
  "engagementCount": 111,
  "engagementPerView": 0.032889,
  "mediaType": "text",
  "languageGuess": "en",
  "source": "search",
  "searchQuery": "matcha",
  "searchVariant": "matcha",
  "searchRank": 7,
  "scrapedAt": "2026-10-11T18:51:10Z"
}
```

| Field | What it holds |
|---|---|
| `text`, `hashtags`, `mentions`, `links` | the post, and what it tags or links to |
| `likeCount`, `replyCount`, `repostCount`, `quoteCount`, `viewCount` | the counters Threads shows |
| `engagementPerView`, `viewsPerHour` | engagement divided by views, and views per hour since the post went up |
| `mediaType`, `mediaUrls` | text, image, video or carousel, and the media links |
| `languageGuess` | the post's language, detected on its text |
| `searchQuery`, `searchVariant`, `searchRank` | the keyword you typed, the wording that found the post, its position |

With **Accounts**, each record is a profile: `username`, `fullName`, `followerCount`, `biography`, `bioLinks`,
`bioEmails` (e-mails the creator made public in the bio), `isVerified`, and `creatorStats` when you turn it on.

The run summary (results per keyword, results per wording, why each keyword stopped) is the `OUTPUT` record of the
run's key-value store.

### Inputs

- **Search keywords**: a word, a phrase or a #hashtag, or a `threads.com/search?q=…` link. Up to 1,000 per run.
- **Search for**: Posts or Accounts.
- **Max results per keyword**: exact cap for each keyword; 0 = no limit. Left empty: 100.
- **Search types**: the Top tab, the Popular tab, topic tags, or all three merged (the most results).
- **Expand each keyword** (on by default) and **Only results that contain the keyword**.
- **Filters**: languages, minimum likes, replies and views; minimum followers for accounts. Removed rows are not
  charged.
- **Watch name**: for scheduled runs, only what is new.

### Pricing

Pay per event:

| Event, per 1,000 | Free and Starter | Scale | Business and above |
|---|---|---|---|
| Search result (post), view count included | $2.50 | $2.00 | $1.75 |
| Account, creator stats included | $5.00 | $4.00 | $3.50 |
| Run start, per run | $0.005 | $0.005 | $0.005 |

Not charged: keywords with no result, error records, duplicates, rows removed by a filter, posts already delivered to
a watch. Set **Maximum cost per run** in the run options and the run stops cleanly before going over it.

### Limits

- Threads search for logged-out visitors has no pagination and no date filter. Expanding the wording multiplies the
  results without making them exhaustive. To follow the accounts that matter over time, the
  [Threads Scraper](https://apify.com/quarra/threads-scraper) collects an account's full post history.
- Account search returns up to about 100 accounts per keyword.

### FAQ

**Do I need a Threads or Instagram account?** No account and no cookies. Platform costs are included in the price.

**Can I monitor a brand or a topic?** Yes. Set **Watch name** and schedule the Actor: the first run delivers what
Threads shows today, later runs only the new posts. A run with nothing new costs only the $0.005 start.

**My run succeeded but returned no data. Why?** Each keyword that gave nothing has an `error` record and a line in the
run status (no result, or your filters removed everything). You pay only the run start.

**Is it legal?** It collects public posts any logged-out visitor can see, without an account. Meta's terms and privacy
law (GDPR in the EU) apply to how you use the data.

### Related tools from Quarra

- [Threads Scraper](https://apify.com/quarra/threads-scraper): posts, full post history, replies, profiles and search
  in one Actor.
- [Threads Replies Scraper](https://apify.com/quarra/threads-replies-scraper): the replies of any post.
- [Reddit Scraper](https://apify.com/quarra/reddit-scraper): posts, comment trees, search and users.

# Actor input Schema

## `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.

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

Posts = posts matching the keyword; Accounts = accounts matching the keyword, with followers, bio and links.

## `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.

## `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.

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

Adds the view count of every post found and the per-view metrics. Included in the post price. Turn off only for the fastest run.

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

Accounts search: 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.

## `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`):

Accounts search: 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.

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

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

## Actor input object example

```json
{
  "searchQueries": [
    "matcha",
    "AI agents"
  ],
  "mode": "search",
  "maxItems": 50,
  "searchMode": "all",
  "expandQueries": true,
  "strictSearch": false,
  "includeViewCount": true,
  "creatorStats": false,
  "languages": [
    "en"
  ],
  "minLikes": 10,
  "minReplies": 2,
  "minViews": 1000,
  "minFollowers": 10000,
  "watchName": "competitor-posts",
  "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 = {
    "searchQueries": [
        "openai"
    ],
    "mode": "search",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

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

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

```

## MCP server setup

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