Threads Followers Scraper With Audience Segments
Pricing
from $5.99 / 1,000 results
Threads Followers Scraper With Audience Segments
Threads Followers Scraper extracts follower profiles and audience segments, including usernames, bios, follower counts, profile links, locations, interests, and engagement data. Ideal for audience research, creator discovery, segmentation, competitor analysis, and lead generation.
Pricing
from $5.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Threads Followers Scraper With Audience Segments
Threads Followers Scraper With Audience Segments logs in with your own Threads session, pulls the follower list for one or more profiles, and classifies every follower into a tier, visibility, verification, and relationship segment as it collects — then adds one audience_summary row per profile describing the real composition of that follower list. Every row is structured JSON, ready to pass into an LLM, load into a spreadsheet, or feed a monitoring pipeline. Paste your Threads usernames, set how many followers you want per profile, and rows stream into the dataset as each profile finishes.
What is Threads Followers Scraper With Audience Segments?
Threads Followers Scraper With Audience Segments is an Apify Actor that fetches the follower list of one or more Threads profiles through the same BarcelonaFriendshipsFollowersTabQuery GraphQL query the Threads web app uses, then computes a real audience breakdown on top of the raw follower data — without you writing a single line of aggregation code. This is the capability neither of the two directly competing Threads follower scrapers on the Apify Store expose in their output schema: automatic per-follower tier/visibility/verification/relationship tagging, plus a per-profile composition row.
A Threads account is required. The Actor authenticates every request with a sessionId cookie value you supply — there is no anonymous or public-only mode, and the run exits immediately if sessionId is missing.
- 🧵 Collects followers for one or many Threads profiles in a single run, from plain
@usernamesor full profile URLs - 🏷️ Tags every follower row with
followerTier,accountVisibility,verificationStatus,isOnboardedThreads, andrelationshipToTarget - 🧮 Adds one
audience_summaryrow per profile with verified/private/mutual percentages and a tier distribution - 🔎 Filters out followers below a minimum follower count before they are saved, counted, or charged
- 🌐 Escalates through a datacenter-then-residential Apify Proxy ladder when a direct request is blocked
- 🎚️ Lets you cap how many followers to collect per profile, from 1 up to 100,000
What data can you get with Threads Followers Scraper With Audience Segments?
Threads Followers Scraper With Audience Segments returns two kinds of dataset rows for every run: an individual record for each follower collected, and one aggregate record per profile summarizing that follower list.
| Result Type | Extracted Fields | Primary Use Case |
|---|---|---|
Follower record (recordType: "follower") | source, target_username, user_id, pk, username, full_name, is_verified, is_private, profile_pic_url, follower_count, following, followed_by, outgoing_request, has_onboarded_to_text_post_app, __typename, profile_url, followerTier, accountVisibility, verificationStatus, isOnboardedThreads, relationshipToTarget | Build a segmented, filterable list of exactly who follows a target profile |
Audience summary (recordType: "audience_summary") | source, target_username, total, verifiedPct, privatePct, mutualPct, onboardedThreadsPct, tierDistribution, nanoCount, microCount, midCount, macroCount, megaCount | Read a profile's follower composition without writing your own aggregation pass |
Audience segments (the differentiator)
Every follower row is tagged with five segmentation fields, all computed from data the Actor already fetched — nothing is guessed or looked up separately.
followerTier is assigned from the follower's own follower_count:
| Tier | follower_count range |
|---|---|
nano | 0 – 999 |
micro | 1,000 – 9,999 |
mid | 10,000 – 99,999 |
macro | 100,000 – 999,999 |
mega | ≥ 1,000,000 |
accountVisibility is "private" when Threads' own text_post_app_is_private flag is true, otherwise "public". verificationStatus is "verified" when is_verified is true, otherwise "unverified". isOnboardedThreads is a boolean copy of has_onboarded_to_text_post_app. relationshipToTarget is derived from the follower's following and followed_by friendship flags: "mutual" when both are true, "fan" when the follower follows back without being followed, "following_target" when followed without following back, and "none" otherwise:
{"followerTier": "mega","accountVisibility": "public","verificationStatus": "verified","isOnboardedThreads": true,"relationshipToTarget": "mutual"}
Audience summary row
Each profile gets one extra row, only when emitAudienceSummary is on (the default) and at least one follower was collected for it. total is the count of followers that passed the minFollowerCount filter; verifiedPct, privatePct, mutualPct, and onboardedThreadsPct are each computed as a percentage of that total, rounded to two decimals. tierDistribution is a {tier: count} map across all five tiers, duplicated as flat nanoCount … megaCount fields for spreadsheet-friendly columns without a nested object.
Because the summary is computed after filtering, turning minFollowerCount up doesn't just shrink the follower rows you receive — it changes what verifiedPct, mutualPct and the tier counts mean, since they now describe only the followers above your threshold rather than the target's entire collected audience. Set minFollowerCount to 0 when you want the summary to reflect the whole list you collected.
Why not build this yourself?
Threads does not publish a general-purpose API that returns an arbitrary profile's follower list to a third-party caller, so the alternative to an Actor is reverse-engineering the same GraphQL contract the Threads web app uses — and keeping it working as Threads changes it.
The BarcelonaFriendshipsFollowersTabQuery persisted query only executes when every Relay "provider" flag it references is present in the POST body — omit one and Threads returns HTTP 200 with data: null and an errors array, which looks like an empty follower list unless you check for it specifically. This Actor ships a known-good set of 50 provider flags and also scrapes the live flag names out of the page's own JS bundles at runtime, merging both so a valid superset is sent even after Threads adds new flags. Locating the doc_id for that query is its own small project: it lives inside one of several rotating JS bundle URLs referenced from the profile page's deferred-script payload, and has to be pattern-matched out of minified code. None of that is documented anywhere — it has to be found and kept current.
Beyond the query contract itself, every page of results needs a fresh CSRF token — Threads issues a new one per request, so a scraper that caches it will start failing partway through a large follower list, not at the first request. Add the residential-proxy requirement for consistent access and the maintenance burden of a DIY script goes well past "send a GET request and parse HTML": it is an ongoing integration against an internal API that was never meant for third-party callers, and it has to be re-verified every time Threads ships a front-end change.
How does Threads Followers Scraper With Audience Segments work?
For each profile, the Actor requests the public profile page with your session cookies attached, extracts the Meta APP_ID, a CSRF token, the target's numeric user ID, and the JS bundle URLs referenced on that page. It fetches those bundles concurrently to locate the doc_id for the followers query and to harvest any Relay provider flag names not already in its known-good set. With those four values resolved, it posts the BarcelonaFriendshipsFollowersTabQuery GraphQL request in pages of 50, refreshing the CSRF token before every page since Threads issues a new one per request. Follower nodes come back with a friendship_status object (following, followed_by, outgoing_request) that the Actor reads directly into relationshipToTarget — no separate relationship lookup is made.
Pagination for a profile stops when maxFollowers unique rows have been saved, or after 10 consecutive pages return no new unique follower — whichever comes first. A 0.35-second delay separates each page request.
Every GraphQL request is sent with a full desktop browser header set — sec-ch-ua, sec-fetch-*, x-ig-app-id, x-csrftoken, and x-fb-friendly-name: BarcelonaFriendshipsFollowersTabQuery — rather than a default HTTP client signature, matching what the Threads web app itself sends. Duplicate followers across pages are filtered out before they are pushed: each node is keyed on its pk (falling back to user_id, then @username if neither is present), so a follower that Threads returns twice across two pages is only saved once and only counted once toward maxFollowers.
How does Threads Followers Scraper With Audience Segments handle rate limits and blocking?
The Actor tries a direct connection first. If token resolution fails, it escalates to an Apify datacenter proxy group (BUYPROXIES94952); if that also fails, it rotates through up to three residential proxy sessions before giving up on that profile and moving to the next one. Once a residential session succeeds mid-run, it is kept "sticky" and reused for the rest of that profile's pagination rather than re-resolved on every page.
A GraphQL response that comes back HTTP 200 with data: null and a populated errors array is treated as a failed request, not an empty result — the Actor logs the error message and retries through the proxy ladder rather than recording zero followers. If a session cookie has expired mid-run, the CSRF-refresh step fails and the Actor logs a warning and moves on to the next profile instead of retrying indefinitely.
How to scrape Threads followers with Threads Followers Scraper With Audience Segments?
- Open Threads Followers Scraper With Audience Segments on the Apify Store and click Try for free
- Paste one or more Threads profile URLs or plain
@usernamesintourls— this is required - Paste your Threads
sessionidcookie value intosessionId— also required, and the run will not start without it - Set
maxFollowers,minFollowerCount, andemitAudienceSummaryto shape what comes back - Click Start, then download the dataset as JSON or CSV, or read it through the Apify API
proxyConfiguration is left out of the example below on purpose — it defaults to Apify Proxy on, and the Actor's own datacenter-then-residential ladder handles escalation, so most runs don't need to touch it:
{"urls": ["zuck", "https://www.threads.com/@creator"],"sessionId": "YOUR_SESSIONID","maxFollowers": 200,"minFollowerCount": 0,"emitAudienceSummary": true}
How to segment multiple profiles in one run
urls accepts a list, one entry per line — paste as many Threads profiles as you need. They are processed one at a time, in the order supplied, and each one gets its own audience_summary row when emitAudienceSummary is on, so a batch of profiles produces directly comparable composition rows without any extra grouping step on your end.
⬇️ Input
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
urls | Yes | array | Threads links or plain usernames, one per line. Mix and match — @zuck, https://www.threads.com/@creator, or a bare zuck all work. | ["zuck", "https://www.threads.com/@creator"] |
sessionId | Yes | string | Your Threads/Instagram sessionid cookie value, copied from your browser's cookie inspector. Default "". Treat it like a password. | "YOUR_SESSIONID" |
maxFollowers | No | integer | Cap on how many follower rows to collect per profile. Minimum 1, maximum 100000, default 20. | 200 |
minFollowerCount | No | integer | Drops follower accounts whose own follower count is below this number before they are saved. 0 keeps everyone. Minimum 0, default 0. Dropped accounts do not count against maxFollowers and are excluded from the audience summary. | 500 |
emitAudienceSummary | No | boolean | Adds one audience_summary row per profile with the real composition of its collected followers. Default true. | true |
proxyConfiguration | No | object | Apify Proxy settings. Optional — the Actor escalates through its own proxy ladder automatically. Prefilled with {"useApifyProxy": true}. | {"useApifyProxy": true} |
Example input
{"urls": ["zuck"],"sessionId": "YOUR_SESSIONID","maxFollowers": 50,"minFollowerCount": 0,"emitAudienceSummary": true,"proxyConfiguration": { "useApifyProxy": true }}
Common pitfall: sessionId wants only the cookie's value, not the full sessionid=...; cookie string and not another cookie like csrftoken or ds_user_id. Open your browser's cookie inspector for threads.com, find the cookie literally named sessionid, and paste just that value. If the cookie has expired, the run logs "session may have expired" partway through a profile and stops collecting for it — re-paste a fresh value and re-run.
urls accepts three interchangeable formats in the same list: a full threads.com/@username or threads.net/@username link, a @username handle, or a bare username with no @ — all three are parsed down to the same plain username internally, so there's no need to normalize your list before pasting it in.
⬆️ Output
Every row is typed, normalized JSON with a consistent field set for its recordType, exportable as JSON, CSV, Excel, or any format the Apify dataset export supports. The default dataset table view shows 12 columns — recordType, target_username, username, full_name, follower_count, followerTier, relationshipToTarget, accountVisibility, verificationStatus, isOnboardedThreads, profile_url, user_id — which is a subset of what each row actually carries. Follower rows hold 22 fields in total, and audience_summary rows hold 14 fields whose names (total, verifiedPct, tierDistribution, and so on) don't overlap with the default view's columns at all — switch to the API, JSON, or Overview tab, or the Export button, to see the summary row's own fields.
One preserved quirk: profile_url is always built on the threads.net domain (https://www.threads.net/@username), even though every request the Actor sends goes to threads.com — both resolve to the same profile, this is simply how the field is constructed.
Every follower field has a typed fallback rather than being omitted when Threads doesn't return it: string fields default to "", boolean fields to false, follower_count to 0, and __typename to "XDTUserDict". That means every follower row carries the same 22 keys on every run — you never need a presence check before reading a field.
Every row pushed to the dataset — a follower record or an audience_summary record — is billed as one row_result event; there is no separate, cheaper event type and no free accounting row. Accounts dropped by minFollowerCount never reach the push step, so they are never charged. If a profile yields zero followers, no audience_summary row is written for it either, since the summary is only emitted from at least one collected follower — so a profile that returns nothing costs you nothing.
Scraped results
[{"recordType": "follower","source": "threads","target_username": "zuck","user_id": "73956966771","pk": "73956966771","username": "baselad21","full_name": "Bassel Kaddour","is_verified": false,"is_private": false,"profile_pic_url": "https://scontent.cdninstagram.com/v/t51.2885-19/example.jpg","follower_count": 1,"following": false,"followed_by": false,"outgoing_request": false,"has_onboarded_to_text_post_app": true,"__typename": "XDTUserDict","profile_url": "https://www.threads.net/@baselad21","followerTier": "nano","accountVisibility": "public","verificationStatus": "unverified","isOnboardedThreads": true,"relationshipToTarget": "none"},{"recordType": "follower","source": "threads","target_username": "zuck","user_id": "6273049812","pk": "6273049812","username": "nightowl_studio","full_name": "Night Owl Studio","is_verified": false,"is_private": true,"profile_pic_url": "https://scontent.cdninstagram.com/v/t51.2885-19/example2.jpg","follower_count": 4820,"following": true,"followed_by": false,"outgoing_request": false,"has_onboarded_to_text_post_app": true,"__typename": "XDTUserDict","profile_url": "https://www.threads.net/@nightowl_studio","followerTier": "micro","accountVisibility": "private","verificationStatus": "unverified","isOnboardedThreads": true,"relationshipToTarget": "following_target"},{"recordType": "follower","source": "threads","target_username": "zuck","user_id": "17841400123456789","pk": "17841400123456789","username": "worldnews_daily","full_name": "World News Daily","is_verified": true,"is_private": false,"profile_pic_url": "https://scontent.cdninstagram.com/v/t51.2885-19/example3.jpg","follower_count": 3200000,"following": true,"followed_by": true,"outgoing_request": false,"has_onboarded_to_text_post_app": true,"__typename": "XDTUserDict","profile_url": "https://www.threads.net/@worldnews_daily","followerTier": "mega","accountVisibility": "public","verificationStatus": "verified","isOnboardedThreads": true,"relationshipToTarget": "mutual"},{"recordType": "audience_summary","source": "threads","target_username": "zuck","total": 3,"verifiedPct": 33.33,"privatePct": 33.33,"mutualPct": 33.33,"onboardedThreadsPct": 100.0,"tierDistribution": { "nano": 1, "micro": 1, "mid": 0, "macro": 0, "mega": 1 },"nanoCount": 1,"microCount": 1,"midCount": 0,"macroCount": 0,"megaCount": 1}]
How can I use the data extracted with Threads Followers Scraper With Audience Segments?
- Creators and social media managers: read
tierDistributionandverifiedPctoff theaudience_summaryrow to see whether an audience skews toward large accounts or genuine small followers before pitching a brand partnership, without opening every follower's profile by hand. - AI engineers and LLM developers: feed the follower and summary rows straight into an agent's context — the agent issues a run, receives typed JSON back, and can answer "how verified is this creator's audience" without any transformation step in between.
- Brand partnerships and influencer marketing teams: filter follower rows on
followerTierin["macro", "mega"]andverificationStatus == "verified"to shortlist high-value followers worth a direct outreach, and userelationshipToTarget == "mutual"to find accounts the target already engages with. - Market researchers: collect
audience_summaryrows across several competing profiles in one run and compareverifiedPct,mutualPct, and tier counts side by side to benchmark audience quality across a niche, usingminFollowerCountto exclude low-signal accounts from the comparison before it's computed.
How do you monitor audience composition over time?
Audience monitoring means re-running the same profile list on a schedule and comparing each profile's audience_summary row to its previous run, rather than reading a single snapshot. Because every follower row carries a stable user_id/pk and every summary row carries target_username, both are easy to key on across runs.
The fields worth diffing between runs are the ones on the audience_summary row: total (audience size), verifiedPct and mutualPct (audience quality signals), privatePct, and the five keys inside tierDistribution (or the flat nanoCount … megaCount fields, if you prefer a flat table). A rising total with a falling verifiedPct usually means growth from low-signal accounts; a rising mutualPct means the target profile is following more of its own audience back.
A typical workflow: run the Actor weekly against the same urls list, keep only rows where recordType == "audience_summary", join each new run's row to the prior run's row on target_username, and alert when verifiedPct, mutualPct, or any tierDistribution count moves past a threshold you set. This Actor has no built-in scheduler — use an Apify Schedule to trigger the run automatically and read each run's dataset through the Apify API for the comparison.
Integrate Threads Followers Scraper With Audience Segments and automate your workflow
Threads Followers Scraper With Audience Segments works with any language or tool that can send an HTTP request to the Apify API.
REST API with Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<YOUR_USERNAME>/threads-follower-audience-segmenter").call(run_input={"urls": ["zuck"],"sessionId": "YOUR_SESSIONID","maxFollowers": 100,"minFollowerCount": 0,"emitAudienceSummary": True,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row.get("recordType") == "audience_summary":print(row["target_username"], row["verifiedPct"], row["tierDistribution"])else:print(row["username"], row["followerTier"], row["relationshipToTarget"])
Works the same way in Go, Ruby, Node.js, or cURL — any client that can call the Apify API.
No-code tools (n8n, Make, Zapier)
In n8n, the Apify node (or an HTTP Request node pointed at the Apify run endpoint with your token) accepts the same JSON input shown above. In Make, the Apify module maps dataset rows straight into a Google Sheets or Airtable step — split the flow on recordType if you want follower rows and audience summary rows routed to different destinations. Both platforms handle scheduling on their own end, so a recurring audience check needs no code.
Scheduled monitoring and delivery
The Actor has no built-in scheduler or webhook parameter of its own, but every Apify Actor can be triggered on a cron-style Schedule from the Apify Console, and every run can push a completion notification through Apify's webhook integration — point one at your own endpoint to pull the finished dataset the moment a scheduled run completes.
Is it legal to scrape Threads follower data?
Scraping publicly visible follower data is generally treated as lawful, but Threads Followers Scraper With Audience Segments is login-gated rather than anonymous: it authenticates every request with your own sessionId cookie, so what it returns is whatever your logged-in account can see, not necessarily what an anonymous visitor sees.
Follower usernames, display names, verification status, and profile pictures are personal data about identifiable individuals, so data protection regimes like the GDPR and CCPA can apply to how you store and process what you collect — plan retention and use accordingly. Beyond data protection law, using an authenticated session to run automated requests is also governed by Meta's Threads Terms of Use, and you are responsible for complying with them for your account. Scraping for AI training and scraping for operational monitoring carry different risk profiles and different obligations around data minimization and retention. Consult your legal team for commercial use cases involving bulk data storage.
❓ Frequently asked questions
Do I need to be logged in to Threads to use this scraper?
Yes. sessionId is a required input — the Actor authenticates as you, using the sessionid cookie value from your own logged-in Threads or Instagram session. There is no anonymous mode; omitting it stops the run before any request is made.
How many followers does the scraper return per profile?
Up to maxFollowers, which defaults to 20 and can be set from 1 to 100,000. Followers are fetched 50 at a time per GraphQL page and accumulated until the cap is reached. The actual count for a profile can come in lower than your cap: collection for that profile stops early after 10 consecutive pages return no new unique follower, which happens once Threads has nothing left to paginate — and a high minFollowerCount can also reduce the saved count, since dropped accounts don't count toward the cap either.
How does Threads Followers Scraper With Audience Segments handle Threads' anti-bot measures?
It escalates from a direct request to a datacenter proxy, then to rotating residential proxy sessions, keeping a session sticky once it works — see "How does Threads Followers Scraper With Audience Segments handle rate limits and blocking?" above for the full ladder. It also detects a GraphQL execution error (HTTP 200 with data: null) and retries instead of recording it as an empty result.
Does Threads Followers Scraper With Audience Segments extract audience segments automatically?
Yes. Every follower row arrives with followerTier, accountVisibility, verificationStatus, isOnboardedThreads, and relationshipToTarget already computed — no post-processing needed. These fields are always present on follower rows; they are absent on audience_summary rows, which carry the aggregate percentages instead.
What does relationshipToTarget mean, and how is it calculated?
It classifies each follower against the account whose session cookie is being used, from Threads' own following/followed_by friendship flags: "mutual" (follows and is followed), "fan" (follows, not followed back), "following_target" (followed, doesn't follow back), or "none" (neither).
Does minFollowerCount affect the audience summary?
Yes. Accounts dropped by minFollowerCount are excluded before the audience_summary row is computed — they are never counted in total, never factored into any percentage, and never charged as a row, since they are filtered before the push step.
How do I monitor a Threads profile's audience composition over time?
Schedule the Actor to run against the same urls on a recurring basis, keep only rows where recordType == "audience_summary", and diff verifiedPct, mutualPct, total, and tierDistribution against the prior run for the same target_username. See "How do you monitor audience composition over time?" above for the full workflow.
Does Threads Followers Scraper With Audience Segments work with Claude, ChatGPT, and AI agent frameworks?
Yes, as an HTTP endpoint. It is callable through the Apify API by any agent framework that can make a request — LangChain, CrewAI, a custom tool definition — which lets an agent retrieve live, segmented follower data before answering a question about an audience.
How does Threads Followers Scraper With Audience Segments compare to other Threads follower scrapers?
Checked on the Apify Store on 26 July 2026, igview-owner/threads-user-followers-scraper markets "audience analytics" and ships a summary record with raw counts (verified_count, private_count, active_count), but its per-follower rows carry no tier, no visibility label, and no relationship classification — those have to be computed from the raw fields yourself. apibox/threads-user-followers-scraper returns a minimal five-field follower record (id, username, full_name, follower_count, is_verified) with no summary row at all. Of the two, as documented on their listings, neither ships per-follower tier/visibility/verification/relationship tags or a percentage-based audience_summary row computed automatically during the run — the segmentation this Actor adds on top of the same base follower data.
What happens if a profile can't be reached, or has no followers?
Nothing is fabricated in either case. If token resolution fails after the Actor exhausts its direct-then-datacenter-then-residential proxy ladder, it logs "Couldn't open @username after several tries — skipping this profile" and moves on without writing any row for it. If a profile is reached but genuinely has zero followers, no follower rows and no audience_summary row are written for it, since the summary is only computed from at least one collected follower.
Can I use Threads Followers Scraper With Audience Segments without managing proxies myself?
Yes, for proxy infrastructure — leave proxyConfiguration on its default and the Actor escalates through Apify's datacenter and residential proxy groups on its own when a direct request is blocked. You do still need to supply your own Threads sessionId cookie value; that credential isn't something Apify can provide for you.
🔗 Related scrapers
Pair follower-side audience data with what a profile itself posts:
| Scraper Name | What it extracts |
|---|---|
| Threads User Posts Scraper: Hashtag & Mention Breakdown | Public Threads posts per profile, with a ranked hashtag- and mention-frequency breakdown report row |
💬 Your feedback
Found a bug, or need a field that Threads exposes but this Actor doesn't surface? Open an issue on the Actor's Issues tab on Apify — reports that include a target username and the run's log output are the fastest to act on. Field requests are easiest to evaluate when you note whether the field already exists in the raw GraphQL response or would need a new derived segment.