# Threads Scraper: Posts, Search, Replies & Profiles (No Login) (`varnmill/threads-scraper`) Actor

Scrape public Threads (Meta) posts from any profile, keyword search results, post replies and profile details as JSON, CSV or Excel, with no login, cookies or residential proxy. $1 per 1,000 posts; monitor mode returns only posts you have not seen before.

- **URL**: https://apify.com/varnmill/threads-scraper.md
- **Developed by:** [Jay Novello](https://apify.com/varnmill) (community)
- **Categories:** Social media
- **Stats:** 3 total users, 2 monthly users, 95.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 post or replies

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, Search, Replies & Profiles (No Login)

Get public **Threads** (Meta) posts from any profile, keyword search results, the replies under a post and profile details (followers, bio, links) as JSON, CSV or Excel, straight from threads.com, with no Threads account, no cookies and no residential proxy.

**Try it:** Click **Start** with the default input: the 15 latest NASA posts in 6 s for about $0.015 (run of October 21, 2026, build 0.1.4).

The most-liked posts from that default run:

| Posted | Likes | Replies | Reposts | Media | Text (start) |
|---|---|---|---|---|---|
| 2026-10-13 | 41,142 | 595 | 4,386 | carousel | Spotted: views of a "space jellyfish" following today's launch of NASA's SpaceX 35th commercial resupply… |
| 2026-10-06 | 5,495 | 116 | 478 | image | Incoming: a new image from the cosmos! NASA's James Webb Space Telescope captured a stellar nursery… |
| 2026-10-13 | 4,192 | 17 | 90 | text | A "space jellyfish" happens near sunrise or sunset when the exhaust plume from the rocket becomes… |
| 2026-10-09 | 2,469 | 28 | 76 | carousel | POV: returning to Earth after spending 237 days living and working in orbit! NASA's SpaceX Crew-12… |
| 2026-10-07 | 2,117 | 61 | 216 | video | A LOT of Artemis II data just dropped! 814GB of observations. 996 new images. 521min of never-before… |

**Pricing:** **$1 per 1,000 posts or replies**, $1.50 per 1,000 profiles, plus $0.00005 per run start. Platform usage and proxy are included; failed runs and "returned nothing" rows are not charged.

The same day, the other modes on the same build: *Keyword search* for `apify` returned 25 posts in 11 s (about $0.025); *Post replies* on the default post URL returned the post plus 20 replies in 5 s (about $0.021).

### More real examples

Run on Apify on **October 13, 2026 (00:14 UTC)**, mode *Profile details*, five usernames, finished in 4 seconds:

| Username | Name | Followers | Verified | Bio link |
|---|---|---|---|---|
| instagram | Instagram | 38,365,144 | no | help.instagram.com |
| natgeo | National Geographic | 18,370,683 | yes | on.natgeo.com/instagram |
| nasa | NASA | 12,771,310 | yes | |
| zuck | Mark Zuckerberg | 5,744,569 | yes | |
| meta | Meta | 1,865,675 | yes | |

Same day, mode *Profile posts*, `nasa` and `natgeo`, 45 posts each (90 posts plus 2 profiles in 15 seconds, cost to the user $0.093). The most-liked posts in that run:

| Account | Posted | Likes | Replies | Reposts | Media | Text (start) |
|---|---|---|---|---|---|---|
| nasa | 2026-08-25 | 164,842 | 619 | 11,483 | image | Today, the universe carries a little more sparkle in honor o… |
| natgeo | 2026-09-17 | 21,276 | 615 | 2,538 | video | New cat alert! A call from a wildlife sanctuary about a "wei… |
| nasa | 2026-08-13 | 12,374 | 262 | 887 | image | Yesterday's eclipse was 10/10, no notes! … |
| nasa | 2026-08-27 | 10,519 | 264 | 917 | image | Calling all our "Look at the Moon! 😍" Thriends! … |

One full row from that run:

```json
{
  "type": "post",
  "id": "4006620349303729406",
  "code": "DeaX_rOGaz-",
  "url": "https://www.threads.com/@nasa/post/DeaX_rOGaz-",
  "text": "Space news, hot off the trail: NASA’s Perseverance Mars rover has driven farther than any vehicle ever has on the surface of another world! …",
  "createdAt": "2026-10-12T23:06:27Z",
  "timestamp": 1791846387,
  "authorUsername": "nasa",
  "authorFullName": "NASA",
  "authorId": "28829152388",
  "authorIsVerified": true,
  "likeCount": 415,
  "replyCount": 15,
  "repostCount": 25,
  "quoteCount": 5,
  "reshareCount": 2,
  "mediaType": "image",
  "imageUrls": ["https://scontent-iad6-1.cdninstagram.com/v/t51.82787-15/848307311_…jpg"],
  "videoUrls": [],
  "imageAltText": "One of Perseverance’s navigation cameras captured this shot on Oct. 11, 2026 …",
  "links": [],
  "mentions": [],
  "topicTag": "Space Threads",
  "isReply": false,
  "quotedPost": null,
  "isPinned": false,
  "input": "nasa",
  "scrapedAt": "2026-10-13T00:14:00Z"
}
```

In *Post replies* mode, the same day, Mark Zuckerberg's launch post (999 likes, 154 replies) returned the post plus 60 replies with author, likes and reply depth in 10 seconds.

### What it does

| Mode | Input | Output |
|---|---|---|
| **Profile posts** | usernames or profile URLs | The profile's posts newest first, paginated (tested to 300+ posts per profile), optional profile row |
| **Keyword search** | keywords or #hashtags | Posts Threads shows for the keyword, plus topic-tag results, with search rank |
| **Post replies** | post URLs | The post, then its replies (direct replies and visible sub-replies, with `replyDepth`) |
| **Profile details** | usernames or profile URLs | Followers, full name, bio, bio links, verified, private flag, HD picture, topic tags |

Every post and reply row has: `id`, `code`, `url`, `text`, `createdAt` (UTC), `timestamp`, author username / name / ID / verified / picture, `likeCount`, `replyCount`, `repostCount`, `quoteCount`, `reshareCount`, `mediaType` (text, image, video, carousel), `imageUrls`, `videoUrls`, `imageAltText`, `links`, `mentions`, `linkPreviewUrl`, `topicTag`, `isReply`, `replyToUsername`, `quotedPost`, `repostedPost`, `isPinned`, `isPaidPartnership`.

Three dataset views are built in: **Posts and replies**, **Profiles**, and **Inputs that returned nothing** (with the reason).

### Monitor mode: only new posts

Turn on **Only new posts** and schedule the Actor (hourly or daily). It remembers which posts it already delivered, per profile, keyword or post, in a named key-value store, and returns only new ones. You pay only for new rows. Tested on October 13, 2026: the first run for the keyword `web scraping` returned 27 posts, the second run 0.

Use it to watch competitors' accounts, brand mentions, a hashtag, or new replies under a post. Use a different **Monitor memory name** for each separate monitor.

### Filters

- **Only posts newer than**: `2026-10-01`, an ISO timestamp, or `7 days` / `24 hours`. In Profile posts mode pagination stops as soon as posts get older, so date-limited runs are fast and cheap.
- **Minimum likes**: skip low-engagement posts.
- **Max posts per profile / results per keyword / replies per post.**

### Pricing

Pay per result. Platform usage and proxies are included.

| Event | Price |
|---|---|
| Post or reply | **$1.00 per 1,000** ($0.001 each) |
| Profile | $1.50 per 1,000 ($0.0015 each) |
| Actor start | $0.00005 per run |

Rows explaining why an input returned nothing (deleted post, unknown username, private profile) are free. Set a maximum charge per run in the run options and the Actor stops cleanly when it is reached.

### Accuracy and limits

- **Only public data.** The Actor reads what a logged-out visitor can see on threads.com. Private profiles return a profile row and a note, no posts.
- **Search depth.** Logged-out Threads search shows roughly 20 to 60 posts per keyword (top results plus topic-tag results), ranked by Threads, not strictly by date, and in every language. For ongoing coverage of a keyword, schedule it with **Only new posts**; each run adds whatever is new. Use **Only posts newer than** to drop older top results.
- **Replies.** Threads decides which replies a logged-out visitor sees; very long threads can return fewer replies than the `replyCount` shown on the post.
- **Counts** are live values at scrape time. View counts are not shown to logged-out visitors, so they are not included.
- **Media URLs** are Meta CDN links that expire after a few days; download them promptly if you need the files.

### Reliability

No login, no browser, no residential proxy: the Actor makes the same requests a logged-out visitor's browser makes. Threads query IDs are read from the live page on every run, so routine Threads deployments do not break it. Failed requests are retried with a fresh session and, if Threads keeps refusing, the Actor switches to Apify datacenter proxy automatically. Unknown usernames and deleted posts produce a clear free error row instead of a failed run.

### FAQ

**Do I need a Threads or Instagram account?** No.

**Do I need a proxy?** No. Leave the proxy setting off; the Actor falls back to Apify datacenter proxy by itself if needed.

**Can I paste threads.net links?** Yes, `threads.net` and `threads.com` URLs both work, as do `@username` and plain usernames.

**How many posts can I get from one profile?** As many as the profile has public posts; the Actor pages through the feed 15 posts at a time. Set **Max posts per profile**.

**Can I use it from n8n, Make, Zapier or my own code?** Yes, through the Apify API or the Apify integrations. Each run's dataset is available as JSON, CSV, Excel or via the API URL in the run's Output tab.

**Is scraping Threads legal?** The Actor collects only publicly visible posts and profiles, without logging in. You are responsible for how you use the data, including privacy law (for example GDPR) when posts belong to private individuals.

### Changelog

- **0.1.5** (October 21, 2026): default post URL for *Post replies* mode so every mode runs out of the box; README restructured with October 21 run numbers. No scraping changes.
- **0.1** (October 13, 2026): first release. Profile posts with pagination, keyword search with topic-tag results, post replies with pagination, profile details, date and likes filters, monitor mode, automatic datacenter proxy fallback.

# Actor input Schema

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

posts: latest posts of each profile (paginated). search: keyword search results. replies: replies under each post URL. profiles: profile details only (followers, bio, links).

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

For 'Profile posts' and 'Profile details'. Accepts zuck, @zuck or https://www.threads.com/@zuck (threads.net links work too).

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

For 'Keyword search'. Each keyword is searched separately, the same as typing it into the Threads search box. Hashtags like #coffee work too.

## `postUrls` (type: `array`):

For 'Post replies'. Links like https://www.threads.com/@zuck/post/DeZtp-TkQHh. The post itself is returned first, then its replies.

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

Stop after this many posts per profile ('Profile posts' mode). Threads serves 15 per page.

## `maxResultsPerQuery` (type: `integer`):

Stop after this many posts per keyword ('Keyword search' mode). Logged-out Threads search returns roughly 20 to 60 posts per keyword; schedule the run with 'Only new posts' to collect more over time.

## `includeTopicTagResults` (type: `boolean`):

Keyword search: also read the topic-tag results for the keyword, which usually adds 10 to 30 different posts.

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

Stop after this many replies per post ('Post replies' mode). Direct replies and the visible sub-replies under them both count.

## `includeParentPost` (type: `boolean`):

Post replies: also output the post the replies belong to (charged as one post).

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

Profile posts: add one profile row (followers, bio, links) per username before its posts.

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

Skip older posts. A date (2026-10-01), an ISO timestamp, or a relative period such as '7 days' or '24 hours'. In 'Profile posts' mode pagination stops once posts get older than this.

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

Skip posts with fewer likes than this. 0 keeps everything.

## `onlyNewPosts` (type: `boolean`):

Remember which posts earlier runs delivered (per profile, keyword or post) and output only posts not seen before. Schedule the Actor hourly or daily to get a feed of new posts and replies. You are only charged for new rows.

## `stateStoreName` (type: `string`):

Name of the key-value store that holds the 'only new posts' memory. Use different names to keep separate monitors apart.

## `maxConcurrency` (type: `integer`):

How many profiles, keywords or posts to process at the same time.

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

Not needed: by default the Actor connects directly and only switches to Apify datacenter proxy if Threads starts refusing requests. Residential proxy is never required.

## `autoProxyFallback` (type: `boolean`):

When no proxy is selected and Threads refuses requests, retry through Apify datacenter proxy automatically.

## Actor input object example

```json
{
  "mode": "posts",
  "usernames": [
    "nasa"
  ],
  "searchQueries": [
    "apify"
  ],
  "postUrls": [
    "https://www.threads.com/@zuck/post/DeZtp-TkQHh"
  ],
  "maxPostsPerProfile": 15,
  "maxResultsPerQuery": 50,
  "includeTopicTagResults": true,
  "maxRepliesPerPost": 50,
  "includeParentPost": true,
  "includeProfile": false,
  "minLikes": 0,
  "onlyNewPosts": false,
  "stateStoreName": "threads-scraper-seen",
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "autoProxyFallback": true
}
```

# Actor output Schema

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

No description

## `postsCsv` (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 = {
    "mode": "posts",
    "usernames": [
        "nasa"
    ],
    "searchQueries": [
        "apify"
    ],
    "postUrls": [
        "https://www.threads.com/@zuck/post/DeZtp-TkQHh"
    ],
    "maxPostsPerProfile": 15,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("varnmill/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": "posts",
    "usernames": ["nasa"],
    "searchQueries": ["apify"],
    "postUrls": ["https://www.threads.com/@zuck/post/DeZtp-TkQHh"],
    "maxPostsPerProfile": 15,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("varnmill/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": "posts",
  "usernames": [
    "nasa"
  ],
  "searchQueries": [
    "apify"
  ],
  "postUrls": [
    "https://www.threads.com/@zuck/post/DeZtp-TkQHh"
  ],
  "maxPostsPerProfile": 15,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call varnmill/threads-scraper --silent --output-dataset

```

## MCP server setup

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