Threads Profile Scraper | Bios & Recent Posts avatar

Threads Profile Scraper | Bios & Recent Posts

Pricing

$4.00 / 1,000 profile or posts

Go to Apify Store
Threads Profile Scraper | Bios & Recent Posts

Threads Profile Scraper | Bios & Recent Posts

Collect public Threads bios, displayed follower counts and recent visible posts from usernames or profile URLs. Export creator research to JSON or CSV. Logged-out visibility limits coverage; no full-history guarantee.

Pricing

$4.00 / 1,000 profile or posts

Rating

0.0

(0)

Developer

Nick McNemar

Nick McNemar

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

6 days ago

Last modified

Share

Review public profiles from a handle list

Threads Profile Scraper: Collect public Threads bios, displayed follower counts and recent visible posts from usernames or profile URLs. Export creator research to JSON or CSV. Logged-out visibility limits coverage; no full-history guarantee.

Start with a small example

  1. Open Input, switch to JSON and paste the example below. Replace the example usernames with your own research targets when ready.
  2. Check the live Pricing tab and set a run spending limit.
  3. Run the Actor, then open the Workflow output view. Inspect username, fullName, followerCount, biography, profileUrl, found.
  4. Export JSON for nested data or CSV for a spreadsheet. Review a small sample before increasing the scope.
{
"usernames": [
"nasa"
],
"maxItems": 1,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
]
},
"outputMode": "profile"
}

At the rate checked September 9, 2026, 1 saved rows cost $0.004 in Actor event fees ($4.00 per 1,000 rows). Actual returned rows determine the event fee. Taxes and other account services may be separate.

What can I use it for?

  • Lead enrichment. Attach Threads user IDs, display names, verified status and recent activity to a list of handles you already have from Instagram, a CRM or a creator database.
  • Influencer and creator vetting. Check recent activity and engagement (likes, replies, reposts per post) across hundreds of accounts in one run.
  • Brand and competitor monitoring. Poll a fixed set of profiles on a schedule and diff the newest posts to catch announcements, campaigns and replies as they land.
  • Account discovery and validation. Find out which of your Instagram handles actually exist on Threads; handles that do not resolve come back flagged rather than silently dropped.
  • Content research. Pull the latest posts, link previews and media from the accounts that matter to you into a spreadsheet for review.

What data does it return?

By default each profile produces one record with its posts nested under posts. Switch Output mode to posts for one flat row per post with the profile's key fields attached, which is easier to filter in CSV or Excel.

FieldExample
username, userIdnasa, 28829152388
fullNameNASA
biographyMaking the seemingly impossible, possible.
followerCount, followerCountText12700000, 12.7M — the figure Threads displays, so rounded above 10,000
threadCount131 — the account's total posts as displayed
bioLinksAlways [] — link details are not served to logged-out visitors
isVerified, isPrivatetrue, false
profilePicUrl, profilePicUrlHdCDN image URLs
profileUrlhttps://www.threads.com/@nasa
foundtruefalse when the handle has no public Threads profile
postCount, latestPostAt7, 2026-09-03T21:06:28.000Z
morePostsRequireLogintrue when Threads shows a "log in to see more" wall
posts[]Array of post records, newest first
scrapedAt, errorISO timestamp, null unless the profile could not be fetched

Each post record contains:

FieldExample
id, code, url3976157978336241783, DcuJp1dkSh3, https://www.threads.com/@nasa/post/DcuJp1dkSh3
textThe post's text, null for media-only posts
postedAt, timestamp2026-08-31T03:43:09.000Z, 1788214989
likeCount, replyCount, repostCount, quoteCount, reshareCount3154, 61, 118, 22, 20
mediaTypetext, image, video or carousel
imageUrls, videoUrlsLargest available image per slide; MP4 URL per video (the poster frame lands in imageUrls)
linkPreview{ url, title, description, displayUrl, imageUrl } for posts that share a link
isReply, replyToUsernametrue, nasa for a self-thread continuation
quotedPost, repostedPost{ id, code, url, text, authorUsername } when the post quotes or reposts another
isPinned, isEdited, isPaidPartnershipbooleans
accessibilityCaptionMeta's generated alt text for images
authorUsername, authorIdAuthor of the post, normally the profile owner

In posts mode every row also carries profileUsername, profileUserId, profileFullName, profileFollowerCount, profileIsVerified and profileUrl.

Illustrative output

The example below explains the output shape; values are illustrative and are not a live result or a promise that every field is populated.

{
"username": "nasa",
"userId": "28829152388",
"fullName": "NASA",
"biography": "Making the seemingly impossible, possible. ✨",
"bioLinks": [],
"followerCount": 12700000,
"followerCountText": "12.7M",
"threadCount": 131,
"isVerified": true,
"isPrivate": false,
"profilePicUrl": "https://instagram.fagc3-1.fna.fbcdn.net/v/t51.82787-19/...",
"profileUrl": "https://www.threads.com/@nasa",
"found": true,
"postCount": 7,
"latestPostAt": "2026-09-03T21:06:28.000Z",
"morePostsRequireLogin": true,
"posts": [
{
"id": "3976157978336241783",
"code": "DcuJp1dkSh3",
"url": "https://www.threads.com/@nasa/post/DcuJp1dkSh3",
"text": "Main character energy unlocked! NASA astronaut Jessica Meir and @europeanspaceagency astronaut Sophie Adenot will conduct a spacewalk Tuesday, Sept. 1 ...",
"postedAt": "2026-08-31T03:43:09.000Z",
"likeCount": 3154,
"replyCount": 61,
"repostCount": 118,
"quoteCount": 22,
"mediaType": "image",
"imageUrls": ["https://instagram.fagc3-2.fna.fbcdn.net/v/t51.82787-15/...jpg"],
"videoUrls": [],
"linkPreview": null,
"isReply": false,
"authorUsername": "nasa"
}
],
"scrapedAt": "2026-09-04T21:12:40.512Z",
"error": null
}

How to use it

  1. Paste the handles you want under Threads usernames or profile URLs, one per line. nasa, @nasa and https://www.threads.com/@nasa are all accepted, and duplicates are removed.
  2. Pick an Output mode: one row per profile (default) or one row per post.
  3. Click Start. The defaults are tuned for most jobs.
  4. Download the results as JSON, CSV, Excel or XML from the Output tab, or read them from the dataset via the API.

Leave Max concurrency at its default; Threads is tolerant of steady sequential traffic but not of bursts. Residential proxies are enabled by default because Threads rate-limits datacenter IP ranges with HTTP 429 responses — leave that setting as it is unless you route traffic through your own residential IPs.

Input

{
"usernames": ["nasa", "zuck", "mkbhd"],
"outputMode": "profile",
"maxItems": 100,
"maxConcurrency": 2
}

How it works

Threads server-renders the logged-out profile page with the profile record and the visitor-visible posts embedded as JSON. The actor requests each profile page once with the same navigation headers a browser sends, parses the embedded JSON blocks and walks them for the profile and post records. Nothing is executed, no session is created and no internal API is called, so there are no tokens to expire and no signatures to break.

Handles that Threads redirects to its login page do not have a public Threads profile: either the account has never joined Threads or the name does not exist. These are returned as rows with found: false and an explanatory error so your input list and output line up one-to-one. Entries that cannot be a Threads handle at all — empty lines, names over 30 characters, stray punctuation — get the same treatment with error set to Not a valid Threads username or profile URL, so nothing you pasted disappears silently. Transient empty responses are retried automatically.

Pricing

You pay per dataset row: one row per profile in profile mode, one row per post in posts mode. Rows for handles that do not resolve are charged like any other row, since knowing that an account is not on Threads is part of the answer. There are no subscriptions or minimums, and you can cap the maximum spend of any run before you start it.

Scope and responsible use

This actor reads only what Threads shows to any logged-out visitor on a public profile page. It does not log in, does not accept or use cookies, session tokens or credentials, and does not attempt to bypass any access control, rate limit or bot-protection challenge. Private profiles return their public header (name, verified and private flags, profile picture) and no posts. Media URLs point at Meta's CDN and are signed, so they expire after a few days; copy the files if you need them to persist. You are responsible for using the results in accordance with the laws that apply to you and the terms of the platforms involved.

Limitations

  • Posts per profile are capped by Threads, not by this actor. A logged-out visitor sees roughly 4 to 10 of an account's most recent posts (self-replies inside a thread count toward that number), after which Threads shows a login wall. Pagination is not available without an account and this actor does not log in, so it cannot return an account's full post history. If you need archives, this is not the right tool.
  • Follower and thread counts are approximate. Threads no longer renders the exact profile record for logged-out visitors; the counts come from the figures Threads itself displays in the page summary (12.7M, 1.5K), so they are rounded above 10,000. Bio links are not served logged-out and come back empty. Accounts with no posts are still found, with postCount: 0.
  • View counts are not exposed on public profile pages, so they are not returned.
  • Post rows include a profile owner's self-replies and quotes but not replies written by other users; a separate post-detail page would be needed for full reply trees.
  • Meta changes the embedded payload from time to time. The parser matches records by their shape rather than by fixed paths, which survives most changes, but a breaking change can reduce output until the actor is updated.

Something missing?

Open an issue on this actor's Issues tab with the username and the field you expected. Reproducible misses are usually fixed within days.

Before a larger run

Billing follows output rows: profile mode returns profile rows; posts mode returns individual post rows. These are paid examples, not a free-results offer. No source-site API key is needed for the example in Console; programmatic Apify API access still requires Apify authentication.

Five internal launch smoke rounds passed on September 6, 2026. This describes small-input test coverage, not customer reviews, a service-level guarantee or a large-batch benchmark. Website behavior and data availability can change.

Interpret empty results and errors

Check the run status and log if no records are returned. Restrictive filters, inaccessible content or a changed source page can produce an empty result; empty output does not prove there are no matching records on the source.

Billing follows saved rows. Profile mode saves one row per processed profile; posts mode saves individual post rows. An unavailable-profile row can still incur a charge. Proxy selection and run duration can affect operating costs. Do not increase concurrency or enable a more expensive proxy merely to work around an unclear result.

For a reproducible problem, open this Actor’s Issues tab with a small public input, expected behavior and relevant error text. Remove tokens and confidential information. No response-time or uptime guarantee is offered.

Use the result in an automation

In Make or n8n, use the Apify integration to run this Actor with the same JSON input, wait for completion, then retrieve its default dataset. Route failed runs and error rows to a review step before sending valid results to your spreadsheet or CRM. Scheduling does not make these Actors emit only new records: deduplicate downstream using the source URL or record ID.

For Node.js, install the official apify-client package and set your own APIFY_TOKEN environment variable. The following example starts a paid run with a small spending limit.

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const input = {
"usernames": [
"nasa"
],
"maxItems": 1,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
]
},
"outputMode": "profile"
};
const run = await client.actor('keystonelabs/threads-profile-scraper').call(input, {
memory: 512, timeout: 180, maxTotalChargeUsd: 0.10
});
if (run.status !== 'SUCCEEDED') throw new Error('Run did not succeed: ' + run.id);
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 100 });
console.log(items);

The first 100 rows are retrieved in this example. Use the dataset API pagination for a larger result. Keep credentials out of shared inputs and source files.