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

Threads scraper for public posts and profiles: search posts by keyword or hashtag, collect an account's posts, replies or reposts, find accounts by keyword, or save a post and its author's thread from a link. Export text, media, engagement, views when available and profile data. No login.

- **URL**: https://apify.com/futurizerush/meta-threads-scraper.md
- **Developed by:** [Rush](https://apify.com/futurizerush) (community)
- **Categories:** Social media, AI, Agents
- **Features:** Limited permissions
- **Stats:** 9,019 total users, 2,281 monthly users, 98.0% runs succeeded, 50 bookmarks
- **User rating**: 4.20 out of 5 stars

## Pricing

from $2.50 / 1,000 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 Scraper - Posts, Reposts, Replies, Profiles & Search

Search public Meta Threads posts by keyword, collect an account's public posts, reposts or replies up to your selected limit, find profiles by keyword, or save a post and its author's thread from a link. No login required. Export posts, media, public engagement metrics, and public profile data.

> **Before you start**: Threads changes its public pages from time to time, and a change can briefly affect what any tool can collect until it is adjusted. Run a small sample first, check the output, then scale up. Results reflect what Threads shows publicly at the time of the run.

### Features: What You Can Do With It

- **Brand & Mention Monitoring**: watch brands, product terms, topics and campaigns as fresh public posts appear
- **Competitor Analysis**: compare public engagement across competitor accounts and posts
- **Influencer Discovery**: find creators by keyword or niche, with public follower counts
- **Lead Generation**: build account and prospect lists from public profile information
- **Trend & Content Analysis**: collect posts on a topic, hashtag, or campaign for downstream analysis
- **Market Research**: gather public posts on a product or category to read the conversation
- **Date-bounded Research**: narrow a search to a specific date range for time-sensitive work
- **Thread Capture**: paste post links to save each post and the author's own posts in the same thread, in thread order

### Choose Your Workflow

| Goal | Use this mode | What you enter |
|---|---|---|
| Collect posts from one or more accounts | `user` | Threads usernames or profile URLs |
| See what an account reposted, and when | `user_reposts` | Threads usernames or profile URLs |
| Read the replies an account wrote | `user_replies` | Threads usernames or profile URLs |
| Search public posts by topic | `search` | Keywords or hashtags |
| Discover account matches by keyword | `profiles` | Keywords, niches, or local phrases |
| Save a post and its author's thread | `post_link` | Threads post links |
| Monitor fresh public mentions | `search` + `recent` | Brand, topic, or competitor keywords |
| Research a specific date range | `search` + date filters | Keyword plus start/end date |

### Ready-Made Examples

Each one is a pre-configured run you can start and then edit. Browse them all on the [Examples tab](https://apify.com/futurizerush/meta-threads-scraper/examples).

| Example | What you get |
|---|---|
| [See which of your Threads posts perform best](https://apify.com/futurizerush/meta-threads-scraper/examples/analyze-your-threads-performance) | Your posts with likes, replies, timestamps, and views when public, ready to sort |
| [Find competitors' best-performing Threads posts](https://apify.com/futurizerush/meta-threads-scraper/examples/benchmark-competitor-threads-accounts) | Several competitor accounts side by side in one export |
| [Turn a Threads account into an AI knowledge base](https://apify.com/futurizerush/meta-threads-scraper/examples/build-ai-training-corpus) | Clean structured text with timestamps for a RAG pipeline |
| [Audit a brand's most relevant Threads mentions](https://apify.com/futurizerush/meta-threads-scraper/examples/monitor-brand-mentions) | Brand mentions with public engagement fields and a keyword-relevance flag |
| [Find creators posting about your niche](https://apify.com/futurizerush/meta-threads-scraper/examples/find-creators-by-topic) | Accounts with followers, bio and profile links |
| [See what people said about a product this week](https://apify.com/futurizerush/meta-threads-scraper/examples/research-product-opinions) | The last 7 days of posts, newest first |
| [Look up Threads accounts matching a keyword](https://apify.com/futurizerush/meta-threads-scraper/examples/lookup-threads-accounts-by-keyword) | An account shortlist with follower counts |

### How To Use

#### Input Configuration

| Parameter | Type | Description | Example |
|-----------|------|-------------|---------|
| `mode` | string | Scraping mode: `user` (User Posts, used when `mode` is left out), `user_reposts`, `user_replies`, `search`, `profiles`, or `post_link` (the shorter `reposts` / `replies` also work) | `"user"` |
| `usernames` | array | Target usernames (required in User Posts, Reposts and Replies modes and ignored in the other modes, max 20). Accepts bare name, with `@`, or full Threads URL. A post address is read as the account in it; to save that post and the author's posts in its thread, put it in Post Links and choose Post by Link. | `["zuck", "@nike", "https://threads.com/@meta"]` |
| `post_links` | array | Threads post links (required in Post by Link mode and ignored in the other modes, max 20): post addresses on threads.com or threads.net, `/t/` short links or share links. | `["https://www.threads.com/@zuck/post/DTa3-B1EbTp"]` |
| `keywords` | array | Keywords or hashtags (required in Search and Find Profiles, optional in the three user modes to tag matching rows, ignored in Post by Link, max 20) | `["AI", "tech"]` |
| `search_filter` | string | Search mode only. `top` shows Threads-ranked relevant results. `recent` starts with the newest matching public posts and reaches further back in time as the limit grows, so a large limit covers a longer period rather than every newest post. | `"top"` |
| `search_language` | string | Search mode only, optional (beta). `english` (default), `japanese` or `chinese` (Traditional). Returns more posts written in that language and fewer of the rest. Many keywords will not change at all. | `"english"` |
| `start_date` | string | Search mode only. Show posts from this date onward (YYYY-MM-DD or "7 days"). Dates are counted in UTC. | `"7 days"` |
| `end_date` | string | Search mode only. Show posts up to this date (inclusive); relative values count back from today. Dates are counted in UTC. | `"2026-08-25"` |
| `max_posts` | number | Results per user or search keyword (10-10000). In User Posts, high limits need enough public posts on that account. In Search, this is a cap and available public results may be lower. Find Profiles uses your selected limit up to 100 accounts per keyword; a setting above 100 does not expand that account-search window. In Post by Link it is the most posts per link, at most 100. | `50` |

Note: Date options, sort order and preferred language apply to **Search** mode only, Post Links to **Post by Link** mode only, and Usernames to the three user modes only; **Post by Link** does not use Keywords either. A setting the chosen mode does not use is ignored, even if it is still filled in, and the run proceeds normally. The run log says when it ignored date options or Post Links, and when Post by Link ignored Usernames or Keywords.

##### Input example

```json
{
  "mode": "search",
  "keywords": ["coffee", "#latteart"],
  "search_filter": "top",
  "max_posts": 100
}
```

#### Mode 1: Scrape User Posts (with Profile Data)

Extract posts and available public profile information from a specific user:

> 📺 **Video tutorial**: [See Which Threads Posts Get More Views | Apify Tutorial](https://youtu.be/51mYc7DJERE)

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

##### Optional: flag a user's posts by keyword

Add `keywords` in User Posts, User Reposts or User Replies mode to flag which returned rows mention your terms in their text, topic tag or link preview title. Nothing is **removed**; each row gets a `keyword_match` value you can filter later.

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

##### Batch Scraping Multiple Users

Scrape posts from multiple users in one run (up to 20 usernames):

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

This returns:

- Available public bio and follower count
- Contact information extracted from bio (emails, phones, links)
- Recent public posts with engagement metrics when publicly available (likes, replies, reposts, shares, views)
- Profile verification status
- Media attachments
- Mentions and hashtags: `mentions` lists usernames found in the text, while
  `mentioned_users` and `mentioned_accounts` list the accounts the platform itself
  resolved as tagged; the two can differ on a given post

#### Mode 2: Search Posts by Keyword or Hashtag

Find public posts about a keyword or hashtag. Result volume depends on what Threads shows publicly for that term at run time.

> 📺 **Video tutorial**: [Find Potential Customers in Threads Discussions | Apify Tutorial](https://www.youtube.com/watch?v=zMtWu0syfS8)

> **Tip**: Include or omit the `#`: both `AI` and `#AI` work. Very specific or cross-language phrases may return fewer public results.

##### Understanding Sort Order

| Sort Order | Best For | What You Get |
|------------|----------|--------------|
| **Top** (`top`) | Discovering notable content | The posts Threads surfaces as most relevant for that term. Row order is not a popularity ranking. |
| **Recent** (`recent`) | Monitoring new activity | Starts with the newest matching public posts and reaches further back as the limit grows; sort `created_at` descending for one combined timeline |

##### Preferred Result Language (beta, optional)

Some keywords are used by people writing in more than one language, so the results arrive mixed together. Pick a language here and you get more of the posts written in it, and fewer of the rest.

| When it helps | When it changes nothing |
|---------------|--------------------------|
| The same keyword is typed the same way in another language: a product name in Latin letters, or a word Chinese and Japanese write with the same characters | A keyword only one language uses, which already returns that language |

Leave it on `english` if you have no preference. Many keywords come back unchanged.

```json
{
  "mode": "search",
  "keywords": ["旅行"],
  "search_language": "chinese",
  "max_posts": 50
}
```

##### Top Results

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

##### Recent Posts

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

#### Mode 3: Find Profiles (Discover Account Matches by Keyword)

Discover public Threads **account matches** for a keyword. Each keyword uses your `max_posts` limit, up to 100 accounts, with available public profile details such as follower count, biography, links, and extracted contacts. This is a maximum, not a promise that every run reaches it. Threads may return fewer accounts, and its matches can change between runs. This mode checks a bounded account-search window; it does not claim to find every matching account on Threads. An account matched by two of your keywords is still delivered once.

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

Output rows are **account profiles** (not posts), with key fields such as `username`, `display_name`, `bio`, `followers_count`, `is_verified`, `profile_url`, `external_links`, `emails`, `phones`, and `search_keyword`. Available public profile details are included for the returned accounts. Follower counts and other nullable fields remain `null` when unavailable. Empty biography or contact fields mean that information was not available in the public details collected; they do not prove that the account has no biography or contact information.

Every row includes `record_type`: `post` for User Posts, Reposts, Replies, Search and Post by Link rows, and `profile` for Find Profiles rows.

> **Local search tip**: For local account discovery, include the place name in the keyword (e.g. `Brooklyn coffee` rather than only `coffee`).

#### Mode 4: Scrape User Reposts

> **(beta)** Reposts and Replies are labelled beta in the input form. Every row carries the same columns as User Posts; in this mode the ones described below are the ones that get filled in. A run can occasionally return fewer rows than the account has, and the run summary cannot always tell; running it again may return more, and saves and charges the rows it collects again.

Collect the posts an account **reposted**, rather than the posts it wrote:

```json
{
  "mode": "user_reposts",
  "usernames": ["natgeo"],
  "max_posts": 50
}
```

Each row is the **original post**, with its own author and engagement fields, plus three
columns saying who reposted it and when: `reposted_by_username`, `reposted_by_user_id` and
`reposted_at`.

If two of the accounts you asked for reposted the same post, you get one row per account,
not one row in total.

#### Mode 5: Scrape User Replies

> **(beta)** As with Reposts: the same columns as User Posts, with the ones below filled in for this mode, and a run can occasionally return fewer rows than the account has, and the run summary cannot always tell; running it again may return more, and saves and charges the rows it collects again.

Collect the public replies an account **wrote**:

```json
{
  "mode": "user_replies",
  "usernames": ["mosseri"],
  "max_posts": 50
}
```

Each row is the account's own reply, with the same fields any other post row carries. When
the conversation shows which post was answered, the row also carries that post: its code,
link, author and text (`replied_to_*` columns). Not every conversation shows it, so on some
accounts most replies arrive without it, and `replied_to_available` tells you row by row.

This mode collects the replies **an account wrote**, wherever it wrote them. If you
want the other direction, the comment thread **under one specific post**, that is a
different tool: [Threads Replies Scraper](https://apify.com/futurizerush/threads-replies-scraper).

Rows from all three user modes carry `source_tab` (`posts`, `reposts` or `replies`);
Search and Post by Link rows leave it empty. So a
combined export stays sortable by where each row came from.

#### Mode 6: Save a Post and Its Thread (Post by Link)

> **(beta)** A newer mode: run one or two links first and check the rows.

Paste up to 20 Threads post links. For each link the run saves the post itself first, then the author's
own posts in the same thread, in thread order:

```json
{
  "mode": "post_link",
  "post_links": ["https://www.threads.com/@zuck/post/DTa3-B1EbTp"],
  "max_posts": 50
}
```

What a link saves:

- **The linked post, then its thread**: the author's posts above it, the author's continuation below it,
  and the author's own answers under the thread's posts, as the post pages show them.
- **A reply to another account is saved on its own.** When the linked post answers someone else, or
  continues the author's reply to someone else, it is a conversation rather than the author's thread, so
  only that post is saved.
- **Max Results counts per link**, up to 100. A thread longer than that keeps the posts nearest to the
  one you linked.
- **A post two links share is saved once.** If two links point into the same thread, each post is one row,
  and both links list it in `link_items`. Two entries that name the same post (the same address with and
  without `/media`, for example) are read as one link: the log says so, and `link_items` lists it once.
- **After the linked post, rows come in thread order.** Each post follows the post it answers as the site
  lists the thread; where two pages list posts in different orders, they follow their posting time. Posts
  found after a run is moved or resurrected come after the ones saved before it; `thread_position` gives
  each post's place in the thread as the pages showed it when that post was saved. For a repeated post,
  this is the position read for the link that saved it first.

Links it reads: post addresses on threads.com or threads.net (with or without `/media`, a slug or
tracking parameters), `/t/` short links and share links. A profile link, an account name, or one line
holding two links is skipped, and the log and `entries_skipped` name it.

This mode adds six columns: `requested_post_url` (the link the row was saved for, in standard form: a
short link as `https://www.threads.com/t/CODE`, a share link keeps its share address), `is_requested_post` (true on a
post one of your links points to), `thread_position` (the post's place in the author's thread as the pages
showed it when the post was saved, 1 for the first post; null when the pages did not show it, for a post
saved on its own as part of a reply to another account, or on a post another link of the run saved first
without placing it), `thread_first_post_code`,
`media_url_types` (what each entry of `media_urls` is: `photo`, `video` or `video_cover`) and
`video_cover_url` (a single video's cover image). A single photo or video is in `media_url`, and
`media_urls` lists a carousel's items. A GIF the site shows a signed-out visitor only as its placeholder
image has an empty `media_url`. How each link ended is in `link_items` (see **What To Expect**).

Running a link again in a new run saves its posts again, and they are charged again, including posts this
run already saved. To continue this run instead, resurrect it: it checks what it already saved and saves
nothing twice; only its start is charged again.

Rows in this mode carry no author profile details such as followers or bio; User Posts
has those.

This mode saves the author's own posts in a thread. For everyone's replies under a post, use
[Threads Replies Scraper](https://apify.com/futurizerush/threads-replies-scraper).

#### Periodic Topic Monitoring

If you want to monitor keywords on a schedule (for lead generation, brand-mention tracking, or competitor monitoring), pair `mode: "search"` with `search_filter: "recent"` and run the actor automatically:

```json
{
  "mode": "search",
  "keywords": ["YOUR_KEYWORD_1", "YOUR_KEYWORD_2"],
  "search_filter": "recent",
  "max_posts": 30
}
```

**Suggested workflow**

1. **Schedule the actor**: Use [Apify Schedules](https://docs.apify.com/platform/schedules) to trigger regular runs.
2. **Review each run's dataset**: every post includes a unique identifier, and a timestamp when the site shows one.
3. **Handle your own downstream workflow**:
   - Deduplicate against your existing records using each post's unique identifier
   - Optionally filter by post timestamp to keep entries within your time window
   - Trigger your own notifications or follow-up workflow
   - Append new entries to your workspace or spreadsheet

**Tips**

- Each run returns a finite batch of matching public posts. For busy keywords, review the returned timestamps and adjust your schedule to match your monitoring needs.
- Runs are independent: the same post can appear again in a later run, which leaves deduplication and retention entirely in your hands.

#### Date Filtering (Search Mode Only)

Narrow search results to a date range. The range can be a recent window (for example the last 7 or 30 days) or an earlier period. Both relative dates (`"7 days"`, counted back from today) and absolute dates (`YYYY-MM-DD`) are accepted.

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

### Output Format

#### Viewing Your Data

Use the field-focused dataset views to inspect posts, profiles, engagement fields, or contact fields. Some views are most useful for specific modes. Switch to "All fields" when you need the complete record.

- 🧵 **Posts**: post content, dates, author, media flags, and search fields
- 📊 **Engagement**: likes, replies, reposts, shares, views, and analysis flags
- 👥 **Profiles**: accounts found in Find Profiles mode
- 🔗 **Contacts**: public profile links and contact fields
- 📌 **Post by Link**: each link's posts with their place in the thread

**Image and video links**: `media_url`, `media_urls` and the profile picture fields point at
Threads' own media servers, and those links stop working a few days after the run. Download the
files you want soon after the run finishes, or run it again to get fresh links. The post and
profile links (`post_url`, `profile_url`) do not expire.

#### Complete Post Record Example

Each post is saved as a separate record. Below is an illustrative example of the fields from **user mode**. The account, URL, text, dates, and numbers are fictional placeholders.

```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": [],
  "media_width": null,
  "media_height": null,
  "has_audio": null,
  "music_artist": "",
  "music_title": "",
  "music_song_id": "",
  "poll_options": [],
  "poll_votes": [],
  "poll_total_votes": null,
  "poll_is_closed": null,
  "is_ai_generated": false,
  "is_gif": false,
  "is_sticker_post": false,
  "sticker_count": 0,
  "sticker_ids": [],
  "sticker_urls": [],
  "hashtags": [],
  "mentions": [],
  "urls": [],
  "is_pinned": false,
  "is_edited": false,
  "is_paid_partnership": false,
  "accessibility_caption": "",
  "is_reply": false,
  "reply_to_username": "",
  "reply_control": "everyone",
  "is_quote_post": false,
  "quoted_post_url": "",
  "is_repost": false,
  "reposted_post_url": "",
  "repost_code": "",
  "repost_url": "",
  "reposted_by_username": "",
  "reposted_by_user_id": "",
  "reposted_at": "",
  "replied_to_post_code": "",
  "replied_to_post_url": "",
  "replied_to_author_username": "",
  "replied_to_author_user_id": "",
  "replied_to_text": "",
  "replied_to_created_at": "",
  "replied_to_available": null,
  "replied_to_like_count": null,
  "replied_to_reply_count": null,
  "replied_to_repost_count": null,
  "replied_to_quote_count": null,
  "replied_to_share_count": null,
  "conversation_id": "",
  "source_tab": "posts",
  "is_spoiler": false,
  "language": "",
  "topic_tag": "",
  "location_name": "",
  "location_id": "",
  "link_title": "",
  "mentioned_users": ["example_partner"],
  "mentioned_accounts": [{ "username": "example_partner", "user_id": "10000000002" }],
  "scraped_at": "2026-04-25T10:00:00+00:00",
  "username": "example_creator",
  "requested_username": "example_creator",
  "user_id": "10000000001",
  "display_name": "Example Creator",
  "profile_url": "https://www.threads.com/@example_creator",
  "is_verified": true,
  "followers_count": 54000,
  "bio": "Research notes and product updates",
  "profile_pic_url": "https://...",
  "profile_pic_hd_url": "https://...",
  "fediverse_enabled": true,
  "external_links": ["https://example.com"],
  "emails": [],
  "phones": [],
  "bio_links": ["https://example.com"],
  "profile_tags": ["AI", "Tech"],
  "podcast_name": "",
  "podcast_url": "",
  "podcast_platform": "",
  "search_filter": null,
  "search_keyword": null,
  "search_keywords": [],
  "keyword_match": null
}
```

> In Search mode, `search_keyword` remains the first selected keyword for backward compatibility, while `search_keywords` lists every input keyword that independently selected that deduplicated row. `keyword_match` is true when the post's text, topic tag or link preview title contains at least one of those selected keywords: as typed, written without spaces, or, for a keyword of several words, with every one of those words somewhere in the same field. When every word of a keyword has four letters or more, a post that writes the same word with accents or with a hyphen inside it can match too, so "cafe" also matches "café" and "covid19" matches "COVID-19". A keyword is listed only when it actually selected that row for delivery. In the three user modes, `search_keywords` is empty; `search_filter` stays `null`, and `search_keyword` plus `keyword_match` are `null` unless you supply `keywords` to tag matching rows.

If a later Search or Find Profiles keyword turns out to match a row that was already
saved, Run Results includes `keyword_membership_updates`. Match the Dataset row using the
entry's `match_field` and `match_value`, then add its `added_keywords` to your analysis.
For a username match, compare without case. This keeps each keyword's relationships, up to
that keyword's limit of results, without creating a duplicate Dataset row.

The same rule applies when two User Posts, Reposts or Replies inputs resolve to the
same saved result, such as an old handle and its renamed handle. Run Results includes
`input_membership_updates`: match the Dataset row with all fields in `match_fields`,
then add `added_usernames` to your input-to-result mapping. The Dataset still contains
one physical row.

> User Posts, Reposts and Replies also include `requested_username`, the account you asked for. In User Posts and Replies it matches `username`, the author of the row. In **User Reposts it does not**: the row is the original post, so `username` is that post's author while `requested_username` is the account whose reposts you asked for. In all three modes, if Threads redirects an old handle after an account rename, `requested_username` keeps your original input.

### What To Expect

**Result availability**

- Result volume depends on how much public content exists for your query, so different
  modes and queries return different amounts.
- If a run looks lighter than expected, open **Run Results** (the run summary on the run's
  Output tab in the Apify Console). `collection_status` says whether the run finished
  (`complete`) or not (`partial`), and `collection_stop_reason` names why. A run is `partial`
  when it stopped early or part of it could not be completed. In Search mode it is also
  `partial` when a keyword came back with fewer posts than you asked for, unless the run saved
  no posts at all. In Post by Link mode it is also `partial` when the pages did not show the
  whole thread. An account that has no more posts to show, or that could not be opened,
  still counts as finished. In Search, a broader query or the other sort order may find more.
- In a batch run, one username or keyword can fail while others still save results.
  **Run Results** lists which ones failed and why, and gives each account its own result in
  `user_items` (each Search keyword in `search_items`), so you know which ones did not finish.
  In Find Profiles, a keyword that saved accounts while some account details could not be
  loaded is not always listed in Run Results; when it is not, the run log says some of its
  account details could not be completed.
- In the post modes, **Run Results** also reports `result_quality`: how completely the optional extra details
  (such as view counts and author profiles) could be filled in. It is separate from
  `collection_status`: a run can deliver every requested row and still show `partial` or
  `unavailable` here. `author_profiles_missing` counts the post authors whose profile details
  were looked up but could not be loaded (when a run stops early, the authors it had no time to
  look up are not counted, and `result_quality` shows `partial`), and `view_counts_missing`
  counts the post rows this run checked that came back without a view count.
  Those rows are saved as they are. A new run may return the same posts with those details
  filled in, and saves and charges them again; after a short time limit, allow it more time first. In Search, a post whose public details could not be read can instead
  be left out. It is not counted in these numbers or in `result_quality`, so `result_quality`
  can show `complete` while a keyword came back short; that keyword's entry in
  `search_items` shows it.
- An entry that is not a Threads username or profile link, a Post Links entry that is not a
  Threads post link, or a keyword that cannot be searched (for example one made only of `#`
  signs, or one longer than 100 characters), is skipped and the rest is collected. The log
  names each skipped entry, the closing status names up to three per field, and
  `entries_skipped` in Run Results lists them all. The run stops before collecting only when
  none of the usernames can be used (or, in Search and Find Profiles, none of the keywords; in
  Post by Link, none of the post links). In User Posts, User Reposts and User Replies mode it also
  stops when none of the keywords you added can be used, unless each of them is made only of
  `#` signs: those are skipped and the run goes on without keywords. When the run stops, its
  message names an entry that could not be used and says why, and `entries_skipped` lists it
  with the other entries that were skipped.
- `mixed_item_results` means this run ended in more than one way, either because keywords
  finished differently or because one keyword stopped for more than one reason. **How to
  read Search stopping reasons** and **How to read account stopping reasons** below say how
  to read each one.

**Working without a login**

This actor reads only what Threads shows publicly, so niche or uncommon keywords can
return very few results, or none, even when you can see those posts while logged in.
When `no_results` appears, it means the public search window checked in this run returned
no matching rows. It does not prove that no matching post exists anywhere on Threads.
If the search was interrupted before it finished, the run is marked partial, so an empty
result is never presented as a confirmed one.

**How to read account stopping reasons**

Runs in User Posts, Reposts, Replies and Find Profiles report one of these:

- `no_more_public_posts` / `no_more_public_reposts` / `no_more_public_replies`: the account
  had nothing further to show publicly on that tab, so the run has everything it could see.
- `no_more_public_accounts`: no keyword reached its effective limit, and the account-search
  windows checked in this run showed no further matches to save. An account already saved under
  another keyword counts for each keyword that listed it and is delivered once. This does not
  establish that every matching account on Threads was found; available matches can change.
- `mixed_item_results`: entries ended in different ways, for example some keywords reached their
  effective account limit and others did not. In Find Profiles, each row's `search_keyword`, and
  `keyword_membership_updates` in Run Results, show which keywords each account came from.
- `requested_limit_reached`: in User Posts, Reposts and Replies, at least one account reached
  the number you asked for, and raising the limit can return more from that account. In Find
  Profiles it means every keyword reached the effective limit: the smaller of `max_posts` and
  100 per keyword. Raising it may return more available accounts up to that ceiling, but does
  not guarantee more results.
- `search_window_limit_reached`: in Find Profiles, the run could not confirm that all available
  account matches in the requested window were collected. More matches may be available, or
  some results could not be confirmed. The collection is marked `partial`; a setting
  above 100 does not expand the per-keyword account-search window.
- `no_results`: nothing public was found for that account or keyword in this run.
- `temporarily_unavailable`: part of the collection could not be finished this time, so some
  rows may be missing. Running it again may return them.
- `budget_reached`, `time_limit_reached` and `run_stopped_early` mean the run ended on a
  limit you or the platform set, keeping everything saved up to that point. When the run
  reaches its time limit or is stopped, rows already saved remain available. An account still
  being collected is listed in `user_items` as `partial` when it has saved rows. An account
  that had no rows yet, or had not started, is listed in `failed_items`. In Find Profiles, a
  keyword whose accounts were still loading saves the accounts already read and is listed in
  `keywords_cut_short`; with none read yet, it is listed in `failed_items`. Rows saved from that
  moment on may arrive without view counts (`view_count_status` is `not_checked`), in Search
  without author profile details, and in User Reposts without the original author's. A new run starts from the beginning,
  so results this run already saved are saved and charged again when it collects them.

**Per-account results in `user_items`**

In User Posts, Reposts and Replies, Run Results lists in `user_items` every username the run
could use, in the order you entered them. Entries it could not use are listed in
`entries_skipped` instead, and a run that ends before collecting starts, or on an unexpected
error, has no `user_items`. Each entry has `requested_username` (the same value as the
`requested_username` column on that account's rows), `requested`, `results_saved`,
`quota_reached`, `status` (`complete`, `partial` or `failed`) and `stop_reason`. A `complete`
account reached the number you asked for, had nothing further to show, or could not be opened;
its `stop_reason` says which. A `partial` account
delivered the rows counted in `results_saved` and stopped early, and its `stop_reason` says why;
run just that account again to try for the rest (a new run starts from the beginning, so rows
this run already saved for that account are saved and charged again when it collects them). A
`partial` account whose `stop_reason` is
`budget_reached` can show `results_saved` 0, because this run's max charge limit was reached
before any of its rows could be delivered: raise the max charge limit before you run it again.
A `failed` account saved nothing this time.
Besides the reasons above, an account can report `account_not_available` (the account could not
be opened: the name may be wrong, or Threads did not show that account to a visitor who is not logged in this time), `account_private`, or one of the per-attempt codes listed under
**Per-keyword codes in `search_items`** below. `results_saved` counts that account's confirmed
rows, including a row first saved under another account in the same run, which
`input_membership_updates` lists, so filtering the Dataset by `requested_username` alone can show
fewer rows. Like `collection_stop_reason`, `user_items` describes this run only and never proves
that every public item of the account was checked.

When any account in `user_items` is not `complete`, `collection_status` is `partial`. The other
way round does not always hold: an account that reached the number you asked for is `complete`
even if collecting stopped early after that, and `collection_status` can then still read
`partial`. `user_items` is what tells you which accounts to run again. The run's status line may
also name some of these accounts; `user_items` lists all of them.

**Per-link results in `link_items`**

In Post by Link, Run Results lists in `link_items` every link the run could use, in the order you
entered them; a run that ends on an unexpected error has no `link_items`. Each entry has `requested_post_url` (the value in the column of the rows this link saved first),
`requested` (Max Results, at most 100), `results_saved`, `quota_reached`, `status` (`complete`,
`partial` or `failed`), `stop_reason`, `post_code` (the post the link named or led to) and `post_codes`
(the link's saved posts, its own first). `results_saved` also counts posts another link of the run saved
first, so the sum over links can be more than `posts_saved`.
A link can be `complete` with no rows when Threads answered but did not show a post at that link;
this describes the public response, not proof that the post does not exist.

How to read a link's `stop_reason`:

- `thread_collected`: every post of the author's thread that the pages showed was saved, and the pages
  showed nothing more following.
- `requested_limit_reached`: the link reached Max Results; the posts nearest to your link were saved.
- `reply_to_another_account`: the post is part of a reply to another account, so it was saved on its own.
- `post_not_served`, `sign_in_page_served`, `page_without_the_post`, `short_link_not_resolved`: Threads
  did not show a post at this link this time (no such post, a sign-in page, a page without the post, or a
  link that led to no post). Check that the link opens the post in a browser where you are not signed in.
- `thread_not_fully_shown` (`partial`): the posts the pages showed were saved, but the pages did not show
  the author's whole thread or establish where it starts or ends. The thread may contain more posts than were
  visible. If it continues after the saved posts, linking a later post of the same thread may reach more.
- `temporarily_unavailable`, `request_unavailable`: a page the link needed could not be read this time,
  for example because Threads asked for a slower pace. Running the link again may return it.
- `budget_reached`, `time_limit_reached` and `run_stopped_early` mean the run ended on a limit you or the
  platform set, keeping everything saved up to that point.
- `save_incomplete`, `save_unavailable`: some of the link's posts could not be saved, whether they were
  saved could not be checked, or the run stopped on a save before the link was read. Resurrect the run to
  try again: it checks which posts were saved and saves nothing twice; only its start is charged again. A new run saves and charges all of
  the link's posts, including those this run already saved.
- `unexpected_error`: the link, or a page it needed, could not be processed this time. Running it again may
  complete it.

A thread includes the author's answers that its posts' pages show. Threads shows a busy post's replies a
page at a time, so an answer by the author further down a long reply list may not be on the page and is
not included; the link can still read `thread_collected`.

**How to read Search stopping reasons**

- `requested_limit_reached`: every keyword reached the number you asked for. Raising the
  limit can return more. When some keywords reached it and others ran out first, the run
  reports `mixed_item_results` instead.
- `search_window_limit_reached`: the run reached the limit of what one run covers for that
  keyword. More posts may exist; a date range lets a run look at just the period you need.
- `date_filter_unverifiable`: some posts did not carry a public date, so they could not be
  placed inside or outside your range. The run is marked partial rather than reported as an
  empty range.
- `search_depth_limit_reached`: the run reached its collection limit for that keyword before your
  number. More posts may remain.
- `search_time_budget_reached`: the time allowed for that keyword ended before reaching your
  number. More matching posts may remain.
- `low_yield_stop`: the run stopped because it was no longer finding new posts for that
  keyword. More posts may still exist.
- `mixed_item_results`: keywords had different completion outcomes or stopped for
  different reasons. It does **not** mean Threads has no more matching posts. Check
  `search_items` in Run Results to see which keyword was short and why; this is not
  proof that the shorter keywords are exhausted.
- `budget_reached`: the run stopped at the max charge limit you set for it. Everything saved
  before that point is kept. To get more, start a new run with a higher limit: a new run starts
  from the beginning, so results this run already saved are saved and charged again when it
  collects them.
- `time_limit_reached` / `run_stopped_early`: the run ended before finishing, for
  example at its time limit or after being stopped, and wrapped up with what it had.
- `temporarily_unavailable`: part of this run's work could not be finished on this attempt,
  so some posts may be missing: for example a page could not be loaded, results could not be
  saved, or some posts were left out because their public details could not be read.
  `search_items` gives each keyword's own reason (see the codes below). Running it again may
  return them.

**Per-keyword codes in `search_items`**

Each keyword in `search_items` also reports its own `status` (`complete`, `partial`, or
`failed`) and its own `stop_reason`. Besides the reasons above, a keyword can report an
operational code about this run's attempt: `setup_unavailable` (collection could not be set
up for this keyword or account this time; for an account that saved some rows, it was loading
the rest that could not be set up), `request_timeout` or `request_unavailable` (a page
request ran out of time or could not be completed), `save_unavailable` or
`save_incomplete` (prepared rows could not be saved, or only partly saved),
`details_unavailable` or `details_incomplete` (some posts were left out because their
public details could not be read on this attempt), or `unexpected_error`. These codes
describe this run's attempt, not the keyword or account itself; running again may complete them.

In the post modes `posts_saved` counts unique physical Dataset rows; in Find Profiles `accounts_saved` does. `search_items[].results_saved` counts
confirmed keyword memberships, so one deduplicated post selected by two keywords counts
once in `posts_saved` and once for each keyword. This is expected and does not mean the
row was saved twice.

If you need content that is visible only inside your own logged-in account, this is not
the right tool.

### FAQ

**Q: What engagement metrics can I get?**
A: Likes, replies, reposts and quotes come through on public posts as Threads provides them; a count Threads does not provide is left empty rather than guessed. Views come through whenever Threads publishes them. Share counts are not published for every post, so `share_count` is empty on some rows and is best treated as a bonus rather than a metric to plan around. `view_count_status` tells you which of three things happened: `available` (a number was read, including 0), `not_public_yet` (the post is too recent for a view count to exist yet), or `not_checked` (the count was not read on this run; a new run may pick it up, and saves and charges its rows again; after a short time limit, allow it more time first). In Run Results, `view_counts_missing` counts the post rows this run checked that had no view count, and `view_counts_not_public_yet` reports how many of those are simply too recent.

**Q: How does contact information extraction work?**
A: Contact fields depend on the public bio text and profile links. The actor does not read text inside images or on linked pages.

**Q: Is there an identifier I can join on besides the username?**

A: Yes. Every post author and every profile record carries `user_id` next to `username`. A username is the account's handle; `user_id` is a separate identifier assigned by the platform and is not derived from it. Across our runs the same account returns the same `user_id` in User Posts, Search and Find Profiles alike, so it is the field to join on when a handle alone would be ambiguous. When it could not be resolved for a record it is `null`, never an empty string, so it is always clear which case you are looking at.

**Q: How do I see the complete field set?**
A: In the Apify console, switch to "All fields". You will see the complete record fields, including fields that may be `null` for some records.

**Q: Does it support batch scraping of multiple users or keywords?**
A: Yes. You can enter up to 20 usernames, 20 keywords or 20 post links in one run. Results are combined into the same dataset. If an entry cannot be used, it is skipped and named, and the others still run, as long as every field you filled in for the chosen mode still has at least one entry the run can use. **What To Expect** says exactly when the run stops instead.

**Q: I sent a setting through the API and it had no effect. Why?**
A: Two things to check. First, the field name: a name the Actor does not recognize is ignored, so compare it with the table under **Input Configuration**. For some near misses, such as `maxPosts` for `max_posts`, the run log names the field it ignored and the setting it most likely means. Second, the mode: a setting the chosen mode does not use is ignored; the note under the table lists the settings that only some modes use.

**Q: One account in my batch was only partly collected. How do I know which one?**
A: `user_items` in **Run Results** lists every username the run could use, each with its own `status`; the run's status line may also name some of them. Run only the accounts marked `partial` or `failed` again. A new run collects each account from its most recent items again, so it can also return rows you already have.

**Q: Can I tell which posts are sponsored / paid partnerships?**
A: Every post includes an `is_paid_partnership` field, and `true` means a paid-partnership label was publicly shown for that post. Threads rarely shows this label in public data, so `false` does not confirm that a post is not sponsored.

**Q: Can I see quote posts and reposts, and the original they reference?**
A: Yes. Quotes are marked on the row itself with `is_quote_post` and `quoted_post_url`. Reposts come from 🔁 User Reposts mode, where each row is the original post and `reposted_by_username`, `reposted_by_user_id`, `reposted_at` and `source_tab` say who reposted it and when. `is_repost` does not mark these rows; use `source_tab` or `reposted_by_username`.

**Q: Can I distinguish top-level posts from replies?**
A: Yes, when reply context is present in the returned public data. `is_reply` marks replies, `reply_to_username` shows who is being replied to, and `reply_control` reflects the reply-audience setting when available.

**Q: What about image alt text and media size?**
A: When available, `accessibility_caption` contains an image description; otherwise it is an empty string (""). `media_width` and `media_height` contain the available media dimensions in pixels and are null when not available (for example text-only posts).

**Q: Can I tell whether a post has a public AI-content label or whether a video has sound?**
A: `is_ai_generated` is true when the post carries an AI-content label, false when the post states it has none, and null when it cannot be determined. `has_audio` is true/false for checked video posts and null for non-video posts or unavailable detail.

**Q: Is there a Fediverse / ActivityPub signal?**
A: Not a dependable one. `fediverse_enabled` repeats a badge flag from the profile's public details. Most accounts read true, including accounts that do not share to the Fediverse, so do not use it to tell who does. It is null when profile details were not available for that row.

**Q: Do I need to choose between hashtag and full-text search?**
A: No. Enter your keyword with or without `#`, then pick a `top` or `recent` sort order. Results depend on what Threads makes publicly available.

**Q: How does Find Profiles work, and how many accounts can it return?**
A: Find Profiles (`mode: "profiles"`) checks public account matches for each keyword and adds available public profile details. The maximum per keyword is the smaller of `max_posts` and 100. For example, `max_posts: 50` allows up to 50 accounts; `max_posts: 200` still allows at most 100. Reaching the maximum is not guaranteed, and a completed search window does not mean every matching account on Threads was found. Related keywords can surface different accounts, with duplicate accounts saved once.

**Q: How can I find local accounts?**
A: Put the place name directly in the keyword (e.g. `austin coffee`) so the search phrase is what the matching is based on. Geo-targeting is not supported.

**Q: Can I choose the language of my search results?**
A: In Search mode you can set `search_language` to `japanese` or `chinese` (Traditional) to get more posts written in that language; `english` is the default. It is a preference, not a filter: posts in other languages can still appear, and many keywords will not change at all. It is most useful when the same keyword is written the same way in more than one language. It applies to Search only: Find Profiles, the user modes and Post by Link do not use it.

**Q: Why do search results seem unrelated to the keyword?**
A: Threads search ranking is not strict keyword-only matching. Results can include broadly related content and sometimes unrelated content. Use `keyword_match` as a relevance aid in downstream filtering; it is true when the post's text, topic tag or link preview title contains at least one keyword in `search_keywords` (as typed, written without spaces, or with every word of a multi-word keyword somewhere in the same field; when every word of the keyword has four letters or more, it can also match when the post adds accents or a hyphen inside the word), but it is not an exact-match guarantee.

**Q: Why do I get fewer results than my max_posts limit?**
A: `max_posts` is a ceiling, not a promise. One run checks a bounded public search window, so it can return fewer rows even for an active keyword. Read `collection_stop_reason` in **Run Results**: it names why the run came back short (the Search reasons are listed under **How to read Search stopping reasons** above), and `search_items` gives each keyword's own reason (listed under **Per-keyword codes in `search_items`** above), for example that some of its posts were left out because their public details could not be read. None of the short-result reasons means every matching post on Threads was checked. Threads also limits how much of a search a visitor who is not logged in can see, and that visible window changes over time. A keyword whose search showed no posts at all reads `complete` with `no_results`, which does not prove that no such posts exist. You can set a date range for just the period you need, or try a broader keyword, another sort order, or split the search into related keywords (up to 20 in one run).

**Q: What time limit should I set for a run?**
A: Keep the default of 3,600 seconds (**Timeout** in the run options), and give a run more time when its `collection_stop_reason` in **Run Results** reads `time_limit_reached`. A run ends as soon as its work is done, so a longer limit does not make it run longer. In Search, a keyword that stopped on `search_time_budget_reached` gets no more search time from a longer limit. With a limit of a minute or two, the run saves what it has before the limit: some or all rows can come without view counts or author details, and a larger request can come back short. With only seconds, a run can end before it saves any row. In **Run Results**, `collection_status` shows `partial` when rows are missing; in the post modes `result_quality` shows `partial` when details are, and in Find Profiles `keywords_cut_short` names the keywords the limit cut part way.

**Q: Why are bio or followers_count sometimes empty in Search mode?**
A: Public profile details are included when available, but some accounts expose limited information, and a run that reached its time limit may leave them unread. Unavailable follower counts and other nullable fields stay `null`; biography text or contact lists can be empty. These missing values are not replaced with invented counts or contact details.

### Explore Threads Workflows

- [Threads Replies Scraper](https://apify.com/futurizerush/threads-replies-scraper): collect public replies and comments for conversation analysis.
- [Threads 海巡 - 貼文、轉發、回覆、個人檔案與搜尋](https://apify.com/futurizerush/meta-threads-scraper-zh-tw): the Traditional Chinese edition of this Actor, with a zh-TW interface and output labels.

### Disclaimer

This Actor collects what Threads shows publicly to visitors who are not logged in. You are solely responsible for how you use it and for ensuring that your use of the Actor and any data it returns, including personal data such as contact details in public bios, complies with all laws, regulations and platform terms applicable to you. Data availability, completeness, and accuracy may vary over time and between runs. This Actor is not affiliated with, endorsed by, or connected to Meta or Threads. The developers accept no liability for how this tool or the data it returns is used.

***

**Keywords**: Threads scraper, Threads search scraper, Threads post scraper, Threads thread scraper, scrape Threads post by URL, Threads data scraper, Meta Threads scraper, Threads post extractor, Threads profile scraper, Threads hashtag search, Threads keyword search, Threads search without login, Threads data extraction, export Threads posts, download Threads data, Threads exporter, Threads posts, Threads engagement metrics, follower count scraper, Threads bio email extractor, Threads account finder, influencer discovery, Threads influencer research, social media scraper, social media monitoring, brand monitoring, competitor analysis, competitor intelligence, trend research, content research tool, social listening tool, market research, Instagram Threads, public Threads data, Threads automation, Threads search, OpenClaw, Claude Code, Gemini CLI, Antigravity, Codex, ChatGPT, GrokBot, Meta Muse, Orca, Herdr, Pi, Jev

# Actor input Schema

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

Pick one, then fill the matching field below:
• 👤 User Posts → 👤 Usernames. Their public posts.
• 🔁 User Reposts → 👤 Usernames. What they reposted, and when.
• 💬 User Replies → 👤 Usernames. Their replies, with the post answered when shown.
• 🔎 Search → 🏷️ Keywords. Public posts for keywords or hashtags, optional dates.
• 👥 Find Profiles → 🏷️ Keywords. Account matches, up to 100 per keyword.
• 🔗 Post by Link → 🔗 Post Links. Each post plus the author's posts in its thread.

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

Required in 👤 User Posts, 🔁 User Reposts and 💬 User Replies modes (ignored in other modes). One or more Threads usernames: bare name (zuck), @-prefixed (@zuck), or full URL (https://threads.com/@zuck or https://threads.net/@zuck). 📺 Not sure how to fill this in? Watch the <a href='https://www.youtube.com/watch?v=51mYc7DJERE' target='_blank' rel='noopener'>User Posts video tutorial</a>.

## `post_links` (type: `array`):

Required in 🔗 Post by Link mode (ignored in other modes). One Threads post link per line, up to 20: a post address (https://www.threads.com/@zuck/post/DTa3-B1EbTp), a threads.net link, a /t/ short link or a share link. Each link gives its post and the author's own posts in the same thread, up to 📦 Max Results per link (at most 100).

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

Required in 🔎 Search and 👥 Find Profiles. Optional in 👤 User Posts, 🔁 User Reposts and 💬 User Replies, where matching rows are tagged and nothing is dropped. 🔗 Post by Link does not use it. The # is optional: both 'AI' and '#AI' work. In Find Profiles, adding a place name (e.g. 'austin coffee') helps surface local accounts. 📺 Not sure how to fill this in? Watch the <a href='https://www.youtube.com/watch?v=zMtWu0syfS8' target='_blank' rel='noopener'>Search video tutorial</a>.

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

A cap per user, keyword or post link: 50 when left empty, at least 10. Results share one dataset.
• 👤 User Posts / 🔁 Reposts / 💬 Replies: depends on the account's available public posts.
• 🔎 Search: public results may be fewer than your limit.
• 👥 Find Profiles: the smaller of your limit and 100 per keyword. Results may be fewer; this does not find every matching account.
• 🔗 Post by Link: how many posts per link, from the linked post outward; at most 100.

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

Only used in 🔎 Search mode. 'Top' returns what Threads surfaces as most relevant for that term; row order is not a popularity ranking. 'Recent' starts with the newest matching public posts and reaches further back in time as the limit grows, so a large limit covers a longer period rather than every newest post; sort exported created_at values for one combined timeline.

## `search_language` (type: `string`):

Optional. Only used in 🔎 Search mode; every other mode ignores it and runs normally.
Some keywords are used by people writing in more than one language, and the results mix them together. Pick a language here and you get more of the posts written in it, and fewer of the rest.
Leave it on English if you have no preference. Many keywords will not change at all: a keyword only one language uses already returns that language.

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

Used in 🔎 Search mode to show posts from this date onward. Supports YYYY-MM-DD or relative values such as '7 days' and '1 month'. Dates are counted in UTC. Other modes ignore it and run normally.

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

Used in 🔎 Search mode to show posts up to this date (inclusive). YYYY-MM-DD is recommended for clarity. Relative values such as '7 days' mean that long ago. Dates are counted in UTC. Other modes ignore it and run normally.

## Actor input object example

```json
{
  "mode": "user",
  "usernames": [
    "zuck"
  ],
  "max_posts": 50,
  "search_filter": "top",
  "search_language": "english"
}
```

# Actor output Schema

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

Scraped results: posts (User Posts / Reposts / Replies / Search / Post by Link) or accounts (Find Profiles)

## `runSummary` (type: `string`):

Run status, saved-result counts, per-account, per-keyword and per-link results, partial-result reasons, and data-quality details

# 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"
    ],
    "max_posts": 50,
    "search_filter": "top",
    "search_language": "english"
};

// Run the Actor and wait for it to finish
const run = await client.actor("futurizerush/meta-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"],
    "max_posts": 50,
    "search_filter": "top",
    "search_language": "english",
}

# Run the Actor and wait for it to finish
run = client.actor("futurizerush/meta-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"
  ],
  "max_posts": 50,
  "search_filter": "top",
  "search_language": "english"
}' |
apify call futurizerush/meta-threads-scraper --silent --output-dataset

```

## MCP server setup

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