# Threads Scraper — Posts, Profiles, Replies & Search | No Login (`anuarbakty/threads-scraper`) Actor

\[$2 / 1K posts, no start fee] Scrape Meta Threads without login: full profile history, all replies, exact views, keyword & hashtag search, accounts with emails. Only-new monitoring.

- **URL**: https://apify.com/anuarbakty/threads-scraper.md
- **Developed by:** [Anuar Bakty](https://apify.com/anuarbakty) (community)
- **Categories:** Social media, Lead generation, AI
- **Stats:** 18 total users, 12 monthly users, 74.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 posts

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

Scrape public data from **Meta Threads** (threads.com / threads.net) without a login, cookies or an account of your own. Paste profiles, post links, keywords or #hashtags into one list and get clean, flat rows ready for Excel, Google Sheets, a database or an AI agent.

- **The whole history of a profile**, back to July 2023, not the 4–25 posts most scrapers stop at. Its replies, reposts and media tabs too.
- **Replies under any post, page after page**, not only the first 25 a visitor sees, with **nested replies** up to 5 levels and the post each reply answers.
- **Exact view counts** (473,362, not "473K") and the **Instagram follower count** of the linked account.
- **Keyword and hashtag search** that reads the top results and the tag page for every spelling of the keyword, without duplicates, and can **collect all replies of every found post** in the same run.
- **Who is talking**: the follower count of every author and commenter, next to the likes, replies, reposts and quotes of each post and reply, and if you want, **a profile row for each of them** with bio, links, emails and phones from the bio and Instagram followers.
- **Account search** with followers, bio links, and the **emails and phone numbers** people put in their bio.
- **Only-new monitoring** for schedules: posts already delivered are skipped for free.
- **Fair billing**: no start fee, and filtered posts, duplicates and errors are never charged.

### What you can use it for

- **Market research**: what people say about a topic and who says it: posts, every comment under them with its likes, and the profile of each author.
- **Social listening and brand monitoring**: every public post about your brand, product or competitor, on a schedule, only what is new.
- **Competitor and creator research**: the full posting history of any account with likes, replies, reposts, quotes and views.
- **Lead generation**: accounts that post about a niche, with bio links, emails and phone numbers.
- **Audience research**: everyone who replies under a viral post or a competitor's posts, with who replied to whom and the profile of each person.
- **AI and RAG datasets**: clean post text with language, topic, links and engagement, ready to embed.
- **Archiving**: photos and videos saved before the Threads links expire.

### Quick start

Paste anything into **Profiles, posts, keywords or hashtags**, one per line:

| You paste | You get |
|---|---|
| `@zuck` or `https://www.threads.com/@zuck` | The profile row and its posts |
| `https://www.threads.com/@zuck/replies` | The replies the profile wrote, each with the post it answers |
| `https://www.threads.com/@zuck/reposts` | The original posts the profile reposted |
| `https://www.threads.com/@zuck/post/CuZsgfWLyiI` | The post with its exact view count, and its replies |
| `https://www.threads.com/t/CuZsgfWLyiI`, `threads.net` links, share links | The same, any link format works |
| `artificial intelligence` | Posts matching the keyword (with all their replies, if you turn that on) |
| `#running` | Posts of the hashtag and its tag page |
| `https://www.threads.com/search?q=coffee` | The same search as on the site |

A bare word is searched as a keyword. To add a profile, write it with `@`, or paste a column of names into **Usernames (bulk)**.

Example input:

```json
{
    "targets": ["@nasa", "https://www.threads.com/@zuck/post/CuZsgfWLyiI", "#artemis"],
    "maxPostsPerProfile": 100,
    "maxRepliesPerPost": 200,
    "replyDepth": 2,
    "postedAfter": "30 days"
}
```

### Market research in one run

What do people think about a topic, and who are they? Give the Actor a few keywords of the topic; it finds the posts, collects all comments under each, and adds a profile of everyone who wrote them.

```json
{
    "searchQueries": ["electric cars", "tesla", "ev charging", "home charger"],
    "repliesOfFoundPosts": true,
    "maxRepliesPerPost": 100,
    "replyDepth": 2,
    "includeAuthorProfiles": true,
    "postedAfter": "3 months"
}
```

You get three kinds of rows, linked to each other:

- **Posts** matching each keyword (`query` says which one), with likes, replies, reposts, quotes and the author's follower count.
- **Replies** under every post, nested as deep as you set. `rootPostId` and `parentPostUrl` tie each reply to its post, and `likeCount` shows which opinions people support.
- **Authors**: one row per person (`type: "author"`) with bio, links, emails and phones from the bio, followers and Instagram followers. `foundViaPostUrl` is the post or reply that brought them in.

Sort the replies by likes in Excel or Google Sheets to see the most supported opinions, or give the dataset to an AI agent and ask what people like and complain about. Each keyword gives up to a few dozen posts (Threads shows a visitor one page per search), so add several keywords of the topic. Filters such as minimum likes choose the posts, and every comment under them still comes; turn on **Apply the filters to replies too** to filter the comments as well.

Example: two Russian keywords, with 8 posts per keyword and 15 replies per post, gave 16 posts, 227 replies and 206 author profiles in 42 seconds.

### Why this Threads scraper

| | Typical Threads scraper | This Actor |
|---|---|---|
| Posts per profile | 4–25 without a login, or a login needed | The whole history, no login |
| Replies under a post | The first ~25 | All of them, page after page, nested up to 5 levels |
| Replies and media tabs of a profile | Rarely | Yes, paged back through the history |
| View counts | Missing or rounded | Exact, for any post |
| Instagram follower count | No | Yes, when the account is linked |
| Emails and phones from bios | Rarely | Yes, for profiles, accounts found by search, and authors |
| Profiles of everyone who posted or replied | Rarely | One row per person, with bio and contacts, in the same run |
| Search depth | One page of ~25 posts | Every spelling × top results and tag page, deduplicated |
| Start fee | Often $0.02 per run | None |
| Duplicates, filtered posts, errors | Often charged | Never charged |
| Monitoring | Dedupe it yourself | Built in: only new posts, free for known ones |

### What you get

Every row has a `type`: `post`, `reply`, `profile`, `account` (a profile found by account search), `author` (the author of a delivered post or reply, with **Profiles of authors and commenters** on; one row per person, and none for a profile or account that already has its own row) or `error` (an input that gave nothing, never charged). Rows are flat: lists are arrays, no nesting.

#### Post and reply rows

| Field | What it is |
|---|---|
| `postId`, `postCode`, `postUrl` | Post id, the code in its link, the link |
| `username`, `userId`, `fullName`, `isVerified`, `profilePicUrl` | The author |
| `authorFollowers` | The author's follower count: for profile posts always, for posts found by search and for replies with **Follower count of every author** or **Profiles of authors and commenters** on |
| `text` | The full text as written, links spelled out |
| `language`, `languageSource` | ISO language code; `threads` when Threads labels it, `guess` when guessed from the text |
| `hashtags`, `mentions`, `links` | #tags, @mentions and outbound links (without Threads' redirect) |
| `linkPreviewUrl`, `linkPreviewTitle`, `linkPreviewImageUrl` | The link card of the post |
| `topicTag` | The Threads topic of the post |
| `createdAt`, `timestamp` | Publication time (ISO and Unix) |
| `likeCount`, `replyCount`, `repostCount`, `quoteCount`, `shareCount` | Engagement |
| `viewCount` | Exact views: always for post links, for posts of profiles and searches with **Views for every post** on (not for replies) |
| `engagementTotal` | Likes + replies + reposts + quotes |
| `mediaType`, `mediaCount` | `text`, `image`, `video` or `carousel`, and how many items |
| `imageUrls`, `videoUrls`, `thumbnailUrl`, `mediaWidth`, `mediaHeight`, `hasAudio`, `accessibilityCaption` | Media at the best resolution, carousels item by item |
| `mediaFiles` | Saved copies of the photos and videos, with **Save photos and videos** on |
| `isReply`, `replyToUsername`, `rootPostUsername` | Reply context |
| `parentPostId`, `parentPostUrl`, `parentPostUsername`, `parentPostText` | The post a reply answers |
| `rootPostId`, `replyDepth` | For replies collected under a post: that post, and how deep the reply is (1 = direct) |
| `threadId`, `positionInThread`, `threadLength` | For profile posts: the author's multi-part thread |
| `isQuote`, `quotedPostUrl`, `quotedPostUsername`, `quotedPostText` | The quoted post |
| `isRepost`, `repostedByUsername`, `repostedAt` | For the reposts tab: who reposted the post and when |
| `isPinned`, `isEdited`, `isPaidPartnership`, `isSpoiler`, `isAiGenerated`, `likesHidden`, `replyControl` | Flags |
| `musicTitle`, `musicArtist`, `location` | Music and place attached to the post |
| `source`, `input`, `query`, `keywordMatched` | Where the row came from: the tab, search page or reply tree; your input line; the search spelling; whether the text contains the keyword |

#### Profile rows

| Field | What it is |
|---|---|
| `userId`, `username`, `profileUrl`, `fullName` | The account |
| `biography`, `bioLinks`, `website` | Bio and its links (`website` is the first link) |
| `emails`, `phones` | Contacts found in the bio and its links |
| `followerCount`, `isVerified`, `isPrivate` | |
| `instagramUrl`, `instagramFollowers`, `instagramFollowing` | The linked Instagram account and its counts |
| `topics` | The topics the account posts about, as Threads shows them |
| `profilePicUrl` | The largest profile picture |
| `latestPostAt`, `latestPostUrl`, `latestPostText` | The latest post, to see if the account is active (profiles and accounts) |
| `query` | For accounts found by search: the keyword. For authors: the keyword that found the post |
| `foundViaPostUrl` | For authors: the post or reply that brought them in |

Example post row:

```json
{
    "type": "post",
    "postUrl": "https://www.threads.com/@zuck/post/CuZsgfWLyiI",
    "username": "zuck",
    "fullName": "Mark Zuckerberg",
    "isVerified": true,
    "text": "70 million sign ups on Threads as of this morning. Way beyond our expectations.",
    "language": "en",
    "createdAt": "2023-07-07T15:39:32.000Z",
    "likeCount": 310236,
    "replyCount": 58105,
    "repostCount": 16092,
    "quoteCount": 13363,
    "viewCount": 473362,
    "mediaType": "text",
    "source": "post",
    "input": "https://www.threads.com/@zuck/post/CuZsgfWLyiI"
}
```

The dataset has ready-made views: **Posts**, **Engagement**, **Profiles & contacts**, **Replies**, **Media** and **Inputs with no results**. A `SUMMARY` record in the key-value store tells, for each input, how many posts were found, delivered, skipped as duplicates or filtered out, and why a profile or search stopped.

### Options

- **Profiles**: which tabs to collect (posts, replies, reposts, media), the profile row, how many posts per tab (0 = the whole history).
- **Posts and replies**: replies of post links, and optionally of every post found by search or in a profile; how many per post, how deep (1–5), top or recent first.
- **Search**: posts and/or accounts, the top results and/or the tag page, spellings of each keyword, limits per keyword.
- **Filters** (filtered posts are never charged): posted after / before (dates or "7 days", "3 months"), languages, minimum likes, replies, reposts and views, only posts that contain the keyword. They choose the posts, and the replies under them all come; **Apply the filters to replies too** filters the replies as well, for example to keep only replies with 10+ likes.
- **Extras**: exact views for every post, the follower count of every author and commenter or their full profiles, saving photos and videos.
- **Monitoring**: only posts not delivered before; a named memory to share between schedules; a reset.
- **Limits**: the maximum number of rows per run. The run also never spends more than the cost limit you set in Apify.
- **Run status**: an input that gives nothing (not found, private, mistyped, empty, a date that cannot be read, or Threads not readable after all retries) comes as a free error row with the reason, and the run still succeeds. **Fail the run when every input gives an error** makes a run with nothing but error rows fail instead.

### Pricing

Pay per result, no subscription and **no start fee**.

| Event | Price per 1,000 |
|---|---|
| Post or reply | $2.00 (down to $1.40 on higher Apify plans) |
| Profile, account or author | $3.00 (down to $2.10) |
| Saved photo or video file | $1.00 |

Never charged: filtered posts, duplicates, posts already delivered in monitoring, inputs that return nothing, views.

Examples: 1,000 posts of a profile cost $2.00 plus $0.003 for its profile row. 50 accounts found by keyword cost $0.15. A post with 500 replies costs about $1.00. A keyword with 30 posts and 600 replies by 450 different people costs $1.26, or $2.61 with the profiles of those people. On the free Apify plan with $5 of monthly credit you get about 2,500 posts a month.

### Monitoring: only new posts on a schedule

1. Set your inputs and filters, turn on **Only posts not delivered before**.
2. Save the input as a task and add a schedule (every hour, every day…).
3. Each run delivers only posts that previous runs of this input did not. Known posts are skipped for free, and profiles stop paging at the first known post, so a check of an account with nothing new costs almost nothing. Profile, account and author rows are delivered once too; turn monitoring off for a run when you want fresh follower counts.

Changing the inputs or what is collected (profile tabs, search pages and spellings, languages, only posts that contain the keyword, replies, the profile row) starts a new memory. Dates and minimum likes, replies, reposts or views keep it: posts they skipped were never delivered, so they can still come. **Monitoring memory name** lets several tasks share one memory, and **Forget what was delivered** starts over.

### Limitations, stated plainly

- **Search depth.** Without a login, Threads shows one page of about 25 posts per search, with no way to page further and no date filter. This Actor reads the top results and the tag page for every spelling of a keyword, so a keyword gives up to a few hundred posts, not thousands. For volume, collect the profiles that post about the topic: their history has no such limit.
- **No followers, following or likers lists.** Threads shows them only to logged-in users, and this Actor never logs in, so it cannot get your account banned.
- **Private profiles**: only the profile row, no posts.
- **Age-restricted profiles** show a visitor nothing: their authors come without a follower count or a profile row, and the `SUMMARY` record counts them.
- **Authors Threads refuses to show.** When Threads rate-limits profile reads, some authors come without a follower count or a profile row; the `SUMMARY` record counts the failed reads.
- **Views** come from each post's own page: always included for post links, one extra request per post for posts of profiles and searches, not available for replies.
- **Languages** are guessed from the text when Threads does not label them; very short posts may have no language.
- **Media links** from Threads stop working after a few days. Turn on **Save photos and videos** to keep copies.
- Counts are those Threads showed at the time of the run.

### Personal data

- **What is collected.** Only what Threads shows to anyone without logging in. Emails and phone numbers come from the public bio and bio links of a profile, never from posts or private data; with **Profiles of authors and commenters** on, this includes the people who wrote the posts and replies you collect. Turn off **Find emails and phones in bios** if you do not need them.
- **Your responsibility.** Processing personal data requires a lawful basis, for example under GDPR in the EU. Do not use contacts for unsolicited messages or spam.
- **What the Actor keeps.** Results stay in your Apify storage. With monitoring on, a named key-value store `threads-scraper-anuarbakty-monitor` keeps the ids of delivered posts and profiles with the time they were delivered: no texts and no contacts. Delete the store in Apify Console, or run once with **Forget what was delivered**, to remove it.

### Use it from AI agents (MCP)

Add the Actor to Claude, ChatGPT, Cursor or any MCP client through the Apify MCP server:

```
https://mcp.apify.com/?tools=anuarbakty/threads-scraper
```

Example requests to an agent:

- "Get the last 200 posts of @nasa with views and tell me which topics perform best."
- "Find 30 Threads accounts about specialty coffee in Almaty with emails in the bio."
- "Collect all replies under this Threads post and summarize the main complaints."
- "Find Threads posts about our brand from the last week with all their comments, and show which commenters have the most followers."
- "Find Threads posts about electric cars from the last 3 months with all comments and the profiles of the people who wrote them. What do people complain about, and who are they?"

Errors come back as rows with `type: "error"` and a reason, so an agent always gets an answer it can read.

### API

```bash
curl -X POST "https://api.apify.com/v2/acts/anuarbakty~threads-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"targets": ["@nasa"], "maxPostsPerProfile": 50}'
```

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('anuarbakty/threads-scraper').call({ targets: ['#running'], maxPostsPerSearch: 200 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("anuarbakty/threads-scraper").call(run_input={"targets": ["@zuck"], "profileContent": ["posts", "replies"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

Results can also go to Google Sheets, Make, Zapier, n8n, webhooks and more through Apify integrations.

### More from this developer

- **[YouTube Transcript Scraper](https://apify.com/anuarbakty/youtube-transcript-scraper)**: transcripts and subtitles of YouTube videos, Shorts, channels, playlists and search in any language, as text, timestamps, SRT, VTT or chunks for AI; no captions, no charge.
- **[Facebook Ads Library Scraper](https://apify.com/anuarbakty/facebook-ads-library-scraper)**: ads from the Meta Ad Library (Facebook and Instagram) by keyword, brand name or page, with creatives, days running, EU reach and advertiser contacts, without login.
- **[2GIS Places Scraper](https://apify.com/anuarbakty/2gis-places-scraper)**: businesses from 2GIS (Russia, Kazakhstan, Central Asia, UAE) with phones, WhatsApp, Telegram, emails and websites, the whole result instead of 60.
- **[2GIS Reviews Scraper](https://apify.com/anuarbakty/2gis-reviews-scraper)**: 2GIS reviews with star, topic and date filters, unanswered reviews across a chain, and only-new monitoring.

### FAQ

**Do I need a Threads account or cookies?** No. The Actor reads only what Threads shows to a logged-out visitor, so there is no account to get banned.

**How far back can it go?** For profiles, to the first post (Threads launched in July 2023). Searches are limited to what Threads shows a visitor, see the limitations.

**Is it the official Threads API?** No. The official API needs a Meta app with review and caps keyword search at about 500 queries per 7 days per user. This Actor needs no app, key or review.

**Why did a keyword return fewer posts than my limit?** Threads shows a visitor only about 25 posts per search page. Keep "spellings of each keyword" on, add related keywords, or collect the profiles that post about the topic.

**Why is `keywordMatched` false for some posts?** Threads pads search results with related posts that do not mention the keyword. Turn on "Only posts that contain the keyword" to skip them for free. Russian words count in any form: "кофейня" also matches "кофейни" and "кофейню".

**Can I get everyone who commented on a post, with their contacts?** Yes: paste the post link and turn on **Profiles of authors and commenters**. Each commenter comes once, with bio, links, and emails and phones from the bio. Who liked a post Threads shows only to logged-in users, so likers are not available.

**How do I get only the most liked replies?** Turn on **Apply the filters to replies too** and set **Minimum likes**. Skipped replies are not charged. The minimum applies to posts as well: for keywords and profiles, a post below it is skipped together with its replies. For a post link, its replies are collected even if the post itself is below the minimum.

**Can I get the posts of a specific week from last year?** From profiles, yes: set "Posted after" and "Posted before". From keyword search, no: Threads does not let a logged-out visitor search by date.

**Is scraping Threads legal?** The Actor collects only public data that anyone can see without logging in. You are responsible for how you use it, see Personal data above. If in doubt, ask a lawyer.

**Why did my run succeed with no posts?** Every input gave an error: missing, private, mistyped, empty, a date the Actor could not read, or Threads not readable after all retries. Each one has a row with `type: "error"`, `errorReason` and `errorMessage` (the **Inputs with no results** view), the status of the run says how many, and nothing was charged. If your automation should see a failed run instead, turn on **Fail the run when every input gives an error**.

**Something does not work?** Open an issue on the Actor's **Issues** tab and paste the link to the run. A run linked in an issue opens to the developer automatically: its log, input and results, and nothing else in your account. To share every run of this Actor instead, turn on **Share run data with developers** in Apify Console under Settings → Login & Privacy.

# Actor input Schema

## `targets` (type: `array`):

One per line, mixed freely:<br>• <b>@username</b> or a profile link (<code>threads.com/@zuck</code>, also <code>/replies</code>, <code>/media</code>, <code>/reposts</code>) → profile and its posts<br>• a <b>post link</b> (<code>threads.com/@user/post/…</code>, <code>threads.net</code>, <code>/t/…</code>, share links) → the post, its view count and replies<br>• a <b>keyword or phrase</b> → matching posts<br>• a <b>#hashtag</b> or a Threads search link → posts of the tag or search<br>A bare word is searched as a keyword; to add a profile, write it with @.

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

A column of usernames pasted from a spreadsheet, with or without @. Same as adding @username lines above.

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

A column of keywords or phrases, searched exactly as typed (even ones starting with @). Same as adding keyword lines above.

## `profileContent` (type: `array`):

Each selected tab is paged back through the whole history, up to the limit below. A profile link ending in /replies, /media or /reposts collects only that tab.

## `includeProfile` (type: `boolean`):

One row per profile: followers, bio, bio links, emails and phones from the bio, verification, topics, the linked Instagram account with its follower count, and the latest post. Charged as one profile.

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

How many posts to collect from each selected tab of each profile. 0 = the whole history (Threads started in July 2023).

## `includeReplies` (type: `boolean`):

For every post link: the replies under it, page after page, not only the first 25 a visitor sees.

## `repliesOfFoundPosts` (type: `boolean`):

For every post delivered from a keyword, a hashtag or a profile: its replies too, with the limit and depth below for each post. Search a keyword and get the posts with all their comments in one run. Each reply is charged as a post.

## `maxRepliesPerPost` (type: `integer`):

Limit of replies for each post link, nested replies included. 0 = all replies Threads shows.

## `replyDepth` (type: `integer`):

1 = direct replies only. 2 = also replies to those replies, and so on up to 5. Each row has its depth and the post it answers.

## `repliesSort` (type: `string`):

Top: the order Threads shows by default. Recent: newest first.

## `searchFor` (type: `array`):

Posts: posts matching the keyword. Accounts: profiles matching it, each with followers, bio, emails and phones from the bio (charged as profiles).

## `searchPages` (type: `array`):

Threads shows a logged-out visitor one page of about 25 posts per search; the top results and the tag page are two different pages, so both give more posts.

## `expandQueries` (type: `boolean`):

Adds the #hashtag form and the plural or singular of the keyword (nike → #nike, nikes). Each spelling is a separate search with its own page, so a keyword yields several times more posts. Duplicates are removed and never charged.

## `maxPostsPerSearch` (type: `integer`):

Limit of posts for each keyword or hashtag, across its spellings and pages. 0 = all that Threads shows.

## `maxAccountsPerSearch` (type: `integer`):

When searching for accounts: how many profiles to return for each keyword.

## `postedAfter` (type: `string`):

Only posts published after this date: YYYY-MM-DD, today, yesterday, or relative, like 7 days or 3 months. Profiles stop paging once they reach older posts.

## `postedBefore` (type: `string`):

Only posts published before this date: YYYY-MM-DD, today, yesterday, or relative.

## `languages` (type: `array`):

Only posts in these languages. Threads rarely labels a post's language for a visitor, so it is guessed from the text: reliable for scripts (Cyrillic, Japanese, Arabic…) and common Latin languages; posts too short to tell are skipped.

## `minLikes` (type: `integer`):

Skip posts with fewer likes.

## `minReplies` (type: `integer`):

Skip posts with fewer replies.

## `minReposts` (type: `integer`):

Skip posts with fewer reposts.

## `minViews` (type: `integer`):

Skip posts with fewer views. Views are known for post links, and for posts of profiles and searches with "Views for every post" on; posts with unknown views are kept.

## `strictKeywordMatch` (type: `boolean`):

Threads pads search results with related posts that never mention the keyword. On: they are skipped and not charged. Off: they are delivered with keywordMatched = false. Russian words count in any form: "кофейня" also matches "кофейни".

## `filterReplies` (type: `boolean`):

Off: the filters choose the posts, and every reply under them is collected, up to the replies limit. On: replies must pass the filters too, for example only replies with at least 10 likes, in the chosen languages or within the dates. Skipped replies are not charged.

## `includeViews` (type: `boolean`):

Exact view counts for posts of profiles and searches too (post links always have them; replies never do). Costs one extra page load per post, so runs are slower.

## `includeAuthorFollowers` (type: `boolean`):

Adds authorFollowers to posts found by search and to replies, so you see how big each author and commenter is. One small request per new author, remembered for the whole run.

## `includeAuthorProfiles` (type: `boolean`):

Adds a profile row (type author) for every person who wrote a delivered post or reply: bio, bio links, emails and phones from the bio, followers, verification, the linked Instagram account. Each person comes once per run, with the keyword and the post that brought them in. Charged as a profile. Fills authorFollowers in posts and replies too. Profiles you added as inputs and accounts found by account search keep their own rows instead.

## `downloadMedia` (type: `boolean`):

Copies every photo and video of delivered posts into the run's key-value store and adds their links in mediaFiles. Threads media links stop working after a few days; these copies stay as long as you keep the run's storage. Charged per file.

## `extractContacts` (type: `boolean`):

Adds the emails and phone numbers people published in their Threads bio and bio links to profile and account rows. Turn off if you do not need personal contact data.

## `onlyNew` (type: `boolean`):

The Actor remembers the posts of this input and delivers only new ones on the next runs. Profiles stop paging at the first post already delivered.

## `monitoringName` (type: `string`):

Optional. By default each set of inputs and filters has its own memory. A name lets several schedules share one memory, or start a fresh one on purpose.

## `resetMonitoring` (type: `boolean`):

Clears the monitoring memory before this run, so everything counts as new again.

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

Stop after this many posts and profiles in total. 0 = no limit. The run never spends more than the cost limit set in Apify either.

## `failIfAllInputsFail` (type: `boolean`):

Off: an input that gives nothing comes as a free error row with the reason (not found, private, mistyped, empty, a date that cannot be read, or Threads not readable after all retries), and the run finishes as succeeded even when every input ended that way, so an automation that sends one profile or post per run keeps going. On: the run fails when every input ended with an error row, so an automation can catch it by the run status.

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

Leave empty: the Actor uses Apify proxies and switches a failing request to residential ones by itself. Set your own only if you need to.

## Actor input object example

```json
{
  "targets": [
    "@zuck",
    "#running"
  ],
  "profileContent": [
    "posts"
  ],
  "includeProfile": true,
  "maxPostsPerProfile": 50,
  "includeReplies": true,
  "repliesOfFoundPosts": false,
  "maxRepliesPerPost": 50,
  "replyDepth": 1,
  "repliesSort": "top",
  "searchFor": [
    "posts"
  ],
  "searchPages": [
    "default",
    "tags"
  ],
  "expandQueries": true,
  "maxPostsPerSearch": 100,
  "maxAccountsPerSearch": 10,
  "minLikes": 0,
  "minReplies": 0,
  "minReposts": 0,
  "minViews": 0,
  "strictKeywordMatch": false,
  "filterReplies": false,
  "includeViews": false,
  "includeAuthorFollowers": false,
  "includeAuthorProfiles": false,
  "downloadMedia": false,
  "extractContacts": true,
  "onlyNew": false,
  "resetMonitoring": false,
  "maxItems": 0,
  "failIfAllInputsFail": false
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "targets": [
        "@zuck",
        "#running"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("anuarbakty/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 = { "targets": [
        "@zuck",
        "#running",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("anuarbakty/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 '{
  "targets": [
    "@zuck",
    "#running"
  ]
}' |
apify call anuarbakty/threads-scraper --silent --output-dataset

```

## MCP server setup

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