# Threads Profile Lookup: threads profile scraper from $2/1k (`accountable_eel/threads-profile-lookup`) Actor

Threads profile scraper: paste Threads handles or profile URLs and get one flat row per profile with display name, bio, exact follower count, verified badge, private flag, profile picture and bio link. Read live from the profile page's own payload, no login and no cookies. Never charged for a miss.

- **URL**: https://apify.com/accountable\_eel/threads-profile-lookup.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.52 / 1,000 profile founds

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?

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 Lookup: threads profile scraper from $2/1k

You give this actor a list of Threads handles or profile URLs and for each one it returns the
display name, bio, exact follower count, verified badge, private-account flag, profile picture and
bio link. Every field is read from the profile page's own data at request time. No login, no
cookies, no browser automation, and no stored database sits between you and the answer.

### Who it's for

Influencer agencies building a shortlist of Threads creators, social teams reporting on how a
brand's Threads account compares with its Instagram twin, and anyone maintaining a creator roster
who is tired of opening one tab per handle to read a follower count. It also fits the plainer
enrichment job: a spreadsheet with a Threads handle column and no numbers next to it. Pricing is
per profile: a few tenths of a cent for a profile that came back with data, and nothing for a
handle that is misspelled or belongs to a deactivated account. No seat license, no monthly
minimum, no credit system to decode.

### Why this one

- **Exact follower counts.** The number returned is the integer Threads itself holds, not a
  rounded "5.7M" from the visible page. That matters the moment you want week-over-week growth
  rather than a screenshot.
- **No login, no cookies, no headless browser.** The profile payload is in the page Threads serves
  to an ordinary request. This actor reads it directly, which is both faster and far cheaper than
  driving a browser, and it means no account of yours is ever involved.
- **Never charged for a miss.** A handle that does not exist, or an account that has been
  deactivated, gets a row saying so and costs nothing. See "Price" below for the found-row rate.
- **Both domains and every handle form work.** `zuck`, `@zuck`, a `threads.com` link and an older
  `threads.net` link all resolve to the same lookup, so you do not have to normalise your column
  before pasting it.
- **Private accounts still resolve.** Threads serves profile-level facts for a private account, so
  display name, bio, verified badge and follower count all come back, with `isPrivate: true`
  flagging the account as locked rather than failing the lookup.
- **No posts, and it says so.** This version returns profile metadata only. That is a stated
  boundary, not an omission you find out about after paying.

### What you get

Every row starts with the same five fields, then the profile fields.

| Field | Type | Description |
|---|---|---|
| `query` | text | The handle or URL you submitted, echoed back |
| `found` | boolean | `true` if the profile was found |
| `status` | text | `OK` on a match; `NOT_FOUND`, `BLOCKED`, `BAD_FORMAT`, or `REQUEST_FAILED` on a miss |
| `message` | text | Plain-English reason for a miss, only present when `found` is `false` |
| `scrapedAt` | ISO 8601 datetime | When the page was fetched |
| `handle` | text | The account's Threads handle, without the `@` |
| `userId` | text | The account's stable numeric ID, which survives a handle change |
| `fullName` | text | The account's display name |
| `bio` | text | The bio text |
| `followerCount` | number | Exact follower count |
| `verified` | boolean | Whether Threads shows a verified badge on the account |
| `isPrivate` | boolean | Whether the account is private |
| `profilePicUrl` | image | Profile picture, at the largest size the page offers |
| `externalUrl` | link | The external link in the bio, if the account sets one |
| `profileUrl` | link | Canonical profile page |

Deselect any field in the Input tab's column picker to drop it from every row: `query`, `found`,
`status`, `message` and `scrapedAt` always stay.

### Price

Pay-per-event. A flat per-run fee covers session/proxy warmup; you're billed
per item only when data is actually found and returned — see
`.actor/pay_per_event.json` for exact prices. A miss is never charged.

1,000 handles through this actor: **about $2** if every one resolves, less if some do not, and
less again on a paid Apify plan. A handle that does not exist is never billed, so a messy list
costs you only for the rows you actually got.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `profiles` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~threads-profile-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"profiles":["zuck","natgeo","mosseri"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

1) Open the Input tab and paste your list into "Threads handles or profile URLs to look up": one
   per line, as a bare handle (`zuck`), an `@handle`, or a full profile URL.
2) Leave "Try it first" on for your opening run. It caps the run at 5 profiles so you can check
   the output shape before spending on the whole list.
3) Optionally trim "Which columns do you want?" to the fields you actually need, or use "Only keep
   rows containing" and "Skip rows containing" to filter by keyword.
4) Turn "Try it first" off and press Start to run the full list.

Typical uses: vetting a shortlist of Threads creators before a campaign, tracking a competitor
brand's Threads following on a weekly schedule, and filling in the follower column of a creator
spreadsheet you already maintain.

### Input

```json
{
  "profiles": [
    "zuck",
    "natgeo",
    "mosseri"
  ]
}
```

One Threads handle or profile URL per line. Accepted formats: zuck, @zuck, https://www.threads.com/@zuck, https://www.threads.net/@zuck.

### Sample output

| query | found | status | handle | userId | fullName | bio | followerCount | verified | isPrivate | profilePicUrl | externalUrl | profileUrl | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| zuck | true | OK | zuck | 63055343223 | Mark Zuckerberg | Mostly superintelligence and MMA takes | 5729099 | true | false | https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-19/550174606\_17925811725103224\_8363667901743352243\_n.jpg |  | https://www.threads.com/@zuck | 2026-09-08T10:12:51.917Z |

A handle that does not exist, or one whose account has been deactivated, gets a row with
`found: false` and a `status` / `message` explaining why. Neither is charged.

### Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

```bash
curl "https://api.apify.com/v2/acts/accountable_eel~threads-profile-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"profiles":["zuck","natgeo","mosseri"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~threads-profile-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"profiles":["zuck","natgeo","mosseri"]}` (swap in an expression from an earlier node for a real value).

**Clay.** Add an "HTTP API" column: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~threads-profile-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"profiles":["{{profile}}"]}`, mapping the row's profile into the `profiles` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Threads Profile Scraper: Follower Counts | Apify" — the agent will find and run this actor.

### Tips

- Run "Try it first" on a handful of accounts whose follower counts you already know, to
  sanity-check the numbers before committing a full list.
- Store `userId`, not `handle`, as your join key. A creator can change their handle; the numeric
  ID stays put, so a rename shows up as a changed `handle` on the same `userId`.
- `externalUrl` is `null` for the many accounts that do not set a bio link. That is normal, not a
  sign of a failed lookup.
- Keep the parallel-request setting low on a long list. A steady run gets through more handles
  than a burst that starts collecting `BLOCKED` rows.
- A Threads handle is usually the same string as the account's Instagram handle, so an existing
  Instagram creator list is often a usable input list as-is.
- Re-run the same list on a schedule and diff `followerCount` between runs to chart growth. This
  actor keeps no history of its own.

### vs. alternatives

| | What it costs | What you get | Trade-off |
|---|---|---|---|
| **This actor** (`threads-profile-lookup`) | $2 per 1,000 found profiles at the FREE tier, less on paid tiers, nothing for a miss | One flat row per handle: display name, bio, exact follower count, verified badge, private flag, profile picture, bio link | Profile metadata only. It returns none of the account's threads, replies or reposts, and no following count, because the profile page does not carry one for a logged-out visitor. |
| **apify/threads-profile-api-scraper** | $2.50 to $5.99 per 1,000 across the group of Threads actors | The same profile shape, from the vendor most Threads buyers land on first | It is the established option with the review history. This one is cheaper per profile and returns the same fields; that is the whole of the difference, so pick on price and on which output shape drops into your table more cleanly. |
| **Meta's Threads API** | Free | A documented, supported contract | It only reaches accounts you own or manage. For any other handle it is not an option, which is why this actor exists. |
| Doing it yourself | Your time, plus finding the profile payload inside a page that ships roughly a megabyte of framework data, and keeping up as Meta reshapes it | The same data | The payload hunt, the request headers that decide whether the data is served at all, and the deactivated-versus-missing distinction are the maintenance this actor absorbs. |

Prices for third-party tools are their published figures as of September 2026 and are not tracked
here; check the vendor before relying on the comparison.

### FAQ

**Why does a row say `found: false`?**
Either the handle does not exist or the account was deactivated (`NOT_FOUND`), the input is not a
valid Threads handle shape (`BAD_FORMAT`), or the request was refused or failed after retries
(`BLOCKED` / `REQUEST_FAILED`). The `message` column names which. None of them is charged.

**Am I charged for a miss?**
No. The charge fires only when a profile actually resolves and its data is returned. A
nonexistent handle produces a row, unless you turn on "Hide rows with no result", and costs
nothing.

**Do I need a Threads or Instagram login?**
No. There is no input field that accepts a credential. The actor reads the public profile page,
the same page a logged-out visitor sees.

**Is the follower count exact or rounded?**
Exact. The visible page abbreviates large numbers; the underlying data carries the real integer,
and that is what `followerCount` returns.

**Why is there no following count?**
Threads does not publish a following count on a logged-out profile page, so there is nothing
honest to put in that column. It is left out rather than filled with a guess.

**Does this return threads, replies or reposts?**
No. This version is profile metadata only. If you need post-level data, this is not the actor for
it, and the README will say so until that changes.

**Does it work on private accounts?**
Yes, for the profile-level fields. Threads still serves display name, bio, verified badge and
follower count for a private account's public profile page, and `isPrivate: true` flags it.

**Is this a live check or a stored database?**
Live. Every run fetches the current page. There is no cached snapshot behind it, which is also why
growth tracking needs a schedule plus your own storage rather than a history field here.

**Is this GDPR-relevant?**
What comes back is an account's own public, self-published profile information, the same fields
any visitor sees without logging in. It returns no private data and no follower lists.

**Can an AI agent call this directly?**
Yes. It is on the Apify MCP server, so an agent in Claude, Cursor or another MCP client can find
and run it by name, or you can call the REST endpoint shown above from any script or workflow.

### Related actors

- [X Profile Lookup](https://apify.com/accountable_eel/x-profile-lookup): the same profile-stats
  shape for X, the platform most Threads accounts are also on.
- [TikTok Profile Lookup](https://apify.com/accountable_eel/tiktok-profile-lookup): follower,
  like and video counts for a list of TikTok handles.
- [YouTube Channel Lookup](https://apify.com/accountable_eel/youtube-channel-lookup): subscriber
  and video counts for a list of YouTube channels.
- [Google News Lookup](https://apify.com/accountable_eel/google-news-lookup): once a creator or
  brand is qualified, check what news coverage they are getting.

# Actor input Schema

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

One Threads handle or profile URL per line. Accepted formats: zuck, @zuck, https://www.threads.com/@zuck, https://www.threads.net/@zuck. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.

## `excludeKeywords` (type: `array`):

Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.

## `maxResults` (type: `integer`):

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

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

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

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

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "profiles": [
    "zuck",
    "natgeo",
    "mosseri"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "columns": [
    "handle",
    "userId",
    "fullName",
    "bio",
    "followerCount",
    "verified",
    "isPrivate",
    "profilePicUrl",
    "externalUrl",
    "profileUrl"
  ],
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "profiles": [
        "zuck",
        "natgeo",
        "mosseri"
    ],
    "includeKeywords": [],
    "excludeKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/threads-profile-lookup").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",
        "mosseri",
    ],
    "includeKeywords": [],
    "excludeKeywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/threads-profile-lookup").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",
    "mosseri"
  ],
  "includeKeywords": [],
  "excludeKeywords": []
}' |
apify call accountable_eel/threads-profile-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/threads-profile-lookup"
        }
    }
}

```

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/3UxCaOszCKyiLJXN6/builds/vvDGbCMsWahVyFLj9/openapi.json
