Threads Followers Scraper By Influencer Filter avatar

Threads Followers Scraper By Influencer Filter

Pricing

from $4.99 / 1,000 results

Go to Apify Store
Threads Followers Scraper By Influencer Filter

Threads Followers Scraper By Influencer Filter

Threads Followers Scraper: Discover followers of selected Threads profiles and filter by influencer criteria such as follower count and engagement. Collect usernames, bios, profile URLs, and available public details for influencer research, audience analysis, and lead generation.

Pricing

from $4.99 / 1,000 results

Rating

0.0

(0)

Developer

API Empire

API Empire

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

a day ago

Last modified

Share

Threads Followers Scraper — Real Followers, With Influencers Ranked First

Threads Followers Scraper By Influencer Filter pulls the real follower list of one or more Threads profiles and writes every follower it collects to your dataset — real username, display name, real follower count, verified and privacy status, profile link — then ranks them and flags the ones that clear your influencer bar. "Influencer" is a label and a sort order, not a filter that deletes your data: a run that collects 50 real followers gives you 50 real follower rows, with the most influential first. Every response is typed, normalized JSON — no HTML, no selectors, no parsing.

What is Threads Followers Scraper By Influencer Filter?

Threads Followers Scraper By Influencer Filter is an Apify Actor that collects the followers of a Threads profile through Threads' own GraphQL backend, writes all of them to your dataset with their real follower counts, and marks and ranks the influential subset with isInfluencer, influencerRank and influencerTier. It targets threads.com (Meta's Threads platform) and requires a logged-in Threads or Instagram session cookie — there is no cookie-free or anonymous mode.

sessionId is stored as an encrypted secret field, so it is not shown back in the Console input form and is not written to run logs. Treat the value you paste there like a password anyway, and don't share a saved input JSON that still contains it.

Authentication is not optional, and it is not a design choice. Verified live against threads.com: the private mobile endpoints i.instagram.com/api/v1/friendships/<pk>/followers/ and www.threads.net/api/v1/friendships/<pk>/followers/ both answer {"require_login": true} with HTTP 401 under every user-agent tried (desktop, curl, Googlebot, and the Threads/Instagram Android app UAs); and the BarcelonaFriendshipsFollowersTabQuery Relay module is absent from all 549 JavaScript bundles Threads serves to a logged-out session, so its doc_id cannot even be discovered anonymously. Profile pages, follower counts, verification and privacy flags are public — the follower list is not. With a valid session the same bundle set grows to ~389 bundles that do contain the module, and the query works.

It is built for:

  • 🎯 Exporting every collected follower with real data, each carrying a 1-based influencerRank and a nano / micro / mid / macro / mega influencerTier
  • ⭐ Flagging the influential subset with isInfluencer and sorting those rows to the top, so "who are this profile's notable followers" is answered by reading from row 1 down
  • 📊 Writing one influencer_summary row per profile with influencer counts, top and median follower counts, and a tier breakdown
  • 📤 Exporting the result as JSON, CSV or Excel with no proxy management and no HTML parsing on your end

What data does Threads Followers Scraper By Influencer Filter collect?

Two dataset record types come out of every run — every collected follower profile, and a per-profile rollup — plus a block of ranking/tier fields computed on top of the raw follower data.

Data TypeKey FieldsJSON Field Names
Follower profile dataUsername, display name, verification and privacy status, own follower count, relationship to the targetusername, full_name, is_verified, is_private, follower_count, following, followed_by
Influencer ranking & tier dataWhether the follower clears your bar, rank across the whole collection, tier label, profile linkisInfluencer, excludedBy, influencerRank, influencerTier, profile_url
Per-profile summary dataInfluencer vs. non-influencer counts, top/median follower count, tier breakdown, the criteria appliedinfluencerCount, nonInfluencerCount, topFollowerCount, medianFollowerCount, collectedTopFollowerCount, tierBreakdown

🧵 Need more Threads data?

If you need the profile's own posts rather than its followers, Threads User Posts Scraper (also published under API Empire) pulls a profile's post history instead of its audience — pair the two when you want both the content a creator publishes and who their most influential followers are.

Why not build this yourself?

Meta's official Threads API is built for posting content and reading insights on an account you own or manage — it does not expose an endpoint that returns another user's follower list, so there is no official API path to the data this Actor collects, and no comparison table to draw against one.

Building this yourself means reverse-engineering Threads' internal GraphQL backend, and the traps are not obvious ones:

  • The BarcelonaFriendshipsFollowersTabQuery persisted query needs a doc_id that Threads rotates on every deploy. It is not in the eagerly loaded scripts — the followers tab is lazy-loaded, so the id only exists in the Bootloader rsrcMap, hundreds of bundles you have to enumerate and search. And it is only shipped to logged-in sessions, so you cannot discover it anonymously at all.
  • There is no /@user/followers page to scrape. It 404s even when you are logged in.
  • A set of Relay "provider" variables (__relay_internal__pv__*relayprovider) must all be present in the POST body or the query execution-errors. Threads returns that failure as an HTTP 200 with data: null and an errors array — indistinguishable from a real empty response unless you check for it explicitly.
  • Relay connections paginate with first + after. Send only first and every request returns page one forever; you dedupe your own results down to 50 rows and conclude the account has 50 followers.
  • A stale sessionid makes threads.com return HTTP 500 with an empty body for pages that load fine anonymously, so attaching your cookie to public requests breaks the public path too — and gives you no signal about which part failed.
  • A missing follower count coerced to 0 silently fails every >= threshold test, so a naive "filter by influence" feature deletes rows it never actually measured.

This Actor already handles all of that — full-rsrcMap persisted-query discovery, provider-flag harvesting, cursor pagination, split public/authenticated connections, follower-count enrichment, and a proxy escalation ladder — so you don't have to maintain it against Threads' next change.

Why do developers and teams scrape Threads followers?

🎯 For partnership and talent scouts

Point the Actor at a creator's or a brand's Threads profile with minFollowerCount set to your partnership floor and verifiedOnly switched on, and the rows flagged isInfluencer: true sort to the top as your outreach shortlist — while the rest of the audience stays in the same export for context. Because influencerRank orders by real follower_count regardless of sortBy, the highest-reach candidate is always the first row you look at. A scout screening a dozen creators for a co-marketing campaign can run all twelve profiles in a single urls list and get back one ranked shortlist per target, instead of opening each profile's follower tab by hand.

📊 For marketers and influencer marketing teams

Filter a brand's own followers by follower_count to surface the micro- and mid-tier creators already following the account organically — an easier conversation to start than cold outreach, since these people are already engaged. influencerTier buckets candidates into nano / micro / mid / macro / mega for you, so a campaign that specifically wants micro-influencer partners can filter influencerTier == "micro" after export instead of eyeballing follower counts row by row.

🔬 For researchers and analysts

tierBreakdown on the influencer_summary row gives an instant distribution — how many of a profile's followers fall into nano, micro, mid, macro and mega — useful for studying audience composition across a set of accounts without building the aggregation yourself. Because the summary row also echoes the exact filter values a profile's pass ran with (minFollowerCount, verifiedOnly, mustBePublic, sortBy), a batch of profiles scraped with the same settings produces directly comparable summary rows for cross-account analysis.

🤖 For AI engineers and agent builders

Every row is flat, typed JSON keyed by recordType, so an agent can branch on "follower" vs "influencer_summary" and route each to a different handler without writing a parser. influencerRank and influencerTier are pre-computed, so an agent tasked with "find this profile's most influential followers" can read the answer directly off the top rows rather than re-deriving a ranking from raw follower counts inside the agent loop.

How to scrape Threads followers (step by step)

  1. Open Threads Followers Scraper By Influencer Filter on its Apify Store listing and click Try for free
  2. Paste one or more Threads profiles into urls — bare usernames like zuck, @zuck, or full https://www.threads.com/@zuck links all work, one per line
  3. Paste your Threads/Instagram sessionId cookie value — this is required; the run exits with zero rows without it
  4. Optionally set your influencer bar with minFollowerCount, verifiedOnly and mustBePublic — these flag and sort, they don't delete, so you always get the full follower list back. Raise maxFollowers for a deeper sample. Leave enrichFollowerCounts on so any missing follower count is resolved rather than left unrankable
  5. Click Start, then download the results as JSON, CSV or Excel from the run's Dataset tab

What to do when Threads changes its structure

The scraper is maintained, and the output schema — the field names and types documented below — stays stable on your end even when Threads changes its internal GraphQL query IDs or provider-flag set. No specific turnaround time is published for fixes.

How does Threads Followers Scraper By Influencer Filter handle rate limits and blocking?

Token resolution (the app ID, CSRF token, target user ID and the GraphQL doc_id needed to query followers) climbs an escalation ladder rather than failing on the first refusal. Every profile starts on a direct connection with no proxy at all. If that doesn't produce a complete set of tokens, the Actor tries your own proxyConfiguration, then an Apify datacenter proxy, then Apify residential. A working route is kept sticky for the rest of the run. If your account has no residential allocation, that rung is detected once and skipped instead of being retried on every profile. Turning Apify Proxy off is honoured — the run then stays direct-only.

Two failure modes are told apart explicitly, because they need different fixes. If the public profile page loads but the authenticated request is refused, the run fails with "the sessionId cookie is expired, invalid or incomplete" — no amount of proxy switching fixes a dead cookie. If the handle simply has no Threads account, the run says so and moves on without burning the whole ladder on it.

Within a profile's follower collection loop the CSRF token is reused and only re-fetched after a failure, rather than re-downloading the ~800 KB profile page before every single request. A GraphQL response that comes back as HTTP 200 with data: null and a populated errors array — Threads' signature for a bad doc_id or a missing Relay provider variable — is treated as a failed request, not an empty result. HTTP 401/403 is treated as a terminal authentication failure for that profile rather than something to retry. Followers are deduplicated by Threads' own pk (falling back to @username when pk is missing) as they're collected, so a retried or overlapping page never produces duplicate rows.

Runs that fail, fail. A run that cannot collect follower data for a single profile — no sessionId, no usable username in urls, a rejected cookie — finishes with status FAILED and an explanatory status message, not a green SUCCEEDED with an empty dataset.

⬇️ Input

ParameterRequiredTypeDescriptionExample Value
urls✅ YesarrayThreads profile links or plain usernames, one per line. Accepts a bare username (zuck), an @-prefixed handle (@zuck), a full threads.com or threads.net profile URL, or an { "url": "..." } / { "href": "..." } object. Entries that resolve to no username are skipped.["zuck", "https://www.threads.com/@creator"]
sessionId✅ YesstringThe value of the sessionid cookie from a logged-in Threads or Instagram browser session (DevTools → Application/Storage → Cookies). Stored as an encrypted secret. The run fails immediately with a clear error if it's missing, and fails with "the public profile page loaded but the logged-in request was refused" if the cookie is stale. The matching ds_user_id cookie is derived from the value automatically — you only supply this one."58012345678%3AAbCdEfGhIjKlMn%3A..."
maxFollowersNointegerHard cap on how many follower rows to collect per profile before any filter runs. Minimum 1, maximum 100000. Default 200. Values ≤ 0 are silently clamped up to 1. Enforced as a real cap — collection stops the moment it is reached, mid-page if necessary.500
minFollowerCountNointegerKeep only followers whose own follower_count is at least this value. Minimum 0 (keeps everyone), which is the default. Negative values are silently clamped to 0. Set this realistically — see the calibration note below.500
verifiedOnlyNobooleanWhen true, a follower must be verified to be flagged isInfluencer. Unverified followers are still returned. Default false.false
mustBePublicNobooleanWhen true, a follower must be public to be flagged isInfluencer. Private followers are still returned. Default false.false
dropNonMatchingNobooleanAdvanced, default false. When true, followers not flagged isInfluencer are removed from the dataset instead of returned. If that would leave the dataset empty, the Actor keeps everything anyway and warns — a successful collection never yields zero rows.false
sortByNostringOrder of the follower rows in the dataset. Rows flagged isInfluencer always come first; this sets the order within each group. "followers" = highest follower_count first; "username" = alphabetical. Default "followers". An unrecognized value passed via the API is silently replaced with "followers". influencerRank is always assigned by real follower count descending, regardless of this setting."followers"
enrichFollowerCountsNobooleanDefault true. Threads' follower list does not reliably carry each follower's own follower count. When this is on, every collected follower whose count came back missing is looked up on its public Threads profile page, so minFollowerCount, influencerRank and influencerTier operate on real numbers instead of zeros. Each enriched row is tagged follower_count_source: "profile_page". Capped at 5,000 lookups per profile (each lookup pulls a full profile page); rows beyond that keep follower_count_source: "unknown". Turn it off for a faster run when you only need the raw list.true
proxyConfigurationNoobjectApify Proxy settings. Prefilled with {"useApifyProxy": true}. The Actor always attempts a direct (no-proxy) connection first, then escalates to your configured groups, then to Apify datacenter, then to Apify residential if your account has a residential allocation. Setting {"useApifyProxy": false} is respected — the run then stays direct-only instead of silently forcing Apify Proxy back on.{"useApifyProxy": true}

⚠️ Calibrating minFollowerCount (read this before you set it)

Threads follower lists are dominated by very small and brand-new accounts. Measured live against real follower samples:

Target profileIts own followersSample sizeMedian follower countHighest in sampleClear 10,000
@zuck5.7M5071,2140
@mosseri1.0M48141,6460
mid-sized creator16020693,1240

These are verified numbers, not estimates: 12 of 12 sampled counts were cross-checked against each account's own public Threads profile page and matched exactly.

So a minFollowerCount of 10000 flags nobody on a typical run — which is why the default is 0. Practical approach: run once with 0, read collectedTopFollowerCount and collectedMedianFollowerCount off the summary row, then set your bar somewhere under that top value. In most samples 5002000 is what separates the standouts from the noise.

Crucially, an unreachable bar costs you nothing: all the real followers are still in your dataset, just with isInfluencer: false. The run also tells you the number to use — e.g. "all 50 follower(s) are in your dataset, but none are flagged as influencers — the most followed account in this sample has 1,214 follower(s), below your minFollowerCount of 10,000. Set minFollowerCount to 1,214 or lower to flag some."

Example input

{
"urls": ["zuck", "https://www.threads.com/@creator"],
"sessionId": "58012345678%3AAbCdEfGhIjKlMn%3A...",
"maxFollowers": 500,
"minFollowerCount": 10000,
"verifiedOnly": false,
"mustBePublic": false,
"sortBy": "followers",
"enrichFollowerCounts": true,
"proxyConfiguration": { "useApifyProxy": true }
}

⬆️ Output

Typed, normalized JSON with two distinct record shapes, distinguished by the recordType field: "follower" and "influencer_summary". Follower rows are written after the whole per-profile collection pass finishes — the Actor buffers each profile's followers, ranks and sorts them, then pushes, so rows for a given profile land together rather than streaming in mid-collection. Export as JSON, CSV or Excel, or read the dataset through the Apify API.

The Actor's dataset view shows 15 columns shared across both record types. That view is a subset: follower rows carry 20 keys and summary rows carry 14 — six of the follower keys (source, user_id, pk, profile_pic_url, __typename, follower_count_source) and four relationship/status keys (following, followed_by, outgoing_request, has_onboarded_to_text_post_app) aren't in the default view, and neither are the summary row's source, collectedCount, tierBreakdown, minFollowerCount, verifiedOnly, mustBePublic and sortBy. All of them are in the dataset itself — open the API or JSON view, or read the dataset through apify_client, to get every field.

Follower rows (recordType: "follower")

{
"recordType": "follower",
"source": "threads",
"target_username": "zuck",
"user_id": "73956966771",
"pk": "73956966771",
"username": "somecreator",
"full_name": "Some Creator",
"is_verified": true,
"is_private": false,
"profile_pic_url": "https://scontent.cdninstagram.com/v/t51.2885-19/...",
"follower_count": 250000,
"following": false,
"followed_by": false,
"outgoing_request": false,
"has_onboarded_to_text_post_app": true,
"__typename": "XDTUserDict",
"profile_url": "https://www.threads.com/@somecreator",
"follower_count_source": "followers_query",
"isInfluencer": true,
"excludedBy": [],
"influencerRank": 1,
"influencerTier": "mid"
}
  • target_username — the profile whose follower list this row came from, i.e. the value from urls
  • user_id / pk — Threads' internal numeric IDs for the follower account, as strings (both fields carry the same value)
  • is_private — read from Threads' own text_post_app_is_private field on the follower node
  • following / followed_by / outgoing_request — the follower's relationship status to your logged-in session, not to the target profile
  • profile_url — built as https://www.threads.com/@{username}, the same domain the Actor fetches against
  • follower_count_source — where the number in follower_count came from: "followers_query" (it was in Threads' follower payload), "profile_page" (looked up on the follower's public profile because the payload omitted it), or "unknown" (missing and enrichment was off or failed)
  • isInfluencertrue when the follower met every criterion you configured (minFollowerCount, verifiedOnly, mustBePublic). With the defaults, every follower qualifies. Rows flagged true are written first
  • excludedBy — an array naming the criterion that disqualified the row (below_min_followers, not_verified, private, or unknown_follower_count); empty when isInfluencer is true. unknown_follower_count is deliberately distinct: it means the account was never measured, not that it fell short
  • influencerRank — 1-based, assigned by real follower_count descending across everything collected for that profile, with username as an alphabetical tiebreak and unknown counts sorted last. It always reflects follower-count order, independent of sortBy and of isInfluencer
  • follower_count — an integer, or null when Threads didn't supply one and enrichment couldn't resolve it. It is never coerced to 0: a 0 in this field means the account genuinely has zero followers (confirmed against their profile page), while null means "not known". Filters and ranking treat the two completely differently
  • influencerTier — computed from the follower's real follower_count: nano below 1,000 · micro 1,000–99,999 · mid 100,000–999,999 · macro 1,000,000–9,999,999 · mega 10,000,000 and above · unknown when the count is null. The nano band exists because without it essentially every row in a real Threads follower sample lands in micro and the breakdown tells you nothing

Summary row (recordType: "influencer_summary"), one per profile

{
"recordType": "influencer_summary",
"source": "threads",
"target_username": "zuck",
"collectedCount": 50,
"keptCount": 50,
"droppedCount": 0,
"enrichedCount": 0,
"followerCountsKnown": 50,
"influencerCount": 6,
"nonInfluencerCount": 44,
"topFollowerCount": 1214,
"medianFollowerCount": 7,
"collectedTopFollowerCount": 1214,
"collectedMedianFollowerCount": 7,
"influencerTopFollowerCount": 1214,
"influencerMedianFollowerCount": 233,
"excludedBelowMinFollowers": 44,
"excludedNotVerified": 0,
"excludedPrivate": 0,
"excludedUnknownFollowerCount": 0,
"tierBreakdown": { "unknown": 0, "nano": 44, "micro": 6, "mid": 0, "macro": 0, "mega": 0 },
"minFollowerCount": 100,
"verifiedOnly": false,
"mustBePublic": false,
"sortBy": "followers"
}
  • collectedCount — how many unique followers were pulled for this profile before any filter ran, capped by maxFollowers
  • keptCount — how many follower rows were actually written. With the default dropNonMatching: false this equals collectedCount: nothing is thrown away
  • droppedCount — rows removed from the dataset; 0 unless dropNonMatching is on
  • influencerCount / nonInfluencerCount — how many written rows are flagged isInfluencer and how many aren't; together they equal keptCount
  • influencerTopFollowerCount / influencerMedianFollowerCount — reach of the flagged subset only, null when nothing qualified
  • enrichedCount — how many of the collected followers had their follower_count filled in from their public profile page because the followers payload didn't carry one; 0 when enrichFollowerCounts is off
  • topFollowerCount — the highest follower_count among the rows written, null if there are none. It is never 0 for an empty set, because "no rows" and "the top account has no followers" are different statements
  • medianFollowerCount — the median follower_count across the rows written; an integer when the middle values allow one, otherwise a float; null if there are none
  • collectedTopFollowerCount / collectedMedianFollowerCount — the same two statistics over everything collected, before filtering. These are what make a keptCount: 0 explainable: they show how far the best available candidate actually was from your threshold
  • followerCountsKnown — how many of the collected rows have a known (non-null) follower count
  • excludedBelowMinFollowers / excludedNotVerified / excludedPrivate / excludedUnknownFollowerCount — why rows failed to qualify as influencers, broken out. A row that couldn't be assessed because its count was unknown is counted separately from one that genuinely fell short, so the summary never implies a row was measured against a bar it was never measured against
  • tierBreakdown — a nested object with all six tier keys always present (unknown, nano, micro, mid, macro, mega), counting the rows written to the dataset
  • minFollowerCount, verifiedOnly, mustBePublic, sortBy — the exact filter/sort values this profile's pass ran with, echoed onto the summary row for auditability

Billed rows. When the Actor runs on pay-per-event pricing, follower rows are charged under the row_result event; the influencer_summary row is pushed without a charged event and is not billed. On a non-PPE build no charge is attempted at all. To isolate billed rows when reading the dataset, filter on recordType == "follower"; to isolate the influencer shortlist, filter on isInfluencer == true.

How does it work?

Threads renders its followers tab through an internal GraphQL query — BarcelonaFriendshipsFollowersTabQuery — rather than exposing it as a documented public endpoint.

Two connections, on purpose. Everything Threads serves anonymously (the target's profile page, the app's JavaScript bundles, follower-count lookups) is fetched on a cookie-free connection. Only the followers tab and the GraphQL POST go out on a second connection that carries your session cookie, and that cookie is attached to it from the moment the connection is created — never bolted on after a request has already fired. This matters: threads.com answers HTTP 500 with an empty body when a stale or malformed sessionid is attached to a page that would load perfectly without one, so mixing the two turns "your cookie expired" into "nothing works at all" and hides which half actually broke.

The public page yields the numeric app ID and the target's internal user ID (read out of the profile's Relay preloader variables, which is exact). The authenticated hit yields the CSRF token and the csrftoken cookie that has to match it.

The GraphQL doc_id that identifies the persisted query is not on the profile page, and there is no /@user/followers page to read it from either — that route returns 404 both logged out and logged in, because the followers list is a client-side dialog rather than a server-rendered page. So the id is scraped out of the app's JavaScript: the shipped operation module looks like __d("BarcelonaFriendshipsFollowersTabQuery_threadsRelayOperation",[],(function(t,n,r,o,a,i){a.exports="…"}),null), and the match is anchored to that module header so an id belonging to a different query can't be picked up by mistake. The scan covers the complete Bootloader rsrcMap — ~389 bundles on a logged-in profile page — not just the handful of eagerly loaded <script> tags, because the followers-tab code is lazy-loaded and only ever appears in the map. The result is cached for the whole run, and a last-known-good id is kept as a fallback in case Threads reshuffles its bundles.

The trickiest part of the request itself is the variables payload. Threads' followers query declares a set of Relay "provider" flags (__relay_internal__pv__*relayprovider) that all have to be present in the POST body or the query execution-errors with an opaque message. The Actor harvests the live set of flag names from the same bundles it's already fetching for the doc_id, merges them with a known-good fallback list refreshed against the live bundle set, and sends the union — so a valid superset goes out on every request even as Threads adds new ones over time.

Pages past the first are requested with the after cursor taken from the connection's page_info.end_cursor, which is how every Relay connection on Threads paginates (first + after). Threads decides the page size itself — it returns ~20 nodes per page for a normal account regardless of the first value asked for — so collection continues until has_next_page goes false, the cursor stops advancing, or maxFollowers is reached, whichever comes first. Both the data.user root used by the tab query and the data.fetch__XDTUserDict root used by the paginating refetchable query are understood. Nodes are normalized into flat records and deduplicated by Threads' own pk as they arrive, which matters because consecutive pages do overlap slightly.

The follower payload carries a real per-account follower_count on essentially every node — measured live at 50/50, 48/48 and 20/20 across three targets, and 12 of 12 spot-checks matched the account's own public profile page exactly. So in normal operation enrichedCount is 0 simply because there is nothing left to look up, and the log says so in as many words rather than leaving a bare zero to be misread as "enrichment is off". For the occasional node that arrives without a count, enrichFollowerCounts (on by default) reads it from that follower's own public Threads profile page. Anything still unresolved stays null and is reported as such — never silently rewritten to 0.

The Actor buffers a profile's entire collected set in memory rather than pushing rows as they arrive, because the influencer filter, rank and tier can only be computed correctly once the whole capped sample for that profile is in hand — ranking one follower requires knowing where it stands relative to every other follower collected for that same profile.

Only data visible to your own logged-in session is collected. No password is ever requested — only the sessionid cookie value, which the Actor holds for the duration of the run and does not persist beyond it.

How does Threads Followers Scraper By Influencer Filter compare to other Threads scrapers?

Checked on the Apify Store on 25 July 2026: igview-owner/threads-user-followers-scraper documents a max_followers cap of 1,000 and multiple dataset views (followers, profiles, analytics, verified) built from the same raw follower fields, but its listing does not document follower-count, verification or privacy filtering — you get the whole collected list back and filter it yourself downstream. apibox/threads-user-followers-scraper documents a minimal username + num input with no filtering options and a five-field output example. instaprism/instagram-followers-filtered filters Instagram (not Threads) followers by count, business type, email and engagement, but its listing states results require enrichment and cites processing times of 10–120+ minutes depending on volume — a different platform and a different cost/latency tradeoff than this Actor's single-pass GraphQL collection.

FeatureThreads Followers Scraper By Influencer FilterGeneric Threads follower scraper
Influencer scoring built inminFollowerCount, verifiedOnly, mustBePublic flag and sort every row — without discarding the rest of the audience❌ Typically returns the raw list; scoring is your job downstream
Rank and tier on every rowisInfluencer + influencerRank + influencerTier (nano/micro/mid/macro/mega) computed per rowNot documented on comparable listings
Per-profile rollup rowinfluencer_summary with kept/dropped counts, top/median follower count, tier breakdownNot documented on comparable listings
Output formatTyped JSON, consistent schema across runsVaries by Actor
Proxy/anti-bot handlingDirect → your proxy config → Apify datacenter → Apify residential escalation ladder, sticky on the route that worksNot documented on comparable listings

If you're building an AI agent or RAG pipeline, the output-format row is the decision-maker — parsing HTML or an unfiltered follower dump inside an agent loop is a reliability failure mode, not a feature.

How many followers can you scrape with Threads Followers Scraper By Influencer Filter?

maxFollowers caps collection at up to 100,000 followers per profile (minimum 1, default 200) — that cap is the ceiling on how many follower rows you get back per profile, and on how many candidates your influencer criteria have to score.

Threads itself limits how much of a large account's follower list it will serve, and that limit is lower than this Actor's cap. Measured live: a 160-follower account and a 52,000-follower account both paginate normally (~20 rows per page, cursor supplied, keeps going). A 1,000,000-follower account and a 5,700,000-follower account each return one page of ~48 followers with has_next_page: false and a null cursor — there is no continuation to follow, from this Actor or from the Threads web app itself. When that happens the run logs "Threads returned a single page of N follower(s) with no continuation cursor" and finishes successfully with the sample it got. Asking for maxFollowers: 200 against a mega-account and receiving 48 rows is the platform's ceiling, not a failure of the scrape. Plan around it: this Actor is well suited to profiling the follower lists of small and mid-sized accounts in full, and to sampling the follower lists of very large ones.

Collection for a profile stops early when Threads reports has_next_page: false, when the pagination cursor stops advancing, or after 3 consecutive requests return no new unique follower — whichever happens first. Each GraphQL request pages forward using the after cursor from the previous page, with a short delay between requests. The maxFollowers cap is enforced as a true cap: collection breaks mid-page the moment it is reached. There is no schema-level limit on how many profiles you can put in urls in one run; each is processed one after another. No benchmark run time is published here — actual duration depends on the profile's follower count, how many requests it takes to reach maxFollowers, and whether the proxy ladder has to escalate past a direct connection.

Integrate Threads Followers Scraper By Influencer Filter and automate your workflow

Threads Followers Scraper By Influencer Filter works with any language or tool that can send an HTTP request — it runs as a standard Apify Actor.

REST API integration

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<YOUR_USERNAME>/threads-influencer-follower-filter").call(run_input={
"urls": ["zuck"],
"sessionId": "<YOUR_SESSIONID_COOKIE>",
"maxFollowers": 500,
"minFollowerCount": 10000,
"verifiedOnly": False,
})
for rec in client.dataset(run["defaultDatasetId"]).iterate_items():
if rec["recordType"] == "follower":
print(rec["influencerRank"], rec["username"], rec["follower_count"], rec["influencerTier"])

Works in Python, Node.js, Go, Ruby, cURL — any language that can make an HTTP request. Branch on recordType to route follower rows and the per-profile summary to separate handlers.

Automation platforms (n8n, Make, LangChain)

In n8n, use the Apify node — or an HTTP Request node pointed at the Apify run-sync endpoint with your token — and pass the same JSON input shown above; a Switch node on recordType splits follower rows from the summary row. In Make, the Apify module supports run-and-wait, so a weekly influencer-follower refresh for a watchlist of profiles can feed straight into a Google Sheets or Airtable step with no code. In LangChain or a comparable agent framework, wrap the Apify Actor call as a tool and pass influencerRank / influencerTier straight into a scoring or ranking chain — the output needs no parsing step before it reaches the model.

Scraping data a logged-in account can already see is broadly treated differently from bypassing an access control, and this Actor never requests a password — only the sessionid cookie value from a session you already control, and it returns only what that session is permitted to view.

The output — usernames, display names, verification and privacy status, and follower counts — is personal data about individual Threads accounts, so GDPR, CCPA and equivalent regimes can apply to how you store and use it, particularly at any volume beyond casual, one-off lookups. Threads' own terms of service govern automated access to the platform regardless of the legal basis for the personal data itself.

Consult legal counsel for commercial use cases involving bulk personal data, especially before combining follower data with other sources to build enriched profiles.

❓ Frequently asked questions

Does Threads Followers Scraper By Influencer Filter work without a Threads account?

No, and no Threads scraper can. Checked live: the logged-out /@user/followers route 404s, the private mobile endpoints return require_login, and the follower query's code isn't even shipped to logged-out browsers. sessionId is required; without it the run fails immediately with an explanatory message. No fabricated or cached data is ever returned in its place.

How often is the scraped data updated?

Every run is a live fetch against Threads' GraphQL backend at the time it executes — there is no caching layer. Run it again whenever you need current follower counts and tiers.

What happens if no follower clears my influencer bar?

You still get all the followers. They're written with isInfluencer: false and influencerCount: 0 on the summary, and the log tells you the exact number to lower minFollowerCount to. An unreachable bar never costs you the data — that's the whole point of flagging rather than filtering. Only dropNonMatching: true removes rows, and even then, if nothing matched the Actor keeps everything rather than handing you an empty dataset.

What happens if a profile can't be reached at all?

If token resolution fails for a username after the proxy ladder has been tried — direct, then your proxy config, then Apify datacenter, then residential — the Actor logs an error and skips that profile, moving on to the next one in urls. No row of any kind is written for a skipped profile, so check the log if a profile you expected is missing. If every profile in the run is skipped, the run finishes as FAILED rather than pretending to have succeeded with an empty dataset.

A handle that has no Threads account (an Instagram-only username, for example) is detected specifically — the profile page loads but carries no profile payload — and reported as "no Threads profile found for this handle" without retrying the whole proxy ladder against it.

Can I scrape private Threads accounts' followers?

Only what your logged-in session is already permitted to see. mustBePublic filters followers by their own privacy setting, not the target profile's — it does not grant access to a private target account's follower list beyond what your session already has visibility into.

sessionId is declared as a secret field, so Apify stores it encrypted, doesn't display it back in the input form and doesn't write it to run logs. It's still the equivalent of a live login session, so the practical risk is someone reusing it to act as you — rotate it (log out and back in on Threads/Instagram) if you believe it's been exposed, and avoid sharing a saved input JSON that still contains it.

The run fails with the public profile page loaded but the logged-in request was refused — the sessionId cookie is expired, invalid or incomplete. That wording is deliberate: it tells you Threads was reachable and the target profile was fine, so the only thing to fix is the cookie. Log back in, copy the whole current sessionid value, and run again.

If I sort by username, does that change which followers get ranked #1?

No. influencerRank is always assigned by real follower_count descending across everything collected, independent of sortBy and of isInfluencer. sortBy only changes the order rows are written in — and in both modes the rows flagged isInfluencer are written first, with sortBy deciding the order within each group. A follower ranked #1 keeps that rank number wherever it lands.

Does Threads Followers Scraper By Influencer Filter work for AI agent workflows and LLM pipelines?

Yes. It's callable as a standard HTTP endpoint through the Apify API, so any agent framework — LangChain, CrewAI, n8n, or a hand-written tool definition — can invoke it and get back typed JSON keyed by recordType, with no parsing step before passing rows to an LLM.

How does Threads Followers Scraper By Influencer Filter handle Threads' anti-bot system?

Token resolution — the app ID, CSRF token, target user ID and the GraphQL doc_id — is attempted on a direct connection first, then through your proxyConfiguration, then an Apify datacenter proxy, then Apify residential if your account has one, staying sticky on whichever route works. A GraphQL response that comes back as HTTP 200 with data: null and an errors array — Threads' signature for a bad doc_id or a missing provider variable — is treated as a failure and retried through the same ladder rather than being mistaken for a genuinely empty follower page. An HTTP 401/403 is treated as an authentication problem and is not retried, because a different IP cannot fix a rejected cookie.

How does Threads Followers Scraper By Influencer Filter compare to other Threads scrapers?

See the comparison table above. In short: comparable Threads follower Actors on the Apify Store document raw collection with a follower-count cap, but not server-side influencer filtering, per-row ranking/tiering, or a per-profile summary row — those three are what this Actor adds on top of the same underlying follower data.

Does Threads Followers Scraper By Influencer Filter return data in a format LLMs can use directly?

Yes. Every row is typed, normalized JSON with stable field names across runs. No HTML, no selectors. Pass a row directly into an LLM context window, index it into a vector store, or hand it to an agent tool.

Can I use Threads Followers Scraper By Influencer Filter without managing proxies?

Yes. The proxy escalation ladder — direct, then Apify datacenter, then Apify residential — runs automatically; you never create a proxy account or rotate an IP yourself. Setting proxyConfiguration only changes which Apify proxy groups the escalation steps use once it needs to escalate past the initial direct attempt.

What happens when Threads changes its structure or blocks the scraper?

The scraper is maintained, and your output schema — field names and types — stays the same on your end even when Threads rotates its internal query IDs or Relay provider-flag set. No specific turnaround time is published for a fix.

Scraper NameWhat it extracts
Threads User Posts ScraperA Threads profile's post history, rather than its follower list

💬 Your feedback

Found a bug, or need a field that's in Threads' follower payload but not in the output? Open an issue on the Actor's Issues tab — reports that include the target username (not your session cookie) are the fastest to reproduce and fix.