# Threads Search Post Scraper By Profile & Keyword (`api-empire/threads-search-post-scraper`) Actor

Threads Search Post Scraper: Find posts by profile and keyword, capturing post text, authors, timestamps, URLs, replies, likes, reposts, and available engagement data. Analyze relevant conversations, content trends, audience interests, and competitor activity for social media research.

- **URL**: https://apify.com/api-empire/threads-search-post-scraper.md
- **Developed by:** [API Empire](https://apify.com/api-empire) (community)
- **Categories:** Social media, Lead generation, Other
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.99 / 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/actors/running/actors-in-store.md#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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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 — Extract Posts, Profiles and Engagement Data as JSON

Threads Search Post Scraper By Profile & Keyword pulls public Threads posts by URL, numeric post ID, search phrase, or username, and returns typed, normalized JSON — no HTML, no selectors, no parsing. One run covers three data shapes: individual posts, a creator's full paginated post history, and a computed per-profile engagement roll-up (average likes, replies, reposts, top post, posting cadence). No Threads login, password, or developer account is required. Point it at a keyword, a profile, or both, and get structured rows ready for a spreadsheet, a database, or an LLM pipeline.

### 🧵 What is Threads Search Post Scraper By Profile & Keyword?

Threads Search Post Scraper By Profile & Keyword is an Apify Actor that reads Threads' own public, server-rendered pages and its anonymous GraphQL endpoint to extract post and profile data — it does not use Meta's official, permission-gated Threads API. It accepts three independent target types (post URL/ID, search phrase, username) in the same run and returns matching posts, a creator's paginated post history, and a locally computed engagement summary per profile. No Threads account, password, or session cookie is required — the Actor reads only what a logged-out browser can already see.

- 🔗 Scrape individual posts by URL or numeric post ID
- 🔍 Scrape every post matching a search phrase or hashtag, not just the first one
- 🧵 Scrape a creator's full public post history by username
- 📊 Compute a per-profile engagement roll-up — average likes/replies/reposts/quotes, top post, posting cadence
- 📤 Export as JSON, CSV, or the other formats every Apify dataset supports

### 📊 What data does Threads Search Post Scraper By Profile & Keyword collect?

The Actor returns three distinct row shapes in the same dataset, controlled by which inputs you fill in:

| Data Type | Key Fields | JSON Field Names |
| --- | --- | --- |
| Posts (by URL, post ID, or search phrase) | caption, engagement counts, mentions/hashtags/links, quote/repost links | `caption`, `like_count`, `direct_reply_count`, `repost_count`, `quote_count`, `mentions`, `hashtags`, `urls` |
| Posts (by profile discovery) | same post fields as above, tagged with the profile they came from | `sourceMode`, `sourceProfile`, `post_url`, `taken_at` |
| Profile engagement roll-ups | averages, top post, posting cadence, computed locally from feature above | `avgLikes`, `avgReplies`, `avgReposts`, `avgQuotes`, `topPostUrl`, `postingCadencePerDay` |

### 🆚 How does Threads Search Post Scraper By Profile & Keyword differ from the official Threads API?

Meta's official Threads API is built for managing a connected account's own presence — publishing, replies, and insights — plus a keyword-search endpoint that is gated behind Meta App Review; Threads Search Post Scraper By Profile & Keyword needs no app review and starts returning public data on the first run.

| Feature | Official Threads API | Threads Search Post Scraper By Profile & Keyword |
| --- | --- | --- |
| Access setup | Meta App Review, plus `threads_basic` and `threads_keyword_search` permissions before public search works (developers.facebook.com, checked 2026-08-04) | Start directly from the Apify Console — no app review |
| Scope before approval | Keyword search returns only the authenticated user's own posts (developers.facebook.com, checked 2026-08-04) | Returns public posts for any target from the first run |
| Public keyword-search cap | 2,200 queries per rolling 24 hours, shared across all apps for that user account (developers.facebook.com, checked 2026-08-04) | No fixed daily query cap in the Actor itself; bounded by the `maxItems` you set |
| Arbitrary profile history | Positioned around managing the connected account's own presence, not a bulk endpoint for another public creator's post history | `profiles` input pages through any public creator's post history directly |
| Entity coverage | Posts/replies/insights tied to the authenticated account, plus keyword search | Posts by URL/ID/search phrase, profile post history, and a computed engagement roll-up — in one run |
| Output | JSON via the Graph API, requires OAuth token management | One flattened JSON row per post/roll-up, no token handling |

If you already manage a Threads business account through a connected app and only need to publish or search your own content, the official API is the right tool. If you need public post or creator data at read-only scale without an app-review process, use this Actor instead.

### 🎯 Why do developers and teams scrape Threads?

#### For AI engineers and agent builders

Threads posts arrive as flat JSON with `caption`, `mentions`, `hashtags`, and `urls` already parsed out of the raw text — no regex needed before indexing. A common pattern: run a `profiles` list for a set of tracked accounts, push each `caption` plus its `like_count`/`direct_reply_count` into a vector store, and let a RAG agent answer "what has this creator said about X" using real post text instead of a summary.

#### For marketers and brand teams

Feed a brand name or hashtag into `urls` as a search phrase to pull every public mention for social listening, or add a competitor's username to `profiles` to get their full post history plus the `avgLikes`/`postingCadencePerDay` roll-up in the same run — a quick read on how often and how well a competitor's content performs, without opening the app.

#### For researchers and analysts

Because the Actor only reads what a logged-out browser can see, it fits public-data academic and market research: track posting cadence and engagement distribution across a list of public figures over time using `taken_at`, `like_count`, and the computed `postingCadencePerDay` field, without touching any private or login-gated content.

#### For developers building data products

Schedule the Actor on Apify and build a dashboard on top of `like_count`, `repost_count`, `quote_count`, and the per-profile roll-up fields — the dataset schema stays stable between runs, so a pipeline built on these field names doesn't need to be rewritten when Threads changes its own internal payload shape.

### 🧭 How to scrape Threads (step by step)

1. Open **Threads Search Post Scraper By Profile & Keyword** on its Apify Store listing and click **Try for free** (or **Run**, if you already have it saved).
2. Add at least one entry to `urls` (a post URL, a numeric post ID, or a search phrase) or `profiles` (a username or profile URL) — the run fails immediately if both are left empty.
3. Set `maxItems` and `maxPostsPerProfile` to bound the run size, and toggle `includeProfileRollup` if you want the per-profile summary row.
4. Click **Start** — or start the run programmatically via the Apify API/`apify-client`.
5. Download results as JSON, CSV, or any other format the Apify dataset export menu offers once the run finishes.

#### What to do when Threads changes its structure

`extract_posts.py` is deliberately schema-tolerant: it probes several known key-name variants for the same data and preserves any field it doesn't recognize instead of dropping it, so minor upstream renames don't blank the output. The Actor is maintained and the output field names stay stable on your end — no specific turnaround time is promised for any given break.

### ⬇️ Input

| Parameter | Required | Type | Description | Example Value |
| --- | --- | --- | --- | --- |
| `urls` | No | array of strings | Each line: a full post URL (`threads.com` or `threads.net`), a numeric post ID (10+ digits), or a search phrase. A search phrase returns EVERY matching post it can find, not just one. | `["Mark Zuckerberg", "https://www.threads.com/@zuck/post/AbCdEfGhIjK"]` |
| `maxItems` | No | integer (minimum `0`) | Cap on how many post rows to save across the whole run (targets + profiles combined). Leave empty or `0` for no limit. Per-profile summary rows don't count against this cap. | `25` |
| `profiles` | No | array of strings | One or more Threads usernames or profile URLs. Each is expanded into that account's own paginated post history. | `["zuck"]` |
| `maxPostsPerProfile` | No | integer (minimum `0`, prefill `20`) | Cap on how many posts to pull from EACH profile in `profiles`. Example: `maxPostsPerProfile=20` with 3 profiles → up to 60 profile post rows (still bounded by `maxItems`). | `15` |
| `includeProfileRollup` | No | boolean (default `true`) | When on, after each profile's posts are collected an extra summary row is added: average likes/replies/reposts/quotes, the top post, and posting cadence. Off = only individual post rows. | `true` |
| `proxyConfiguration` | No | object (proxy editor) | Leave off for a simple run. Turn on Apify Proxy here when you want Apify to route requests through its network — useful on busy or sensitive targets. | `{"useApifyProxy": false}` |

**Common pitfall:** `maxPostsPerProfile` set to `0` or left empty does **not** mean unlimited — the Actor falls back to its default of 20 posts per profile. Only `maxItems` treats `0`/empty as no limit.

#### Example JSON input

```json
{
  "urls": ["Mark Zuckerberg", "https://www.threads.com/@zuck/post/AbCdEfGhIjK"],
  "maxItems": 25,
  "profiles": ["zuck"],
  "maxPostsPerProfile": 15,
  "includeProfileRollup": true,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

### ⬆️ Output

Every row is typed, normalized JSON pushed to the Apify dataset as soon as it's collected — exportable as JSON, CSV, Excel, XML, or RSS from the dataset's export menu, the same formats every Apify dataset provides. Two structurally different row shapes are pushed: individual **posts** and, when `includeProfileRollup` is on, one **profile roll-up** summary per profile.

Every field below is present on every post row (`null` when Threads didn't supply it for that post); any extra field present in Threads' own raw payload beyond this list is preserved as-is rather than dropped.

| Field | Description |
| --- | --- |
| `post_url` | Deep link to the post, built from username + code |
| `pk`, `id`, `code` | Threads' own numeric/media identifiers for the post |
| `canonical_url` | Canonical link reported by Threads, if present |
| `user` | Author sub-object: `username`, `full_name`, `is_verified`, `profile_pic_url`, `friendship_status`, and related flags |
| `caption`, `caption_is_edited`, `caption_add_on` | Post text and edit metadata |
| `text_post_app_info` | Raw Threads reply/thread metadata, including `text_fragments` (source of `mentions`/`hashtags`/`urls` below) and `share_info` (source of quote/repost fields) |
| `transcription_data`, `accessibility_caption` | Audio transcript / alt-text data, when Threads supplies it |
| `carousel_media`, `image_versions2`, `video_versions` | Raw media asset URLs and variants |
| `has_audio`, `audio`, `media_type`, `original_height`, `original_width` | Media metadata |
| `media_overlay_info`, `giphy_media_info`, `usertags` | Overlay/sticker/GIF/tag metadata, when present |
| `like_count` | Like count |
| `direct_reply_count` | Reply count — flattened out of `text_post_app_info` |
| `repost_count` | Repost count — flattened |
| `quote_count` | Quote count — flattened |
| `reshare_count` | Reshare count — flattened |
| `has_liked`, `like_and_view_counts_disabled` | Viewer-state and visibility flags |
| `mentions` | Flat array of mentioned usernames, parsed from the caption |
| `hashtags` | Flat array of hashtags, parsed from the caption |
| `urls` | Flat array of URLs linked in the caption |
| `is_quote_post`, `quoted_post_url` | Whether this post quotes another, and a deep link to it |
| `is_repost`, `reposted_post_url` | Whether this post is a repost, and a deep link to the original |
| `taken_at` | Unix timestamp the post was published |
| `is_paid_partnership` | Paid-partnership flag |
| `sharing_friction_info`, `gen_ai_detection_method` | Sharing-friction and AI-generated-content labels reported by Threads |
| `metaPlace`, `meta_place` | Location tag, if attached |
| `logging_info_token`, `organic_tracking_token`, `__token` | Threads' own internal tracking tokens, preserved verbatim |
| `type` | Always `"post"` for individual post rows |
| `sourceMode` | `"profile"` when the row came from the `profiles` input, otherwise `null` |
| `sourceProfile` | The username that produced this row via profile discovery, otherwise `null` |
| `scrapedAt` | UTC timestamp (ISO 8601) this row was scraped |

#### Scraped post

```json
{
  "post_url": "https://www.threads.com/@zuck/post/AbCdEfGhIjK",
  "pk": 3510298471234567,
  "id": "3510298471234567_78901234",
  "code": "AbCdEfGhIjK",
  "user": {
    "username": "zuck",
    "full_name": "Mark Zuckerberg",
    "is_verified": true,
    "profile_pic_url": "https://scontent.cdninstagram.com/example.jpg"
  },
  "caption": { "text": "Excited to share what we're building next 🚀 #meta" },
  "like_count": 48213,
  "direct_reply_count": 1204,
  "repost_count": 632,
  "quote_count": 89,
  "reshare_count": 41,
  "mentions": [],
  "hashtags": ["meta"],
  "urls": [],
  "is_quote_post": false,
  "quoted_post_url": null,
  "is_repost": false,
  "reposted_post_url": null,
  "taken_at": 1769078400,
  "media_type": 1,
  "has_audio": false,
  "type": "post",
  "sourceMode": "profile",
  "sourceProfile": "zuck",
  "scrapedAt": "2026-08-04T09:12:03Z"
}
```

#### Scraped profile roll-up

```json
{
  "type": "profile_summary",
  "username": "zuck",
  "postsAnalyzed": 15,
  "avgLikes": 21430.53,
  "avgReplies": 812.4,
  "avgReposts": 305.13,
  "avgQuotes": 44.2,
  "topPostUrl": "https://www.threads.com/@zuck/post/AbCdEfGhIjK",
  "topPostLikes": 48213,
  "postingCadencePerDay": 1.867,
  "firstPostAt": "2026-06-01T14:03:00Z",
  "lastPostAt": "2026-08-01T18:47:00Z",
  "scrapedAt": "2026-08-04T09:12:07Z"
}
```

`postingCadencePerDay`, `firstPostAt`, and `lastPostAt` are `null` when a profile returns fewer than two distinct post timestamps — the Actor leaves cadence undefined rather than faking a value.

**Pay-per-event pricing note:** individual post rows are pushed with the charged event `row_result`. Profile roll-up rows (`type: "profile_summary"`) are pushed to the dataset but are **not charged**, and don't count against `maxItems`. If you're reconciling row counts against usage, filter them out with `item["type"] != "profile_summary"` (Python) or `item.type !== "profile_summary"` (JavaScript).

### ⚔️ How does Threads Search Post Scraper By Profile & Keyword compare to other Threads scrapers?

| Feature | Threads Search Post Scraper By Profile & Keyword | Generic alternative |
| --- | --- | --- |
| Search results per phrase | Every matching post found, paginated via GraphQL and de-duplicated | Often only the first matching thread |
| Profile coverage | Full paginated public post history by username, plus a computed engagement roll-up | Post-by-post only, no aggregate summary |
| Output format | Flattened, schema-tolerant JSON row per post — unknown platform fields preserved, not dropped | Varies; fields are often nested or dropped when the platform changes |
| Anti-bot handling | Automatic 3-tier proxy escalation (no proxy → datacenter group → residential) triggered on failure | Manual proxy setup, or none |
| Engagement fields | `direct_reply_count`, `repost_count`, `quote_count`, `reshare_count` exposed as flat top-level columns | Often left nested inside the raw platform payload |

If you're building an AI agent or RAG pipeline, the output-format row is the decision-maker — parsing HTML inside an agent loop is a reliability failure mode, not a feature.

### 📈 How many results can you scrape with Threads Search Post Scraper By Profile & Keyword?

There is no hard cap in the Actor itself unless you set one: leave `maxItems` empty or at `0` and the run keeps collecting until every target is exhausted. Internally, profile-history pagination requests pages of between 5 and 25 posts at a time and stops after `max(3, maxItems // 5 + 10)` pages or when Threads stops returning new posts, whichever comes first; keyword search paginates the same way and additionally stops after three consecutive pages with no new matches. `maxPostsPerProfile` defaults to 20 posts per profile if left at `0` or empty — it is not an "unlimited" value the way `maxItems` is. The real ceiling on any single run is however many public posts exist for that target and however far Threads' own pagination continues to return new results.

### 🔌 Integrate Threads Search Post Scraper By Profile & Keyword and automate your workflow

Threads Search Post Scraper By Profile & Keyword works with any language or tool that can send an HTTP request.

#### REST API integration

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_API_TOKEN>")
run = client.actor("your-username/threads-search-post-scraper-by-profile-and-keyword").call(
    run_input={
        "urls": ["Mark Zuckerberg"],
        "profiles": ["zuck"],
        "maxItems": 25,
        "maxPostsPerProfile": 15,
        "includeProfileRollup": True,
    }
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("type"), item.get("post_url") or item.get("username"))
```

Works in Python, Node.js, Go, Ruby, cURL.

#### Automation platforms (n8n, Make, LangChain)

Apify publishes native integrations that can call any Actor by its ID, including this one: the Apify node in n8n, the Apify module in Make, and LangChain's Apify Actor tooling can all trigger a run and read back the resulting dataset without writing a custom HTTP client.

### ⚖️ Is it legal to scrape Threads?

Yes — Threads Search Post Scraper By Profile & Keyword only reads posts, captions, and profile information that Threads already renders on public, logged-out pages; it does not access private accounts or login-gated content. Because post captions, usernames, and profile details relate to identifiable individuals, this counts as personal data under regimes like the GDPR and CCPA — you are responsible for having a lawful basis before storing, processing, or reusing it, particularly at bulk scale. Scraping public data is generally permitted, but how you use the results (marketing outreach, profiling, retention) is what determines compliance, not the act of collection itself. Consult legal counsel for commercial use cases involving bulk personal data.

### ❓ Frequently asked questions

#### Does Threads Search Post Scraper By Profile & Keyword work without a Threads account?

Yes. It reads Threads' own public, server-rendered pages and the anonymous session tokens embedded in them — no username, password, or session cookie is required.

#### How often is the scraped data updated?

Every run performs a live fetch against Threads at the time it runs; nothing is served from a cache, so results reflect whatever is publicly visible on Threads at run time.

#### What happens if a post is deleted or a profile can't be reached?

If a target can't be reached, the Actor logs "Could not complete this target. Skipping." and moves on rather than failing the whole run. If a profile is private, blocked, or doesn't exist, it's skipped with a specific warning and produces zero rows — the run itself still completes and saves whatever else it found.

#### Can I scrape private Threads accounts?

No. Only publicly accessible posts and profiles are returned. A private, blocked, or nonexistent profile raises an internal "profile unavailable" condition and is skipped.

#### How is Threads Search Post Scraper By Profile & Keyword priced?

It runs on Apify's pay-per-event pricing: each individual post row is charged under the `row_result` event. Per-profile roll-up summary rows are pushed to the dataset but are not charged. Check the Actor's Pricing tab on its Apify Store listing for the current per-event rate.

#### Does Threads Search Post Scraper By Profile & Keyword work for AI agent workflows and LLM pipelines?

Yes. It's callable as an HTTP endpoint via the Apify API from any agent framework. Every response is typed JSON with `mentions`/`hashtags`/`urls` already parsed out of the caption — no HTML parsing step before passing it to an LLM.

#### How does Threads Search Post Scraper By Profile & Keyword handle Threads' anti-bot measures?

It rotates the User-Agent per request, retries up to 3 times with exponential backoff plus jitter on `429`/`502`/`503`/`504` responses and network errors, and automatically escalates through no-proxy → Apify's datacenter proxy group → residential proxy if requests keep failing, falling back to residential retries before giving up.

#### How does Threads Search Post Scraper By Profile & Keyword compare to other Threads scrapers?

It returns every matching post for a search phrase instead of just the first one, paginates a creator's full public post history, and adds a computed engagement roll-up in the same run — see the comparison table above for the specific fields and behavior.

#### Does Threads Search Post Scraper By Profile & Keyword return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with stable field names — pass it directly into an LLM context window, index it into a vector store, or route it through an agent tool without a parsing step.

#### Can I use Threads Search Post Scraper By Profile & Keyword without managing proxies?

Yes. Proxy escalation across no-proxy, datacenter, and residential tiers happens automatically inside the Actor. The `proxyConfiguration` input is only needed if you want to force a specific Apify Proxy group or country.

#### What happens when Threads changes its structure or blocks the scraper?

The Actor is maintained, and its output field names and types stay stable on your end — the extraction logic probes several known key-name variants and preserves unrecognized fields instead of dropping them, so most upstream renames don't require any change on your side. No specific fix turnaround time is promised.

### 💬 Your feedback

Found a bug, or missing a field you need? We want to know. Open an issue on the Actor's Apify Store page (the Issues tab) or message the developer directly through Apify — reports like these are how this Actor stays maintained against Threads' own changes.

# Actor input Schema

## `urls` (type: `array`):

Each line: a full post URL (threads.com or threads.net), a numeric post ID (10+ digits), or a search phrase. A search phrase now returns EVERY matching post it can find (not just one). Example URL: https://www.threads.com/@zuck/post/AbCdEfGhIjK — example phrase: Mark Zuckerberg

## `maxItems` (type: `integer`):

Cap on how many post rows to save across the whole run (targets + profiles combined). Leave empty (or 0) for no limit. Per-profile summary rows don't count against this cap.

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

One or more Threads usernames or profile URLs. Each is expanded into that account's own paginated post history — a coverage mode the base targets list doesn't have. Example: zuck or https://www.threads.com/@zuck

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

Cap on how many posts to pull from EACH profile in the list above. Example: maxPostsPerProfile=20 with 3 profiles -> up to 60 profile post rows (still bounded by Max items). Default is 20.

## `includeProfileRollup` (type: `boolean`):

When on, after each profile's posts are collected an extra summary row is added: average likes / replies / reposts / quotes, the top post, and posting cadence (posts per day). Off = only individual post rows.

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

Leave off for a simple run. Turn on Apify Proxy here when you want Apify to route requests through its network — useful on busy or sensitive targets.

## Actor input object example

```json
{
  "urls": [
    "Mark Zuckerberg"
  ],
  "maxItems": 10,
  "profiles": [
    "zuck"
  ],
  "maxPostsPerProfile": 20,
  "includeProfileRollup": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All scraped items in the Actor's default dataset.

# 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 = {
    "urls": [
        "Mark Zuckerberg"
    ],
    "maxItems": 10,
    "profiles": [
        "zuck"
    ],
    "maxPostsPerProfile": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("api-empire/threads-search-post-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 = {
    "urls": ["Mark Zuckerberg"],
    "maxItems": 10,
    "profiles": ["zuck"],
    "maxPostsPerProfile": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("api-empire/threads-search-post-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 '{
  "urls": [
    "Mark Zuckerberg"
  ],
  "maxItems": 10,
  "profiles": [
    "zuck"
  ],
  "maxPostsPerProfile": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call api-empire/threads-search-post-scraper --silent --output-dataset

```

## MCP server setup

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