# Threads Scraper (No Cookies) (`mina_safwat/threads-scraper-no-cookies`) Actor

Scrapes public Threads profiles, their latest posts, single posts with their replies, and keyword or hashtag searches, without login or cookies.

- **URL**: https://apify.com/mina_safwat/threads-scraper-no-cookies.md
- **Developed by:** [Mina](https://apify.com/mina_safwat) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.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.

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

### What does Threads Scraper (No Cookies) do?

**Threads Scraper (No Cookies)** collects public data from [Threads](https://www.threads.com),
Meta's conversation app, **without a login, cookies or an account**. Paste
profile links to get each **profile** (username, full name, bio, **follower
count**, verified badge, profile picture and bio links) with its **newest
posts**. Paste post links to get a **post with its replies**, or **search by
keyword or #hashtag**. Every post comes with its **text, date, likes, replies,
reposts, quotes, shares, photos, videos, carousel items, links, mentions and
topic tag**. It also says whether the post is a reply or a quote, with the
quoted post attached.

Try it with the prefilled profiles: open the Actor, click **Start**, and two
profiles with 10 posts each arrive within seconds. Because it runs on the
Apify platform, you also get API access, scheduled runs, integrations (Google
Sheets, Make, Zapier, webhooks), run monitoring and automatic retries through
Apify Proxy whenever Threads refuses a request.

### Why scrape Threads?

- **Social listening and brand monitoring**: follow what brands, creators and
  journalists post on Threads, and how many likes, replies and reposts each
  post earns.
- **Influencer research**: compare accounts by follower count, verified
  badge and engagement per post.
- **Customer feedback**: collect the replies under a brand's or a creator's
  post, top replies or newest first.
- **Trend and topic research**: search keywords and hashtags, or open a topic
  tag page, and save the posts Threads shows for them.
- **Archiving and AI datasets**: save a profile's public history back to its
  first post, with text, links and media URLs.

### How to scrape Threads

1. Open a Threads profile or post in your browser and copy its link, such as
   `https://www.threads.com/@zuck`. A plain `@zuck` or `zuck` works too, and
   so do old `threads.net` links.
2. Paste the links into **Threads profiles or posts**, one per line.
3. Optionally, type words or hashtags into **Search Threads**.
4. Set **Max posts per profile or search** and, if you only want recent posts,
   **Only posts newer than** (a date, or an age such as `7 days`).
5. Click **Start**, then download the results from the **Output** tab.

### Input

Everything is set on the Input tab. In JSON, the input looks like this:

```json
{
    "startUrls": [
        "https://www.threads.com/@zuck",
        "@nasa",
        "https://www.threads.com/@zuck/post/Ddt7cL5EfUG"
    ],
    "searchQueries": ["openai", "#artemis"],
    "maxPosts": 20,
    "newerThan": "30 days",
    "includeProfiles": true,
    "includeReplies": true,
    "maxRepliesPerPost": 50,
    "repliesSort": "TOP"
}
```

| Field | What it does |
|---|---|
| `startUrls` | Profile links (`threads.com/@name`, `threads.net/@name`, `@name` or `name`), post links (`threads.com/@name/post/CODE` or `threads.com/t/CODE`), or search links copied from threads.com/search, including topic tag pages. |
| `searchQueries` | Optional words, phrases or #hashtags. Without a login Threads shows its top results only: about 20 posts per search. |
| `maxPosts` | Posts saved per profile (newest first) or per search. Default: 20. Set `0` to save only profile rows. |
| `newerThan` | Skips profile and search posts older than a date (`2026-09-01`) or an age (`12 hours`, `7 days`, `2 weeks`). Post links and their replies are always saved. |
| `includeProfiles` | Adds one row per profile link. Default: on. |
| `includeReplies` | Saves the replies under each post link, with the conversations under them. Default: on. |
| `maxRepliesPerPost` | Replies saved per post link. Default: 50. |
| `repliesSort` | `TOP` (the order threads.com shows by default, which for logged-out visitors starts with the oldest replies) or `RECENT` (newest first). |
| `proxyConfiguration` | Optional; leave it empty. The Actor connects directly and switches to Apify datacenter, then residential proxies, on its own if Threads refuses it. |

### Output

Each post and each profile becomes one row. Here is a real post, with its
long media links shortened:

```json
{
    "type": "post",
    "id": "4002762028958762635",
    "code": "DeMqtuYgkaL",
    "url": "https://www.threads.com/@nasa/post/DeMqtuYgkaL",
    "author": "nasa",
    "authorFullName": "NASA",
    "authorIsVerified": true,
    "createdAt": "2026-10-07T15:22:45+00:00",
    "text": "A LOT of Artemis II data just dropped! 🌖 \n\n814GB of observations. 996 new images. 521min of never-before-released crew audio. …",
    "likes": 1772,
    "replies": 47,
    "reposts": 177,
    "quotes": 40,
    "shares": 49,
    "media": [
        {
            "type": "video",
            "url": "https://scontent-iad3-2.cdninstagram.com/o1/v/t16/f2/m84/AQN…",
            "thumbnailUrl": "https://scontent-iad3-2.cdninstagram.com/v/t51.71878-15/8316…",
            "width": 1080,
            "height": 1920
        }
    ],
    "links": ["http://go.nasa.gov/Artemis2LunarScience"],
    "linkPreview": null,
    "mentions": [],
    "tag": "Artemis II",
    "isReply": false,
    "replyToUsername": null,
    "isQuote": false,
    "quotedPost": null,
    "isPinned": true,
    "source": "nasa",
    "scrapedAt": "2026-10-08T12:55:37.085061+00:00"
}
```

And the profile row from the same run:

```json
{
    "type": "profile",
    "username": "nasa",
    "fullName": "NASA",
    "userId": "28829152388",
    "url": "https://www.threads.com/@nasa",
    "biography": "Making the seemingly impossible, possible. ✨",
    "followers": 12762210,
    "isVerified": true,
    "isPrivate": false,
    "profilePicUrl": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-19/6697…",
    "bioLinks": [],
    "source": "nasa",
    "scrapedAt": "2026-10-08T12:55:36.322748+00:00"
}
```

The Output tab has two views, **Posts** and **Profiles**. You can download
the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data fields

Post rows (`type` is `post`), including replies and search results:

| Field | Description |
|---|---|
| `id`, `code` | The post's numeric id (as text, because it is too long for some spreadsheet tools) and its short code from the link. |
| `url` | Link to the post. |
| `author`, `authorFullName`, `authorIsVerified` | Who posted it. |
| `createdAt` | When it was posted (UTC, ISO 8601). |
| `text` | The full post text, with line breaks and emoji. Empty for a photo or video posted without text. |
| `likes`, `replies`, `reposts`, `quotes`, `shares` | Exact counts. `likes` is empty when the author hides it; `shares` is empty on most replies, because Threads does not report it for them. |
| `media` | Photos and videos in display order, one item per carousel slide: `type` (`image` or `video`), `url`, `width`, `height`, and `thumbnailUrl` for videos. |
| `links` | Web addresses in the text and in the link preview, with Threads' redirect removed. |
| `linkPreview` | The preview card of a shared link: `url`, `title`, `displayUrl`, `imageUrl`. |
| `mentions` | Usernames mentioned in the text. |
| `tag` | The topic tag the author added. |
| `isReply`, `replyToUsername` | Whether the post replies to another one, and to whom. An author's follow-up posts in their own thread are replies to themselves. |
| `isQuote`, `quotedPost` | Whether the post quotes another one, with the quoted post's `id`, `code`, `url`, `author`, `authorIsVerified`, `createdAt`, `text`, counts and `media`. |
| `isPinned` | `true` when the author pinned the post to their profile. |
| `source` | The input the row was found through. |
| `scrapedAt` | When the row was saved. |

Profile rows (`type` is `profile`):

| Field | Description |
|---|---|
| `username`, `fullName`, `userId`, `url` | The account. |
| `biography` | The bio text. |
| `followers` | Exact follower count. |
| `isVerified`, `isPrivate` | Verified badge, and whether the account is private. |
| `profilePicUrl` | The largest profile picture available. |
| `bioLinks` | The links shown under the bio. |
| `source`, `scrapedAt` | As for posts. |

### How much does it cost to scrape Threads?

Threads Scraper (No Cookies) uses **pay-per-event** pricing: you pay for the
rows you get, and the price per result is on the **Pricing** tab. Each post,
reply or profile saved is one row. Inputs that return nothing, such as a
deleted post, an unknown username or a search without results, are never
saved as rows, so they cost nothing. If you set a maximum cost for a run, the
Actor stops cleanly as soon as it is reached.

It is also fast: 1,000 posts from 10 profiles took 36 seconds in our tests,
because it reads Threads' own data feed instead of loading web pages in a
browser.

### Tips for scraping Threads

- **Monitor accounts on a schedule.** Run daily with **Only posts newer than**
  set to `1 day` and **Save profile rows** off, to get only the new posts.
- **Follower counts only:** set **Max posts** to `0` to check a long list of
  profiles quickly and cheaply.
- **Full history:** Threads lets the Actor page back to an account's first
  post, so a large **Max posts** (for example `1000`) archives a whole profile.
- **Replies:** paste the post link. Choose **Newest replies first** to follow
  a conversation as it grows.
- **Pinned posts** come first on a profile whatever their age; they are marked
  `isPinned`, and with a date limit an old pinned post is skipped without
  stopping the rest.
- **Search** shows about 20 top posts per query. Use several specific
  keywords or hashtags, or paste a topic tag page from threads.com, to cover a
  subject; to get more from one account, paste its profile instead.
- Each post is saved only once per run, even when several inputs lead to it.

### FAQ, disclaimers and support

**Do I need a Threads account, cookies or a login?** No. The Actor reads only
what Threads shows to visitors who are not logged in.

**What can it not get?** Without a login, Threads does not show following
counts, post view counts, posts of private accounts or the "Recent" search
tab, so search returns Threads' top results only, about 20 per query. A
private account still gets its profile row, and the run notes that its posts
are hidden. From a profile the Actor reads the main Threads tab: the
account's replies to other people and its reposts are not included.

**What happens to links that return nothing?** They are not saved as rows,
so you are not charged for them. Each one is listed with its reason in the
`FAILED_INPUTS` record of the run's key-value store, and the run's status
message gives the counts. A run fails only when every input failed because
Threads could not be reached.

**Are media links permanent?** No. Photo and video links point to Meta's
content servers and stop working after a while. Download the files soon after
the run if you need to keep them.

**Is it legal to scrape Threads?** This Actor collects only public posts and
profiles that Threads shows to anyone without an account. Posts and profiles
can still contain personal data, so you are responsible for making sure your
use complies with Threads' Terms of Use and with data protection laws such as
the GDPR. If in doubt, ask a lawyer.

**Found a problem or need a custom solution?** Open an issue on the
**Issues** tab and we will look into it. Custom scrapers and data feeds are
available on request.

# Actor input Schema

## `startUrls` (type: `array`):

One per line. A profile (https://www.threads.com/@zuck, threads.net links, @zuck or just zuck) gives the profile and its newest posts. A post (https://www.threads.com/@zuck/post/Ddt7cL5EfUG) gives the post and its replies. A search link copied from threads.com/search works too. Links that cannot be read are listed in the FAILED_INPUTS record.

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

Words, phrases or #hashtags, one per line, such as openai or #artemis. Without a login Threads shows only its top results for a search: about 20 posts, with no paging and no "Recent" tab.

## `maxPosts` (type: `integer`):

Stops after this many posts for each profile (newest first; a thread's follow-up posts by the author count as posts) or search. Profiles can be read back to their first post. Set 0 to save only profile rows.

## `newerThan` (type: `string`):

Skips profile and search posts older than this date (for example 2026-09-01) or age (for example 7 days). Leave empty to read as far back as the limit above allows. Post links and their replies are always saved.

## `includeProfiles` (type: `boolean`):

Adds one row per profile link with the username, full name, bio, follower count, verified badge, profile picture and bio links. Turn it off to save only posts.

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

Also saves the replies people left under each post link, with the conversations under them.

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

Stops after this many replies for each post link.

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

Which replies come first, the same choice as on threads.com.

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

Leave this empty: the Actor connects to Threads directly and, if it is ever refused, retries through Apify datacenter and then residential proxies on its own.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.threads.com/@zuck",
    "https://www.threads.com/@mosseri"
  ],
  "searchQueries": [],
  "maxPosts": 10,
  "includeProfiles": true,
  "includeReplies": true,
  "maxRepliesPerPost": 50,
  "repliesSort": "TOP",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "startUrls": [
        "https://www.threads.com/@zuck",
        "https://www.threads.com/@mosseri"
    ],
    "maxPosts": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("mina_safwat/threads-scraper-no-cookies").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 = {
    "startUrls": [
        "https://www.threads.com/@zuck",
        "https://www.threads.com/@mosseri",
    ],
    "maxPosts": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("mina_safwat/threads-scraper-no-cookies").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 '{
  "startUrls": [
    "https://www.threads.com/@zuck",
    "https://www.threads.com/@mosseri"
  ],
  "maxPosts": 10
}' |
apify call mina_safwat/threads-scraper-no-cookies --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mina_safwat/threads-scraper-no-cookies"
        }
    }
}
```

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/C7hVjwC3Vi8C4RVWW/builds/eL5i7MgFhl5qtj4q2/openapi.json
