# Threads Profile Scraper — Followers, Bio Links, Recent Posts (`scrapersdelight/threads-profile-scraper`) Actor

Bulk-scrape public Threads (threads.com) profiles by username or URL: follower count, full name, bio, every bio link, verified and private flags, topic tags, plus the 4-10 most recent posts with likes, replies and reposts — and a computed recent engagement rate. $2.00 per 1,000 profiles. No login.

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

## Pricing

$2.00 / 1,000 per profile returneds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

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

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Threads Profile Scraper — Followers, Bio Links, Recent Posts

Bulk profile data from [Threads](https://www.threads.com), Meta's text network. **One row per
profile**, carrying **username, user\_id, full\_name, biography, follower\_count, is\_verified,
is\_private, bio\_links, topic\_tags, profile\_pic\_url** and the profile's **most recent posts** —
each with text, timestamp, likes, replies, reposts, quotes, media URLs and its permalink.

**No login. No cookies. No Instagram account. No CAPTCHA solving.**

**$0.002 per profile returned — $2.00 per 1,000, no actor-start fee.**

```json
{
  "profiles": ["zuck", "@natgeo", "https://www.threads.com/@openai", "mosseri", "spotify"]
}
```

Click **Try for free** and hit **Start** — that block is literally the input this Actor ships with.
That run returns 5 rows and costs **one cent**.

***

### ⚠️ Read this first: you get the 4–10 most recent posts, not a post archive

Threads server-renders only the **top of a profile's Threads tab**, and that is what this Actor
reads. Measured on **30 public profiles on 2026-08-15 through Apify proxies**, and re-measured on
**20 public profiles on 2026-08-18**: the embedded feed block carried **exactly 4 post cards on
every single one of the 50**. A card unpacks into more than one post when the author wrote a
self-thread, so the real yield was:

| Posts returned | Profiles (2026-08-15, n=30) | Profiles (2026-08-18, n=20) |
|---|---|---|
| 4 | 26 | 15 |
| 5 | 2 | 2 |
| 6 | 1 | 0 |
| 7 | 1 | 1 |
| 8 | 0 | 1 |
| 10 | 0 | 1 |

**127 posts across the first 30 profiles (4.2 each); 95 posts across the next 20 (4.8 each).**

**Correction, 2026-08-18.** An earlier version of this page said the feed cursor "cannot be spent
and there is no page 2". That was wrong, and it is corrected here rather than quietly deleted:
Threads' paginated feed query *is* reachable logged-out, and a deeper post history is technically
possible. It is simply **not what this Actor does** — deep post history is a different product with
a different price and a different failure surface, and shipping it inside a per-profile scraper
would change what you are billed for. **What this Actor sells is one row per profile with a recency
sample attached, and that is what the price and the field table describe.**

So: if what you need is a creator's **full post archive**, this is not that Actor. If what you need
is *who this account is, how big it is, how to reach them, and whether they are still active*, that
is exactly what a row is.

***

### The wedge: an engagement rate you can sort on

Every Threads profile scraper on the store hands you `follower_count`. Follower count alone is the
number that stopped meaning anything years ago. This Actor also computes, per profile, from the
posts it just read:

- `recent_avg_likes`, `recent_avg_replies`, `recent_avg_reposts` — the mean across the profile's own
  recent posts, skipping any post whose counts the author hid
- `recent_engagement_rate` — `recent_avg_likes ÷ follower_count`, to six decimals
- `last_post_at` and `days_since_last_post` — the dead-account filter

Sort a 5,000-handle pull by `recent_engagement_rate` descending and filter
`days_since_last_post < 14`, and you have a shortlist of accounts that are both *alive* and
*actually read* — which is the list an influencer-marketing or social-listening buyer was going to
build by hand anyway. It costs $10.00 to build for 5,000 handles.

Two honest caveats on that number: it is computed from **4–10 posts**, so it is a coarse recent
signal and not a 90-day average; and Threads' like counts move for hours after a post goes up, so a
row scraped 20 minutes after publication under-reads. Both are why the field is called
`recent_engagement_rate` and not `engagement_rate`.

***

### What you get — one row per profile

| Group | Fields |
|---|---|
| Identity | `username`, `user_id` (numeric, stable, the dedupe key), `full_name`, `profile_url` |
| Profile | `biography`, `bio_link`, `bio_links` (every link with its label), `bio_link_count`, `topic_tags` |
| Scale & status | `follower_count`, `total_threads_approx`, `is_verified`, `is_private`, `has_threads_profile`, `transparency_label` |
| Media | `profile_pic_url`, `profile_pic_hd_url` |
| Activity | `recent_post_count`, `last_post_at`, `days_since_last_post` |
| Engagement | `recent_avg_likes`, `recent_avg_replies`, `recent_avg_reposts`, `recent_engagement_rate` |
| Posts | `recent_posts[]` — see below |
| Provenance | `queried_handle`, `scraped_at` (ISO-8601 UTC) |

Each entry in `recent_posts[]`:

`post_id` · `post_code` · `post_url` · `author_username` · `text` · `posted_at` (ISO-8601 UTC) ·
`like_count` · `reply_count` · `repost_count` · `quote_count` · `post_type`
(`text` / `image` / `video` / `carousel`) · `image_url` · `video_url` · `carousel_count` ·
`is_paid_partnership` · `counts_hidden` · `mentions[]` · `links[]`

Counts are plain integers, timestamps are ISO-8601 UTC strings, arrays are `[]` when empty, and
anything Threads did not publish is `null` — never an empty string, never a zero standing in for
"missing".

***

### Field fill — measured, not estimated

30 public profiles (brands, publishers, creators and Meta staff accounts), run through Apify
proxies on the shipped defaults, **2026-08-15**. Sparse fields in **bold**.

#### Profile fields (n = 30)

| Field | Fill |
|---|---|
| `username`, `user_id`, `full_name`, `profile_url` | 100.0% |
| `biography` | 100.0% |
| `follower_count` | 100.0% |
| `profile_pic_url`, `profile_pic_hd_url` | 100.0% |
| `total_threads_approx` | 100.0% |
| `last_post_at`, `days_since_last_post` | 100.0% |
| `recent_avg_likes` / `_replies` / `_reposts`, `recent_engagement_rate` | 100.0% |
| `recent_posts` (non-empty) | 100.0% |
| `is_verified` = true | 93.3% (28 of 30 — a *value*, not a fill rate) |
| **`bio_link` / `bio_links`** | **80.0% (24 of 30)** |
| **`topic_tags`** | **23.3% (7 of 30)** |
| **`transparency_label`** | **0.0% (0 of 30)** |
| `is_private` = true | 0.0% (this sample was all public accounts) |

`topic_tags` are the self-declared interest tags Threads shows under a bio ("AI Threads", "UFC
Threads"). Most accounts set none. `transparency_label` is the state-controlled-media banner — it
appeared on none of these 30, and you should expect it on a small minority of news accounts only.
`bio_link` is empty on one profile in five because that account published no link.

**Re-measured independently on 24 different public profiles, 2026-08-19** (24 of 24 readable, one
pass, no retries needed): `bio_link` / `bio_links` **79.2%**, `topic_tags` **20.8%**,
`transparency_label` **0.0%** — the same three sparse fields, at the same rates. For each of them
the raw Threads payload was dumped: `profile_tags.edges` is literally `[]` on 19 of 24,
`transparency_label` is literally `null` on 24 of 24, and `bio_links` is empty on exactly the 5
accounts that show no link on threads.com. These are properties of the accounts, not gaps in the
scrape.

**One caveat the 2026-08-15 table missed:** an account can exist on Threads with **no bio and no
posts at all**. In the 2026-08-19 sample, `@lego` returned `biography: null`, `recent_post_count: 0`
and an empty `recent_posts` (its raw Threads-tab payload is `"edges":[]` with
`has_next_page: false`). So read `biography`, `last_post_at`, `days_since_last_post`,
`recent_avg_*`, `recent_engagement_rate` and `recent_posts` as **95.8% (23 of 24)** rather than
100% — a `0` / `null` there means that profile has published nothing, not that the run failed.

#### Post fields (n = 127 posts)

| Field | Fill |
|---|---|
| `post_id`, `post_code`, `post_url`, `author_username` | 100.0% |
| `text` | 100.0% |
| `posted_at` | 100.0% |
| `like_count`, `reply_count`, `repost_count`, `quote_count` | 100.0% |
| **`image_url`** | **63.8%** |
| **`video_url`** | **30.7%** |
| **`links` (non-empty)** | **26.0%** |
| **`mentions` (non-empty)** | **13.4%** |

Post types in that sample: **46 text-only, 39 video, 32 image, 10 carousel**. The media fields are
sparse because most Threads posts have no media — a `null` `video_url` means the post was not a
video, not that the scrape failed.

***

### Transport — what actually happens, with the numbers

Threads intermittently answers a logged-out profile request with its **"Threads · Log in"
interstitial** instead of the profile: a 256–361 KB HTML shell with no data in it. This is
transient and per-request — **a retry on a fresh proxy session clears it**, and the Actor does that
for you.

Measured across **two independent runs, 59 profiles, through Apify datacenter proxies**, with a
fresh pinned session on every attempt:

| Measure | Result |
|---|---|
| Profiles returned | **59 of 59 (100%)**, all within 3 attempts |
| Single requests that landed the profile | **59 of 81 (72.8%)** |
| Attempts needed | 1st try 40, 2nd try 16, 3rd try 3 |
| Residential fallback needed | 0 times |
| Duplicate rows | **0** (0 duplicate profiles in 59; 0 duplicate `post_id` in 127 posts, in-profile and across profiles) |

Read that table honestly: **a single HTTP request to Threads succeeds about seven times in ten**,
and the Actor gets you to 100% by retrying up to four times on fresh sessions, then falling back to
RESIDENTIAL proxies (capped at `max(3, 20% of your list)` per run so the fallback cannot run away
with your proxy bill). That is why the per-profile price is flat: you pay for a profile *returned*,
not for the requests it took.

A handle that fails every rung is named in the log and **not billed**. Note that Threads serves the
*same* log-in interstitial for a username that does not exist, so from outside those two cases are
indistinguishable — the log says exactly that rather than guessing.

***

### Sample row

```json
{
  "username": "spotify",
  "user_id": "63295417283",
  "full_name": "Spotify",
  "profile_url": "https://www.threads.com/@spotify",
  "biography": "squeezing in a few more summer anthems",
  "follower_count": 3130636,
  "is_verified": true,
  "is_private": false,
  "has_threads_profile": true,
  "transparency_label": null,
  "bio_link": "https://open.spotify.com/genre/0JQ5DAqbMKFJ6dHNHTv6Mx",
  "bio_links": [
    { "url": "https://open.spotify.com/genre/0JQ5DAqbMKFJ6dHNHTv6Mx", "title": "Fitness with Spotify" },
    { "url": "http://open.spotify.com", "title": null },
    { "url": "https://open.spotify.com/genre/section0JQ5IMCbQBLyGf0Sj0c3IJ", "title": "Editors’ Picks: Best Audiobooks of the Year so Far" }
  ],
  "bio_link_count": 3,
  "topic_tags": [],
  "profile_pic_url": "https://scontent-lax3-2.cdninstagram.com/v/t51.2885-19/358162502_...jpg",
  "profile_pic_hd_url": "https://scontent-lax3-2.cdninstagram.com/v/t51.2885-19/358162502_...jpg",
  "total_threads_approx": 1100,
  "recent_post_count": 4,
  "last_post_at": "2026-08-15T12:59:15.000Z",
  "days_since_last_post": 0,
  "recent_avg_likes": 28.75,
  "recent_avg_replies": 1.5,
  "recent_avg_reposts": 1,
  "recent_engagement_rate": 0.000009,
  "recent_posts": [
    {
      "post_id": "3964277724764062307",
      "post_code": "DcD8ZZHjkJj",
      "post_url": "https://www.threads.com/@spotify/post/DcD8ZZHjkJj",
      "author_username": "spotify",
      "text": "“Encouragement from other women is the best.” @Rosegray_ is opening up about …",
      "posted_at": "2026-08-15T12:59:15.000Z",
      "like_count": 8,
      "reply_count": 2,
      "repost_count": 1,
      "quote_count": 0,
      "post_type": "video",
      "image_url": "https://scontent-lax3-2.cdninstagram.com/v/t51.82787-15/774136886_...jpg",
      "video_url": "https://scontent-lax3-2.cdninstagram.com/o1/v/t2/f2/m86/AQPX0P2Uc6fDsnA...",
      "carousel_count": null,
      "is_paid_partnership": false,
      "counts_hidden": false,
      "mentions": ["rosegray_"],
      "links": []
    }
  ],
  "queried_handle": "spotify",
  "scraped_at": "2026-08-15T13:04:41.902Z"
}
```

***

### How to use it

1. Click **Try for free**, then **Start** — the prefilled input returns 5 rows immediately.
2. Replace the demo profiles with your own list: a bare username (`zuck`), an `@handle`
   (`@natgeo`), or a full URL (`https://www.threads.com/@openai` — `threads.net` works too).
   Mixed together is fine.
3. Bulk instead: open **📄 Profile URL list** and paste hundreds of URLs, upload a `.txt`/`.csv`,
   or link a Google Sheet. Entries there must be full Threads URLs — a bare username inside a file
   is ignored, because a CSV column of names cannot be told apart from data.
4. Watch the log. Every profile that could not be read is named, and the run prints its own totals
   at the end.
5. Export as JSON, CSV, Excel or HTML, or pull it from the API. The **Threads profiles** dataset
   view gives you the flat spreadsheet columns (username, name, followers, verified, bio, bio link,
   recent posts, last post, avg likes, engagement rate, URL) without the nested post array.

#### Turning off posts

`includePosts: false` drops the `recent_posts` array and the derived engagement fields, for a
slimmer profile-only row. **The price is identical** — it is the same single page request either
way — so leave it on unless the nested array is inconvenient for your pipeline.

***

### Pricing

| | |
|---|---|
| Model | Pay per event — **one** event, `profile-scraped` |
| Rate | **$0.002 per profile returned** ($2.00 per 1,000) |
| Actor start fee | **none** |
| Not billed | Profiles Threads refused to serve; duplicate handles that resolve to a profile already returned in the same run |

The shipped default input (5 profiles) costs **$0.01**. 1,000 profiles cost $2.00. Nothing else is
metered — posts, bio links and the computed engagement fields all ride along inside the profile row
at no extra charge.

Comparable live Threads profile rows on the store on 2026-08-15 ran from $0.0005 to $0.01 per item,
with the lane leader at $0.005.

***

### Honest limits

1. **4–10 posts per profile — the recency sample, not an archive.** Restated here because it is the
   single thing most likely to disappoint: this Actor reads the server-rendered top of the Threads
   tab and does not page back, so buying more rows does not buy more posts per row. Deep post
   history is reachable on Threads but is deliberately out of scope here (see the correction in the
   first section) and belongs in a separate post-history Actor.
2. **`total_threads_approx` is rounded by Threads, not by us.** Threads publishes "1.5K Threads" on
   the profile's own meta description; we parse it to `1500`. It is an approximation to two or three
   significant figures — use it for banding, not for arithmetic. `follower_count` is exact.
3. **Like counts are a moving target.** A post scraped minutes after publication has not finished
   accumulating likes. If you are comparing accounts, compare rows scraped in the same window.
4. **Private profiles are reported, not guessed at.** `is_private` is Threads' own flag and is
   passed through as-is. All 30 profiles in the measured sample were public, so the shape of a
   private row is **not** something this page has measured — expect identity and follower count to
   be present and `recent_posts` to be empty or short, because Threads does not serve a private
   account's feed to a logged-out client.
5. **Discovery is not included.** You bring the usernames. This Actor does not search Threads and
   does not enumerate followers, because logged-out Threads search is hard-capped and returns no
   pagination cursor — a search mode here would quietly truncate, so there isn't one.
6. **No e-mail field.** Threads publishes no contact e-mail on a profile. `bio_links` is the
   contact path — for 80% of profiles it is a website you can then enrich.
7. **This Actor returns profile data only** — no replies, no follower lists, no hashtag or search
   feeds. Those are separate Threads surfaces and belong in their own Actors.

***

### How it works

`GET https://www.threads.com/@<username>` returns a fully server-rendered page with the profile
record and the top of the profile's feed embedded as JSON inside Meta's `RelayPrefetchedStreamCache`
blocks. The Actor slices those two blocks out structurally (balanced-bracket scan, so a `}` inside a
string can never truncate the object), parses them, and builds one row.

That is the whole mechanism: no headless browser, no GraphQL token mint, no login, no cookie jar.
The Actor runs in 512 MB. What it costs in reliability is the retry loop described in the transport
section — which is a cheaper price than a 4 GB Chromium.

***

### When a run comes back short

- **Some profiles named "not readable"** — either those usernames do not exist on Threads (an
  account has to opt in to Threads separately from Instagram), or Threads walled every session for
  them. Re-run just those handles; a fresh run gets fresh sessions.
- **A run fails with "No Threads profiles returned"** — that is deliberate. The Actor fails loudly
  rather than finishing green with an empty dataset. Check the usernames actually exist by opening
  one in a browser, then re-run.
- **`recent_posts` empty on a row** — the account is private, or has posted nothing.
- **Fewer posts than you expected** — see the first section. 4 is the normal number.

***

### Who buys this

- **Influencer / creator discovery** — score and rank a candidate list by real recent engagement
  instead of follower count, and drop the accounts that have gone quiet.
- **Social listening & brand monitoring** — a repeatable daily snapshot of a watchlist: follower
  trajectory, posting cadence, what they said last and how it landed.
- **Competitive research** — the same fields for a competitor's account and everyone they mention.
- **Lead enrichment** — turn a list of Threads handles into names, bios and the websites in their
  bio links, which is the joinable key into the rest of your stack.

***

### Legal & fair use

**Read this before you run it.** `https://www.threads.com/robots.txt` opens with:

> `# Notice: Collection of data on Threads through automated means is prohibited unless you have`
> `# express written permission from Threads and may only be conducted for the limited purpose`
> `# contained in said permission.`

and its wildcard rule is:

> `User-agent: *`
> `Disallow: /`

There is **no allowed path** in that file for a generic client — the per-path `Disallow` lists
further down apply only to named search-engine crawlers. This Actor reads pages that are public and
require no login, and it does not authenticate, does not solve challenges and does not touch private
data — but it is **not** operating inside a robots.txt allowance, and this page will not pretend
otherwise. Whether that is acceptable for your use is your decision to make against Meta's Terms of
Service and your own legal advice.

Profile records can contain personal data — a person's name, photograph, biography and links. **You
are responsible** for how you store and use them, including GDPR, CCPA and the rules that apply to
any outreach you do with them.

Threads® and Instagram® are trademarks of Meta Platforms, Inc. This Actor is not affiliated with,
endorsed by, or connected to Meta.

***

### Feedback

Found a missing field, or want a filter? Open an issue on the **Issues** tab. If the Actor earns it,
a review on the **Reviews** tab helps other buyers find it.

# Actor input Schema

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

One profile per line. Accepts a bare username (`zuck`), an `@handle` (`@natgeo`), or a full profile URL (`https://www.threads.com/@openai`, `threads.net/@mosseri` — both domains work). You are billed per profile **returned**, so this list is also your cost ceiling: 1,000 profiles = $2.00. Duplicate entries collapse to one billed row.

Leave this **and** the URL list empty and the Actor runs a 3-profile demo sample (`zuck`, `natgeo`, `openai`, $0.006) instead of failing, so an API or agent call with no input still gets real rows back.

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

The bulk path: paste many profile URLs at once, upload a .txt/.csv of them, or link a Google Sheet. Entries must be full Threads URLs (`https://www.threads.com/@handle`) — a bare username inside a file is ignored, because a CSV column of names cannot be told apart from data. Merged with the field above and de-duplicated. Reading the list is free; you are billed only for profiles returned.

## `includePosts` (type: `boolean`):

Keep this on to get the `recent_posts` array (4-10 posts: text, timestamp, likes, replies, reposts, quotes, media URLs, post URL) and the derived `recent_avg_likes` / `recent_engagement_rate` fields. Turn it off for a slimmer, profile-only row — the price per profile is the same either way, because it is the same single page request.

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

Start with the default. Threads intermittently answers a logged-out request with its log-in interstitial instead of the profile; the Actor clears that by retrying on a fresh proxy session (measured: 29 of 29 profiles readable within 3 attempts through Apify datacenter proxies) and, if a profile still will not load, retries it through RESIDENTIAL — capped at max(3, 20% of your list) per run so the fallback stays bounded. You normally never need to touch this field.

## `requestConcurrency` (type: `integer`):

How many profiles to fetch at once. The default of 4 is what the measured retry numbers were taken at. Raising it shortens the run but gives Threads more reason to serve the log-in interstitial, which costs you retries — not money.

## `requestDelayMs` (type: `integer`):

Pacing per worker, applied after each profile. 0 is allowed and is faster; 500 ms is the measured default.

## Actor input object example

```json
{
  "profiles": [
    "zuck",
    "@natgeo",
    "https://www.threads.com/@openai"
  ],
  "startUrls": [],
  "includePosts": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestConcurrency": 4,
  "requestDelayMs": 500
}
```

# Actor output Schema

## `profiles` (type: `string`):

Username, full name, bio, follower count, verified and private flags, bio links, topic tags, the 4-10 most recent posts and the derived recent engagement rate.

# 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 = {
    "profiles": [
        "zuck",
        "@natgeo",
        "https://www.threads.com/@openai",
        "mosseri",
        "spotify"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/threads-profile-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 = { "profiles": [
        "zuck",
        "@natgeo",
        "https://www.threads.com/@openai",
        "mosseri",
        "spotify",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/threads-profile-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 '{
  "profiles": [
    "zuck",
    "@natgeo",
    "https://www.threads.com/@openai",
    "mosseri",
    "spotify"
  ]
}' |
apify call scrapersdelight/threads-profile-scraper --silent --output-dataset

```

## MCP server setup

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