Threads Scraper: Posts, Replies, Search & Profiles
Pricing
from $4.00 / 1,000 post or reply scrapeds
Threads Scraper: Posts, Replies, Search & Profiles
Scrape Threads without login: posts from profiles, keyword and hashtag search, replies to any post, and profile info. Exact counts (hidden likes stay null, not 0), full media URLs, links, mentions, topic tags. No duplicates, limits respected. Export CSV, Excel, JSON.
Pricing
from $4.00 / 1,000 post or reply scrapeds
Rating
0.0
(0)
Developer
CHEN-SHU-CHEN
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
What is Threads Scraper?
Threads Scraper reads public Threads posts without a login and gives you one row per post. Give it profiles to get their recent posts, keywords or hashtags to get search results, or post URLs to get the replies under them. Turn on Profile info for a row per account with its bio, bio links and exact follower count.
Every row carries what Threads shows a logged-out visitor: the text with its links, mentions and hashtags, the topic tag, every image size and video file (including the best-quality DASH stream), carousel cards with their own size and alt text, likes, replies, reposts, quotes and shares, the author, and for replies the post they answer.
It is built to get the details right that Threads scrapers are usually criticised for:
- No duplicates. A post found twice, by two searches or two inputs, is delivered and charged once.
- Limits are exact. Ask for 20 posts and you get 20, not 25 and a bill for 25.
- Hidden is not zero. When an author hides their like count,
likeCountisnullandlikeAndViewCountsDisabledistrue. Threads itself sends0there; this Actor does not pass that on. - The right post. A post URL is only answered with the post whose code matches the URL, and a profile only with that account's own data.
Because it runs on Apify, you can schedule runs, call it from the API, connect it to Make, Zapier or Google Sheets, and export as CSV, Excel or JSON.
How to scrape Threads
- Fill in any mix of Profiles (
https://www.threads.com/@nasa,@nasaornasa), Search keywords or hashtags (coffee,#coffee) and Post URLs (https://www.threads.com/@zuck/post/Ddt7cL5EfUG). - Set how many posts, results or replies you want for each.
- Optionally narrow it down: a date range, a minimum number of likes, or languages.
- Click Start. A profile with 20 posts takes a few seconds.
- Open the Output tab or export the dataset. Each input line that returned nothing has a row of its own saying why.
What data does it return?
Every post and reply row has type (post or reply), status, and the input it came from (inputType, input, inputIndex).
| Fields | Notes |
|---|---|
id, code, url | code is the short id in the post's URL |
text, textFragments | The text, and the same text split into plain text, links, mentions and stickers as Threads stores it |
links, mentions, hashtags | Links are the real destinations, not Threads' click-tracking redirects |
topicTag | The one topic a Threads post can carry: id, name, community flag |
createdAt, timestamp, isEdited | ISO-8601 in UTC, and epoch seconds |
likeCount, replyCount, repostCount, quoteCount, shareCount | Exact integers. null when Threads did not send the count or the author hid it, never a made-up 0 |
viewCount | Threads shows views only on a post's own page: filled in for the posts you give under Post URLs, and for every post with View counts on |
likeAndViewCountsDisabled | true when the author hid likes and views. Then likeCount and viewCount are null |
mediaType, mediaCount, media | text, image, video or carousel. Each media item has type, width, height, altText, imageUrl (largest), imageCandidates (every size), videoUrl, videoVersions, dash (best video and audio stream, bandwidth, resolution, duration), hasAudio, usertags |
thumbnailUrl, videoUrl, bestVideoUrl | Shortcuts to the first image and video. bestVideoUrl is the highest-bandwidth DASH video track (video only; audio is dash.audioUrl) |
isPinned, replyControl, isSpoiler, isPaidPartnership, isGhostPost | |
location, music, gif, stickers, linkPreview, linkedInlineMedia | Place tag, song (title, artist, ids, cover), GIF reply, inline stickers, link card (destination, title, image), an embedded Instagram post |
aiDetectionMethod, isAiLabeled | Meta's AI-content label |
sensitiveContentOverlay | The warning screen over sensitive media, when there is one |
quotedPost, quotedPostCode, repostedPost | The quoted or reposted post with its own text, counts, media and author |
isReply, replyToAuthor, rootPostAuthor, isLikedByRootAuthor | isLikedByRootAuthor says whether the original poster liked this reply |
rootPostCode, parentPostCode, replyDepth | On replies read from a post URL: the post at the top, the post this one answers, and how deep it sits (1 = direct reply) |
selfThreadCount, selfThread | On profile posts: the author's own follow-up posts in the same thread, each with its text, counts and media |
isRepost, repostedBy | On profile posts: a post the account reposted from someone else |
searchQuery, searchVariant | On search results: which tab it came from (top, recent or tag) |
authorId, authorUsername, authorFullName, authorIsVerified, authorProfilePicUrl, authorIsMetaAiBot, authorIsPrivate, authorTransparencyLabel, authorFollowerCount | authorFollowerCount is filled in on a profile's own posts; Threads does not send it for other authors |
language, languageConfidence, languageSource | See below. threadsDetectedLanguage is Threads' own, rarely set |
isOriginalPost | true on the row for a post you gave under Post URLs |
notes, scrapedAt |
Profile rows (type: "profile", with Profile info on): id, username, url, fullName, biography, biographyFragments, biographyLinks, biographyMentions, biographyHashtags, bioLinks (the links under the bio), followerCount (exact), isVerified, isPrivate, profilePicUrl, hdProfilePicUrl, hdProfilePicVersions, profileTags, transparencyLabel, transparencyProduct, showThreadsBadge, hasOnboardedToThreads.
Input rows (type: "input") appear only for an input that returned nothing or stopped early: status, error, rowsDelivered, postsSeen, duplicatesSkipped, filteredOut (how many posts each filter removed) and notes. The same, for every input, is in RUN_SUMMARY in the key-value store.
status | Meaning |
|---|---|
ok | Read |
no_results | Read, but nothing matched, or every match was already delivered by an earlier input |
partial | Some rows were delivered, then Threads stopped answering, or the run hit its budget or timeout |
not_found | The post was deleted or never public, or Threads answered 404 |
private | A private profile |
login_required | Threads sent the request to its login page (see the FAQ) |
blocked | Threads kept refusing, on several IPs |
parse_error | The page came back but not in the shape this Actor knows; reported rather than guessed |
invalid_input | Not a profile, post URL or search this Actor can read |
not_processed | Never reached, because the run stopped early. Not charged |
How is the language detected?
Threads' own detected_language is set on very few posts, so this Actor detects the language from the text itself. The writing system decides where it can: Hangul is Korean, kana is Japanese, Chinese characters without kana are Chinese, Thai script is Thai, and so on. Text in Latin, Cyrillic or Arabic script goes to langdetect, seeded so the same text always gets the same answer. Links, mentions and hashtags are left out first. Posts with no words to go on (an emoji, a photo, only hashtags) get null, and are skipped when you filter by language. Short posts of a few words can be misread; languageConfidence tells you how sure langdetect was.
How much does it cost?
You pay per row delivered, with no charge for compute or proxies. Rows that failed, were filtered out, or were duplicates are free.
| Event | What it is | Price | Per 1,000 |
|---|---|---|---|
post-scraped | One post or reply row | $0.004 | $4 |
profile-scraped | One profile row (only with Profile info on) | $0.004 | $4 |
view-count-fetched | A view count read from a post's own page (only with View counts on, and only when a count was found) | $0.001 | $1 |
The view count costs extra because Threads only shows it on each post's own page, a separate request of about 1 MB per post. Posts given under Post URLs get their view count for free, since that page is read anyway.
Can I try it for free?
Apify's free plan includes $5 of usage a month, which covers about 1,250 posts.
How do I keep a run from costing more than I expect?
Set a maximum charge for the run when you start it. Each row is written and charged in one step by Apify's SDK, which writes only rows the remaining budget covers, so you are never charged for a row that did not reach your dataset, and no row is written past your limit. When the budget is used up the run stops, and the inputs it did not reach come back not_processed. A view count is only read when the budget covers both the post and its count, and only charged once its post is in the dataset. If writing or charging a row fails, the run stops rather than retry, because a retry could charge twice.
The run also stops in time for its timeout: requests are cut short before the run's time runs out, and whatever was not read comes back not_processed.
What happens if Apify restarts a run?
Apify sometimes moves a running Actor to another server, which restarts it. Progress is saved every 25 rows, after each input, and when Apify announces the move. A restart skips the inputs already finished, reads the dataset for the rows written since the last save, and does not write or charge those again; the input that was in progress carries on, counting the rows it already delivered toward its limit. If the run had already decided to stop (budget, timeout), the restart keeps to that decision. One case favours you: if the restart lands between a post and its view-count charge, that view count is never charged.
Input example
{"profiles": ["https://www.threads.com/@mosseri"],"maxPostsPerProfile": 50,"searchQueries": ["#coffee", "espresso machine"],"searchMode": "recent","maxResultsPerSearch": 50,"postUrls": ["https://www.threads.com/@zuck/post/Ddt7cL5EfUG"],"maxRepliesPerPost": 200,"since": "30 days","minLikes": 10,"languages": ["en"],"includeProfileInfo": true}
Output example
A post from a real run on 2026-10-18, trimmed to the main fields:
{"type": "post","status": "ok","inputType": "profile","input": "https://www.threads.com/@mosseri","code": "Dd_mV-4iVTT","url": "https://www.threads.com/@mosseri/post/Dd_mV-4iVTT","text": "Three DM settings worth knowing about. Let me know if there are other ...","createdAt": "2026-10-02T13:32:20Z","likeCount": 344,"replyCount": 79,"repostCount": 64,"quoteCount": 3,"shareCount": 12,"viewCount": null,"likeAndViewCountsDisabled": false,"mediaType": "carousel","mediaCount": 4,"media": [{"type": "image","width": 1080,"height": 1350,"altText": null,"imageUrl": "https://instagram.frmq5-1.fna.fbcdn.net/v/t51.82787-15/834527974_...","imageCandidates": [{"url": "https://...", "width": 1080, "height": 1350}, {"url": "https://...", "width": 720, "height": 900}]}],"replyControl": "everyone","isPinned": false,"authorUsername": "mosseri","authorIsVerified": true,"authorFollowerCount": 1050331,"language": "en","languageSource": "detected"}
Limits worth knowing
- Search returns about 50 posts per term. Logged out, Threads answers a search with about 20 posts and no next page. With Combine search tabs on (the default), the Actor also asks the other tab (Top or Recent) and the topic tag, and merges them without duplicates: about 50 in tests. To get more, search several related terms; duplicates between them are removed and not charged.
- Replies come in Threads' Top order, as on the post's page. Under each reply Threads shows a short chain of replies to it; those are included (with Include replies to replies), but a long discussion further down a chain is not followed.
- Date range. A profile is read newest first and reading stops once posts are older than Posted on or after, so a narrow recent window is quick. Pinned posts and reposts sit out of date order and do not end the scan. Search and replies are not in date order, so the range is a filter there.
- Follower counts of authors other than the profile you asked for are not in the data Threads sends with posts.
- No logged-in data. Private accounts, and anything Threads only shows to logged-in users, cannot be read.
FAQ
Is it legal to scrape Threads?
This Actor reads only what any logged-out visitor can see, and uses no account. Personal data is still personal data: if you collect it, the rules where you work (for example the GDPR) apply to what you do with it. This is not legal advice.
Why did a profile come back login_required?
Threads sends a handle that does not exist, an account that only shows itself to logged-in users, and a visitor it is rate-limiting, to the same login page. So the row says login_required rather than guessing not_found. Check the spelling first. The Actor already retries once from another IP; if many correctly spelled accounts come back this way, Threads is limiting logged-out access for now: run again later.
Why does a run report fewer posts than I asked for?
The account has fewer posts in the range, the filters removed some (see filteredOut on the input row and in RUN_SUMMARY), or a search ran out of results. Duplicates are removed before counting, so 20 means 20 different posts.
What happens when Threads changes its site?
Threads loads more posts through internal query IDs that change every few weeks. The Actor carries the current ones, falls back to the query each page itself names, and if both fail, looks the current IDs up in Threads' own scripts, once per run. If a page still cannot be read, that input is reported as parse_error or partial with the rows already found, rather than failing the run.
Why is memory limited to 1 GB?
The Actor reads pages over plain HTTP, with no browser, so 512 MB is plenty. More memory would not make it faster.
Something broke or a number looks wrong
Open an issue on the Issues tab with the input and the run link.
Other Actors for social media reporting
| Actor | Use it when |
|---|---|
| Instagram, Facebook, Threads & YouTube Post Metrics | You have post URLs from a campaign and need likes, comments, shares and views for each, across platforms |
| Instagram, Facebook & Threads Post Metrics Tracker | You want the same posts re-checked on a schedule, with the change since the last run |
| Instagram & Threads Influencer Audit | You want engagement rate, median likes and posting frequency per account rather than every post |