Threads Scraper & API - Posts, Replies, Profiles & Search
Pricing
from $1.20 / 1,000 post scrapeds
Threads Scraper & API - Posts, Replies, Profiles & Search
Unofficial Threads API: scrape Threads posts, full reply trees, comments, profiles and keyword search results. No login, no Meta token, no weekly search cap. Export Threads data to JSON, CSV or Excel.
Pricing
from $1.20 / 1,000 post scrapeds
Rating
0.0
(0)
Developer
Mayowa Ogedengbe
Maintained by CommunityActor stats
0
Bookmarked
21
Total users
17
Monthly active users
an hour ago
Last modified
Categories
Share
Threads Scraper — Posts, Replies, Profiles & Keyword Search
Scrape Threads (Meta) at scale. Returns posts, complete reply trees, profiles and keyword search results as clean, structured JSON.
No login. No cookies. No account pool. No session tokens to supply.
Sample output (real run, keyword "anthropic")
| Author | Post | Likes | Replies | Reposts |
|---|---|---|---|---|
| @bodylikeseafoam | In case you need another reason to hate AI, OpenAI just scraped... | 11,305 | 182 | 2,049 |
| @novaramedia | An artificial intelligence researcher has quit Anthropic, accusing... | 287 | 17 | 89 |
| @aditijain.ai | Former OpenAI and Anthropic researcher Jacob Coxon, who publicly... | 10 | 1 | 1 |
Every row also carries the post URL, timestamp, language, media, quoted post and the keyword that found it.
Why this one
| This Actor | Official Threads API | Typical Store alternative | |
|---|---|---|---|
| Keyword searches | Unlimited | About 500 per 7 days | Varies |
| Login or Meta token | None | App review + token | Often none |
| Full reply trees with depth | Yes | Limited | Rarely |
| Price per 1,000 posts | $1.80, no start fee | Free, capped | $2.50 to $20, often plus $0.02 per run |
What it costs: 1,000 posts = $1.80. Monitoring 10 brand keywords at 200 posts each = about $3.60 per run.
Why this scraper exists
Meta's official Threads API allows roughly 500 keyword searches per rolling seven days. That is unusable for social listening, brand monitoring or lead generation, and it is why teams end up looking for a scraper at all.
This Actor reads the same public pages a logged-out visitor sees. There is no weekly search quota, nothing to authenticate, and nothing to keep alive.
It also handles the two things other Threads scrapers get wrong:
| | Typical Threads scraper | This Actor |
|---|---|---|
| Reply trees | Flat list, or fails outright | Full tree with conversation depth |
| Quote posts with no added text | Row with empty text, looks broken | Quoted post resolved inline |
| Login required | Often | Never |
| Breaks when Meta rotates its query ids | Yes | No — this path does not use them |
What you can scrape
Keyword search — every public post matching a term, by relevance or recency, each result tagged with the keyword that found it.
Profiles — handle, display name, bio, bio links, follower count, verification and privacy status, profile pictures, plus recent posts.
Posts and reply trees — the post plus its replies, each carrying its depth in the conversation, so you can reconstruct who answered whom.
Input
Provide at least one of searchQueries, profiles or postUrls. They can be combined in one run.
{"searchQueries": ["openai", "claude ai"],"profiles": ["@zuck", "https://www.threads.com/@mosseri"],"postUrls": ["https://www.threads.com/@zuck/post/DdCYWl7GktV"],"searchSort": "both","includeReplies": true,"maxPostsPerQuery": 200,"maxRepliesPerPost": 300,"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
Running with no input. If you start a run without setting anything, the Actor returns a small live sample so you can see the output shape immediately. Set your own keywords, profiles or post URLs for a real run.
Handles are accepted as zuck, @zuck or a full URL. Posts are accepted as a full URL or a bare shortcode.
searchSort accepts default (relevance), recent (reverse chronological) or both. The two orderings return overlapping but different sets, so both gives the widest coverage at twice the request cost.
Output
One record per post, reply or profile. Post records look like this:
{"type": "post","id": "3981852126213720917_63055343223","pk": "3981852126213720917","code": "DdCYWl7GktV","url": "https://www.threads.com/@zuck/post/DdCYWl7GktV","text": "Mostly superintelligence and MMA takes","language": "en","createdAt": "2026-09-08T14:56:24.000Z","takenAtTimestamp": 1788893784,"likeCount": 2715,"replyCount": 1602,"repostCount": 231,"quoteCount": 142,"reshareCount": 293,"isReply": false,"replyToAuthor": null,"rootPostCode": null,"replyDepth": 0,"isQuotePost": false,"quotedPost": null,"mediaType": "text","media": [],"linkPreview": null,"author": {"id": "63055343223","username": "zuck","fullName": "Mark Zuckerberg","isVerified": true,"profilePicUrl": "https://...","profileUrl": "https://www.threads.com/@zuck"},"authorUsername": "zuck","source": "profile","scrapedAt": "2026-09-10T04:31:00.000Z"}
Three details that matter if you are moving this into a database:
-
pkis a string. Threads primary keys exceed 2^53, so any pipeline that reads them as JSON numbers silently corrupts the last digits. This Actor derives them from the string id and never emits them as numbers. -
Missing counters stay
null, never0. You can tell "no likes" apart from "not published by Threads". -
replyDepthis0for the conversation root,1for a direct reply, and deeper for nested ones. -
authorUsernameis the flat copy ofauthor.username. Spreadsheet and table views cannot read nested paths, so use the flat field for CSV exports and the nestedauthorobject in code. -
Filter on
type, notsource. A run can mix posts and profiles in one dataset.typeis"post"or"profile";sourcetells you which surface a post came from (search,profile,postorreplies), and a profile's own posts are taggedsource: "profile"too.
Pricing
Pay per result, not per minute. A run that returns nothing costs nothing.
| Event | What it covers |
|---|---|
| Post scraped | One post from search or a profile, with engagement, media and any quoted post |
| Reply scraped | One reply, with its depth in the conversation |
| Profile scraped | One profile with follower count, bio, links and verification |
Replies are billed separately because deep reply traversal is the expensive path. If you only want search results, you never pay for it.
Limits, stated plainly
Depth per request. Threads embeds roughly the first page of each surface in the page it serves: about 25 search results per keyword and ordering, and about 25 to 30 replies per post. Running both search orderings widens keyword coverage. Deeper pagination is on the roadmap and is the one thing this version does not do.
Proxies. Threads rate-limits single IP addresses quickly. Residential proxies are strongly recommended for anything beyond a handful of requests. The Actor warns you if it is running without one.
Public data only. Private accounts, direct messages and anything behind a login are out of scope by design.
Legal and compliance
This Actor reads only public Threads pages, the same ones any logged-out visitor can open. It does not log in, does not bypass an access control, and does not touch private accounts.
Threads posts and profiles contain personal data. If you are in the EU or UK, GDPR applies to what you collect and what you do with it, and having a lawful basis is your responsibility as the data controller. Do not resell profile-level personal data as a lead list without the regional carve-outs that apply to you.
FAQ
Do I need a Threads or Instagram account?
No. Nothing in this Actor authenticates, and there is nowhere to enter credentials.
Does it break when Meta ships an update?
Less often than most. Scrapers that call Threads' internal GraphQL API depend on persisted query ids that Meta rotates without notice, and they break each time. This Actor reads the data Threads server-renders into the page and recognises records by their shape rather than by a fixed path, so re-nesting does not break it.
Can I get more than ~25 replies on a post?
Yes. By default (Reply depth = 1) you get the first page of replies embedded in the post — roughly the top 25 — with accurate tree depth. Raise Reply depth to open each reply's own page and pull replies-to-replies: 2 adds the replies under each top-level reply, 3 goes one level deeper, and so on up to 6. The total is still capped by Max replies per post, and a reply is billed the same whatever depth it was found at. Deeper runs make one extra page request per reply that has its own replies, so they take longer and use more proxy traffic.
How do I monitor a keyword continuously?
Schedule the Actor and give it your keywords. Each result carries searchQuery and scrapedAt, so appending runs to one dataset and de-duplicating on id gives you a time series.
Why is text empty on some records?
Those are quote posts where the author added no words of their own. The post they quoted is in quotedPost, with its text and author. The record is complete, not broken.
Does this work with threads.net links?
Yes. Threads moved from threads.net to threads.com, and both forms are accepted, as are bare handles and bare post shortcodes. You do not need to rewrite old links.
How is this different from the official Threads API?
Meta's Threads API needs an app, an access token, and it caps keyword search at roughly 500 queries per rolling seven days. This Actor needs none of that and has no weekly quota, because it reads the same public pages a logged-out visitor sees.
Can I use it from Make, Zapier, n8n or a script?
Yes. Every Apify Actor is callable over the REST API and through Apify's integrations, and results come back as JSON, CSV or Excel.
Is Threads the same as Instagram?
Threads runs on Instagram's infrastructure and shares its account system, but the content is separate. This Actor scrapes Threads only.
Use it as an API
Run it from your own code and get the results back in one call. Replace YOUR_TOKEN with your Apify API token.
curl -X POST "https://api.apify.com/v2/acts/headply~threads-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"searchQueries": ["openai"], "maxPostsPerQuery": 100}'
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run_input = {'searchQueries': ['openai'], 'maxPostsPerQuery': 100}run = client.actor("headply/threads-scraper").call(run_input=run_input)for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
It also works from Make, Zapier, n8n, Google Sheets and as a tool for AI agents through the Apify MCP server.
More data tools from the same developer
- Yelp Scraper & API: every business in a city with phones, websites and all reviews
- TikTok & YouTube Transcript API: video to text, even without captions
- Google Trends Scraper & API: hundreds of keywords on one scale, daily history
- Airbnb & Vrbo Scraper: listings, calendars, occupancy and revenue
- Jumia Scraper & API: prices and sellers across 11 African countries