Threads Search Scraper: Posts by Keyword, Mentions & Monitoring avatar

Threads Search Scraper: Posts by Keyword, Mentions & Monitoring

Pricing

from $0.09 / 1,000 posts

Go to Apify Store
Threads Search Scraper: Posts by Keyword, Mentions & Monitoring

Threads Search Scraper: Posts by Keyword, Mentions & Monitoring

Search Threads by keywords, phrases and hashtags without login: hundreds of recent posts per keyword, only posts that contain your keyword, views, author followers and bio contacts, monitoring of new mentions. Export JSON, CSV or Excel.

Pricing

from $0.09 / 1,000 posts

Rating

0.0

(0)

Developer

Nice Dev

Nice Dev

Maintained by Community

Actor stats

0

Bookmarked

15

Total users

10

Monthly active users

10 hours ago

Last modified

Share

🔎 What is Threads Search Scraper?

Threads Search Scraper finds the posts that mention your keywords on Threads, Meta's text network: brand names, products, topics, #hashtags, phrases. For each post you get the text, date, likes, replies, reposts, quotes, views, media and links, the author (with Author profiles: follower count and bio), and where your keyword was found.

Type a few keywords (nike, #ai, "air max"), click Start, and download the results in JSON, CSV or Excel. No login, nothing to set up. Schedule it with Only new posts to monitor mentions: each run returns only the posts you have not received yet.

One item per post, 113 fields:

CategoryWhat you get
🎯 Keyword matchwhich of your keywords the post contains and where (text, quoted post, link, image description, topic), the search that found it — nike in text, found by nike dunk
📝 Posttext, link, date to the second, edited or not — Nike SB Dunk restock today
📊 Engagementlikes, replies, reposts, quotes, shares and views, plus a ready-made engagement rate (interactions per view, or per follower when a post has no views) — 2,234 likes, 44 replies, 9,045 views
🖼️ Mediaevery photo and video of the post (carousels included, with the length of each video), the sound file of a voice note, alt text, GIF, stickers, music and podcast shared
🔗 Links and mentionslinks of the text and of the link card (real target, no redirect), mentioned accounts, accounts tagged on the photos, hashtags, topic and its ID
💬 Conversationswho the post answers and that post's text, quoted post, reposts, polls with their votes
👤 Authorusername, name, verified badge, picture, profile link, follower count and bio; on request the e-mails and phone numbers written in the bio, and those found on the website the author cites in the bio
📁 Extras (optional)a summary of each keyword (posts per day, average and median likes and views, top hashtags, top authors, top posts) your own copy of the photos and videos of the posts, and the contacts found on the websites of the authors — nike: 281 posts, median 3 likes · media-3905-1.jpg · hello@acme-shop.fr
🤖 AI (optional)an AI sentiment label (positive, neutral or negative, with a score) and your own AI labels (the ones you wrote that apply to the post, with a score) — negative, 0.91 · pricing, 0.82

Every field, with an example, is listed in the Output section below.

✅ Why use Threads Search Scraper?

  • 💸 Cheap: $0.10 per 1,000 results, down to $0.088 on paid Apify plans — proxy and platform usage included.
  • 🎯 Only posts that really mention your keyword: Threads pads its public search results with popular posts that have nothing to do with it (up to 3 out of 4 for a common word). They are dropped — and never charged — and every row says where the keyword was found.
  • 📈 Hundreds of posts per popular keyword: after Threads' Top, Recent and topic views, Deep search also searches the phrases people write around your keyword (nike dunk, nike stock, sepatu nike) and the site in other languages — on the Apify platform, nike gave 290 posts in under 6 minutes with the default options (views and authors on), 481 in under 4 minutes with both off, where one search page gives 20-35.
  • 🔔 Mention monitoring built in: tick Only new posts and schedule the Actor (every hour, every day): each run returns — and charges — only the posts it never delivered before.
  • 👤 Who is talking: follower count and bio of every author (with Author profiles), views of every post, an engagement rate on every post, and on request the contacts written in the author's bio.
  • 🤖 What they think: tick AI sentiment label for a positive / neutral / negative label on each post, and write AI labels (pricing, complaint: The author reports a problem) to see which of your topics each post is about.
  • 📊 A report per keyword: tick Keyword statistics and get, next to the dataset, one record that sums up each keyword: how many posts and replies, posts per day, average and median likes, replies, reposts, quotes and views, median engagement rate, the top hashtags, authors and posts.
  • 📁 Photos and videos that do not expire: the media links Threads gives are signed and stop working. Tick Download photos and videos and each file is kept in your run's key-value store, with a link on the row.
  • 🔁 Same input as other Threads search Actors: keywords, maxItemsPerKeyword, sortByRecent work as they are.
  • 🧩 Search inside accounts: every post of chosen accounts (their whole history) that contains your keywords.
  • 🔌 API, scheduling, integrations (Make, Zapier, n8n, Google Sheets…) and JSON / CSV / Excel export via the Apify platform.

🚀 How to scrape Threads search results

  1. Create a free Apify account.
  2. Open Threads Search Scraper and type one or more Keywords (e.g. nike, #ai, "air max").
  3. Set Max posts per keyword (50 by default, 0 = as many as Threads shows) and click Start.
  4. Download the dataset in JSON, CSV, Excel or via API.
  5. To follow a brand or a topic, tick Only new posts and schedule the Actor.

💰 How much does it cost to scrape Threads search results?

This Actor uses pay per event pricing: $0.10 per 1,000 results (posts) without an Apify subscription — plus $0.01 per run start (one per GB of memory: one at the default 512 MB). Paid Apify plans pay less: $0.09 (Bronze), $0.089 (Silver) and $0.088 (Gold) per 1,000 results. Author profiles (off by default: follower count and bio of each distinct author) adds $0.29 per 1,000 authors looked up ($0.28, $0.27 and $0.26 on Bronze, Silver and Gold). The other extras, all off by default, each have their own price: a price per author whose bio gives an e-mail or a phone number (Author contacts, off by default), a price per post given an AI sentiment label (post-sentiment, off by default; a post without text costs nothing), a price per post and per label judged with AI labels (ai-label, off by default; each label you write is charged once for each post it is judged on, whether it applies or not), a price per keyword summarised (Keyword statistics, keyword-stats, off by default; a keyword needs at least 5 posts in the run, at most 50 keywords are given), a price per media file kept (Download photos and videos, media-file, off by default; a file that could not be kept costs nothing), a price per author whose website gives an e-mail or a phone number (Contacts from the author's website, website-contacts, off by default; a website that gives neither costs nothing). The filters Threads does not apply itself (postedAfter / postedBefore, minLikes, minReplies, minReposts, mediaOnly, mediaTypes, excludeReplies, verifiedOnly, excludeAuthors, excludeKeywords) are checked by the Actor on every post it reads, kept or not: each post checked is charged a filter check (filter-check): $0.14 per 1,000 posts checked ($0.13, $0.12 and $0.096 on Bronze, Silver and Gold), once per run however many views or searches show it again, and with Only new posts once per post and per filter setting (see Monitoring below). The posts Threads adds without your keyword are never charged. The two AI options need 2 GB of memory (Run options → Memory): with less, they are skipped, the log says so and nothing is charged. The engagement rate is free. See the Pricing tab for the amounts of the other extras. Example, without a subscription: keyword searches that save 5,000 posts ≈ $0.51; a daily mention monitor of 300 new posts ≈ $0.04. Platform usage (compute, proxy) is included in the price.

⚙️ Input

{
"keywords": ["nike", "#ai", "\"air max\""],
"maxItemsPerKeyword": 100
}

Monitor a brand every hour: only the posts not delivered before, the last day only, no replies:

{
"keywords": ["apify", "web scraping"],
"maxItemsPerKeyword": 200,
"postedAfter": "24 hours",
"excludeReplies": true,
"onlyNew": true,
"stateKey": "apify-mentions"
}

A keyword in the whole history of a few accounts, with the contacts of their bio:

{
"keywords": ["mars"],
"fromUsers": ["nasa", "spacex"],
"includeAuthorProfiles": true,
"includeAuthorContacts": true
}
FieldNotes
keywordsWords, phrases or hashtags as typed in the Threads search box: nike, artificial intelligence, #ai; "air max" in quotes = the exact phrase; @account = that account's posts (its whole history).
maxItemsPerKeywordPosts per keyword (0 = as many as Threads shows). A rare keyword can give a few dozen.
sortByRecentThreads' Recent view first, each page taken newest first (on by default); off = Threads' Top ranking first.
deepSearchAlso search the phrases found around the keyword and the site in other languages (on by default); off = the three views of the search only (about 15-35 posts per keyword).
includeViewsRead each post a keyword search finds on its own page for its views (on by default); off = faster, no views. The posts of accounts and replies have no views.
fromUsersAccounts (nasa, @nasa, profile URL) whose whole history is searched for the keywords (all their posts without keywords).
startUrlsThreads search URLs (https://www.threads.com/search?q=nike), profile or post URLs, or a text file of URLs (one per line).
maxItemsStop after this many results for the whole run (0 = unlimited).
requireKeywordMatchOnly the posts that contain a keyword (on by default); off = also the loosely related posts Threads adds (with no matched keyword).
postedAfter, postedBeforePublication date range: 2026-09-01 (a UTC day), or a period before now (24 hours, 7 days, 2 weeks).
minLikes, minReplies, minReposts, mediaOnly, excludeRepliesOnly the posts with at least that many likes / replies / reposts, with a photo or a video, or that are not replies.
mediaTypesOnly the posts of these kinds: text (a link card, a poll or a GIF can come with it), image, carousel, video, audio (a voice note). Empty (the default) = every kind.
verifiedOnlyOnly the posts whose author has the verified badge (off by default).
excludeAuthorsDrop the posts of these accounts (nasa, @nasa or a profile URL).
excludeKeywordsDrop the posts whose text, image descriptions or link title contain one of these words (case and accents ignored; also inside a longer word: art drops party).
includeAuthorProfiles, includeAuthorContactsFollower count and bio of each author (off by default; needed for the contacts); e-mails and phone numbers written in that bio (off by default).
includeSentimentAn AI sentiment label (positive / neutral / negative) and its score on each post and reply, in two extra fields (off by default). Charged once per row labelled; nothing for a post without text. Requires 2 GB of memory (Run options → Memory); with less the option is skipped and nothing is charged.
aiLabelsAI labels: your own labels, one per entry — a name (pricing) or a name and a sentence that is true when the label applies (competitor: The author compares tools); up to 20. Each post and reply gets the labels that apply, with a score from 0 to 1, in aiLabelMatches. Empty (the default) = off. Charged per row and per label judged, whether it applies or not; nothing for a post without text. Requires 2 GB of memory (Run options → Memory); with less the option is skipped and nothing is charged.
includeKeywordStatsA summary of each keyword in the KEYWORD_STATS record of the key-value store, never in the dataset (off by default). Charged once per keyword given; a keyword needs at least 5 posts in the run, at most 50 keywords. With onlyNew, only the posts delivered in this run are counted.
downloadMedia, maxMediaFileMbKeep the photos, videos and voice notes of the posts in the key-value store and give their links in two extra columns of the row (off by default). Charged once per file kept; a file over maxMediaFileMb (50 MB by default, 1 to 100; at most 50 below 1 GB), gone or out of time is not kept and not charged.
includeWebsiteContactsOpen the website each author cites in its bio and add the e-mails, phone numbers and social links found there (off by default; needs includeAuthorProfiles, without it nothing happens). Charged once per author for whom at least one e-mail or phone number is found; a website that cannot be opened or gives none costs nothing.
includeProfileOne profile row per account of @account keywords and fromUsers (off by default, no extra request).
repliesForAllPosts, maxReplies, repliesSortAlso the replies under every post found: how many per post, top or recent first.
onlyNew, stateKey, resetStateMonitoring: only the posts never delivered under this memory key; resetState forgets the memory.
AdvancedmaxSearchPagesPerKeyword (bound on the search pages of one keyword, 300 by default), proxyConfiguration (Apify proxy by default, included in the price; the residential proxy is not available), maxConcurrency, maxRequestsPerMinute, maxRequestRetries, debugLog.

📦 Output

A post as the run saved it (empty fields left out, links shortened):

{
"type": "post",
"id": "3994728069789340396",
"url": "https://www.threads.com/@dimas.sdwo/post/DdwIAO2E1Ls",
"source": "search",
"sourceInput": "nike",
"scrapedAt": "2026-09-26T14:42:13.838Z",
"searchQuery": "nike",
"matchedKeywords": [
"nike"
],
"matchedIn": [
"text"
],
"code": "DdwIAO2E1Ls",
"text": "WTS PRELOVED❗️❗️❗️\n1. Nike Dri-fit Stride Runinng Shorts 5” Size L\n2. Adidas Terrex Climacool 5L Size S + 2Flask 500ml Fieldway\nLok Surabaya, minat DM gusyy",
"createdAt": "2026-09-26T13:18:36.000Z",
"createdAtTimestamp": 1790428716,
"isEdited": false,
"likeCount": 4,
"replyCount": 6,
"repostCount": 0,
"quoteCount": 0,
"shareCount": 1,
"viewCount": 401,
"engagementRate": 0.0249,
"engagementBase": "views",
"mediaType": "carousel",
"hasMedia": true,
"images": [
{
"url": "https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323203_17972180118140782_8033678563312053090_n.jpg",
"width": 2788,
"height": 2788,
"altText": null
},
{
"url": "https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323100_17972180127140782_4343163602084703056_n.jpg",
"width": 2455,
"height": 2455,
"altText": null
},
{
"url": "https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323375_17972180145140782_9065125105949654558_n.jpg",
"width": 3024,
"height": 3024,
"altText": null
},
{
"url": "https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323088_17972180175140782_5901268117608142722_n.jpg",
"width": 3024,
"height": 3024,
"altText": null
},
{
"url": "https://instagram.fnap7-2.fna.fbcdn.net/v/t51.82787-15/825323395_17972180184140782_5360971089617000564_n.jpg",
"width": 3024,
"height": 3024,
"altText": null
}
],
"videos": [],
"mediaUrls": [
"https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323203_17972180118140782_8033678563312053090_n.jpg",
"https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323100_17972180127140782_4343163602084703056_n.jpg",
"https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323375_17972180145140782_9065125105949654558_n.jpg",
"https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-15/825323088_17972180175140782_5901268117608142722_n.jpg",
"https://instagram.fnap7-2.fna.fbcdn.net/v/t51.82787-15/825323395_17972180184140782_5360971089617000564_n.jpg"
],
"mentions": [],
"userTags": [],
"hashtags": [],
"links": [],
"topicTag": "Running Threads",
"isReply": false,
"isQuotePost": false,
"isRepost": false,
"mediaCount": 5,
"isGif": false,
"stickerUrls": [],
"pollOptions": [],
"likeCountsHidden": false,
"replyControl": "everyone",
"authorId": "64141212781",
"authorUsername": "dimas.sdwo",
"authorFullName": "Dimas sadewo",
"authorIsVerified": false,
"authorProfilePicUrl": "https://instagram.fnap7-1.fna.fbcdn.net/v/t51.82787-19/731113161_17960488296140782_378451424120892358_n.jpg",
"authorUrl": "https://www.threads.com/@dimas.sdwo",
"authorFollowerCount": 60,
"authorEmails": [],
"authorPhones": [],
"authorWebsiteEmails": [],
"authorWebsitePhones": [],
"authorSocialLinks": [],
"bioLinks": [],
"emails": [],
"phones": [],
"profileTags": []
}

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

Keyword statistics

With Keyword statistics, the run also writes one record, KEYWORD_STATS, to its key-value store (a link is in the run's log). It is not a row of the dataset. Shortened example, from 29 posts:

{
"generatedAt": "2026-10-10T12:00:00.000Z",
"onlyNew": false,
"rowsRead": 29,
"minRowsPerKeyword": 5,
"keywordsFound": 1,
"keywordsDelivered": 1,
"keywords": [
{
"keyword": "nike",
"posts": 16,
"replies": 13,
"firstPostAt": "2026-09-23T09:42:16.000Z",
"lastPostAt": "2026-09-23T22:58:13.000Z",
"periodDays": 0.55,
"postsPerDay": 29,
"perPost": {
"likes": { "mean": 61.34, "median": 2 },
"replies": { "mean": 11.66, "median": 2 },
"reposts": { "mean": 2.48, "median": 0 },
"quotes": { "mean": 0.28, "median": 0 },
"views": { "mean": null, "median": null }
},
"engagementRateMedian": null,
"mediaShare": 0.069,
"authors": 26,
"verifiedAuthorsShare": 0.0769,
"rowsWithLanguage": 2,
"languages": [{ "language": "ja", "share": 0.5, "rows": 1 }, { "language": "zh_tw", "share": 0.5, "rows": 1 }],
"topHashtags": [],
"topAuthors": [{ "username": "barrettpall", "rows": 2, "likes": 1285 }],
"topPosts": [{ "id": "3992702351627170477", "url": "https://www.threads.com/@barrettpall/post/Ddo7aJymrKt", "likes": 806 }],
"sentiment": null
}
],
"notDelivered": []
}
  • A post counts under every keyword it contains, so the posts of your keywords can add up to more than the dataset. A post found without a keyword match (Only posts that contain a keyword off) counts under the keyword it was searched with. Posts of accounts (@account, fromUsers without a keyword) and profile rows belong to no keyword.
  • Averages and medians cover posts and replies together; a count Threads hides is left out, never counted as 0. postsPerDay is the number of rows divided by the days between the first and the last post, a period under one day counting as one day. languages only lists the posts where Threads gives a language. sentiment is filled when AI sentiment label is on: the share of positive, neutral and negative posts among those labelled.
  • A keyword needs at least 5 posts (replies included) in the run; at most 50 keywords are given, the biggest first, and the keywords left out are named in notDelivered. With Only new posts, only the posts delivered in this run are counted (onlyNew: true in the record).

Media files

With Download photos and videos, every photo, video and voice note of the posts the run delivers is kept in the run's key-value store as media-<post id>-<n>.<extension> (media-<post id>-audio.<extension> for a voice note), with its real content type. The row says where, in storedMediaUrls (same order as mediaUrls; null for a file not kept) and storedAudioUrl. The links Threads gives in mediaUrls and audioUrl are signed by Meta and expire: your copy stays. A GIF (gifUrl), the author's picture and the picture of a link card are not copied.

A file is kept whole or not at all, and charged only when it is kept. Not kept, and not charged: a file larger than maxMediaFileMb, a file Threads no longer serves, a download that fails or runs out of time, and any file beyond what the run's maximum cost pays for. The log says how many files were kept and why the others were not.

Contacts from the author's website

With Contacts from the author's website (and Author profiles, where the links come from), the Actor opens the website each author cites in its bio: its home page and up to two pages of the same site that the home page links as contact, about or legal notice (a link-in-bio page such as Linktree is one page). The row gets authorWebsite (the site), authorWebsiteEmails and authorWebsitePhones (+ and digits for an international number), and authorSocialLinks (Instagram, Facebook, LinkedIn, X, YouTube, TikTok, WhatsApp and Telegram profiles, from the bio and from the website). Each website is read once per run: every post of the author carries the same values.

An author is charged once per run, and only when at least one e-mail address or phone number is found on its website; the social links are free. Links to Instagram, Facebook, YouTube, TikTok, X, LinkedIn, WhatsApp, Telegram and Threads are never opened, and the Actor reads only the website the author itself cites. A website that cannot be opened, is protected or gives nothing costs nothing, and the log counts them.

All 113 fields

FieldsWhat you get
type, id, url, source, sourceInput, scrapedAtpost or profile, Threads id, public link, what produced the row (search, hashtag, profile-posts, profile, post, replies), the keyword / account / URL you gave, ISO timestamp
searchQuery, matchedKeywords, matchedInKeyword match: the search sent to Threads (nike dunk), your keywords found in the post, where (text, quotedPost, link, imageAlt, topic)
code, text, createdAt, createdAtTimestamp, isEdited, languagePost: code of its URL, full text, publication date (what the date filters read), edited, language when Threads gives it
sentiment, sentimentScore, aiLabelMatchesAI (options): positive, neutral or negative for the text of the post or reply, and the confidence in it from 0 to 1 (AI sentiment label); the labels you wrote that apply to the text, each as { "label", "score" }, [] when none applies (AI labels). null when the option is off or skipped, or when the row has no text
likeCount, replyCount, repostCount, quoteCount, shareCount, viewCount, likeCountsHiddenEngagement; views read on the post's own page (includeViews: posts found by a keyword search, and post URLs), null for the posts of accounts, replies, and a post too new for Threads to show them; likeCountsHidden = the author hides likes and views: likeCount and viewCount are then null, never a false 0
engagementRate, engagementBaseEngagement rate (computed for you, free): likes + replies + reposts + quotes divided by the views (views), or by the author's follower count when the post has no views (followers; needs Author profiles), 4 decimals — 0.0249. A count Threads does not give counts 0, unless it gives none of the four. null when the post has neither views nor followers
mediaType, hasMedia, hasAudio, audioUrl, mediaCount, images, videos, videoDuration, mediaUrls, accessibilityCaptionMedia: text, image, video, carousel or audio (a voice note: its sound file is audioUrl); every photo (url, width, height, altText) and video (url, width, height, thumbnailUrl, durationSeconds); videoDuration = the length in seconds of the post's video (the first of a carousel)
storedMediaUrls, storedAudioUrlYour copy of the media (Download photos and videos): where each file of mediaUrls is kept in the run's key-value store, in the same order, null for a file not kept; where the voice note of audioUrl is kept. [] and null when the option is off
isGif, gifUrl, stickerUrls, musicTitle, musicArtist, musicSongId, podcastName, podcastEpisodeName, podcastPlatform, podcastUrlGIF, stickers, song attached, podcast episode shared
mentions, userTags, hashtags, links, topicTag, topicId, linkUrl, linkTitle, linkDisplayUrl, linkImageUrlLinks and mentions: usernames, accounts tagged on the photos and videos (rare), hashtags, links of the text, topic and its ID, link card — real targets, no redirect
pollOptions, pollTotalVotes, pollIsClosed, pollExpiresAtPolls: {text, votes} per option
isReply, replyToUsername, replyToText, replyToPostId, replyToUrl, replyDepth, rootPostUsername, isLikedByAuthor, relatedToConversations: the post answered and its text, depth under a post whose replies are read, starter of the thread, the post URL a reply belongs to
isQuotePost, quotedPostId, quotedPostUrl, quotedPostText, quotedPostUsername, isRepost, repostedByUsernameQuoted post; reposts (the original post, and who reposted it)
isPinned, replyControl, isPaidPartnership, isSpoiler, isAiGenerated, isGhostPost, locationId, locationNamePinned on the profile, who can reply, paid partnership, spoiler, AI label, 24-hour post, place tagged (locationId and locationName only: no address or coordinates; Threads gives a place to about 3 % of the posts of its search results)
authorId, authorUsername, authorFullName, authorIsVerified, authorProfilePicUrl, authorUrl, authorFollowerCount, authorBio, authorEmails, authorPhonesAuthor; followers and bio with Author profiles, e-mails and phone numbers of the bio with Author contacts
authorWebsite, authorWebsiteEmails, authorWebsitePhones, authorSocialLinksAuthor's website (Contacts from the author's website): the website cited in the bio, the e-mails and phone numbers found on it, the social profiles of the bio and of the website. null and [] when the option is off
username, fullName, bio, bioLinks, emails, phones, followerCount, isVerified, isPrivate, profilePicUrl, profileTags, transparencyLabelProfile rows (includeProfile): name, bio, its links, e-mails and phone numbers written in it, followers, badges, topics

💡 Tips

How to get more results

Keep Deep search on and raise maxItemsPerKeyword (or set it to 0). A popular keyword (a brand, a celebrity) gives hundreds of posts per run; a rare one gives what Threads shows publicly — a few dozen recent posts. Add related keywords and hashtags, and schedule the Actor with Only new posts: Threads' public search turns quickly, each run brings new posts.

How to reduce costs

The price is per post saved, so the levers are maxItemsPerKeyword, maxItems, the filters and onlyNew for recurring runs (you never pay twice for the same post). Author profiles is charged per distinct author: leave it off (the default) when you do not need follower counts. The AI options are charged per post (and per label): leave them off, or keep the number of labels low, when you only need the text. Keyword statistics is charged per keyword and Download photos and videos per file kept: leave them off when the dataset is enough. The posts Threads adds without your keyword are never charged.

Several keywords in one run

Put them all in keywords: each one is searched on its own, with its own maxItemsPerKeyword cap. A post found by several keywords is saved — and charged — once, with all of them in matchedKeywords.

Monitoring: only the new posts

Tick Only new posts (onlyNew) and schedule the Actor. The first run returns everything; each later run skips the posts already delivered: they are not saved and not charged, and a search that finds only known posts stops early. The memory lives in a named key-value store of your account (threads-search-scraper-seen, up to 150,000 posts per key) and is only updated with posts that really reached the dataset. Besides them, the same store keeps the posts your filters dropped (never delivered, never counted as delivered): the next runs with the SAME filters skip them without checking or charging them again. A post dropped by postedAfter, mediaOnly, mediaTypes, excludeReplies, verifiedOnly, excludeAuthors or excludeKeywords costs one filter check, once per filter setting. A post dropped for its likes, replies or reposts (minLikes, minReplies, minReposts) or by postedBefore is checked, and charged, again at each run: it may reach the minimum or the date later, and you would lose it. Change a filter, a keyword, an account or a URL and the dropped posts are forgotten (checked, and charged, once more under the new filters); changing a cap (maxItems, maxItemsPerKeyword, maxSearchPagesPerKeyword) or the options View counts, Author profiles, Author contacts and Profile of each searched account keeps them. An account of fromUsers (or an @account keyword) stops once it meets 20 posts in a row you already have (pinned posts are not counted). Give each schedule its own stateKey, and tick resetState once to start over.

Filter by author and by media

verifiedOnly, excludeAuthors and mediaTypes read what Threads already shows with each post, and cost no extra request. In our tests on nike (54 posts that contain the word), verifiedOnly keeps 1, mediaTypes: ["video"] keeps 4 and mediaTypes: ["text"] keeps 35. Every post the filters check is charged a filter check, kept or not.

Filter by publication date

postedAfter and postedBefore take a date (2026-09-01, the whole day is included, UTC) or a period before now (24 hours, 7 days, 2 weeks), counted from the start of the run; the log shows it as Date range (UTC). The filter reads createdAt. Threads' public search mostly shows posts from the last day or two: a date range further back gives few posts from a search — use fromUsers to search accounts' whole history.

🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the Apify MCP server, billed to their Apify account like any run — for questions such as "what are people saying about X on Threads". It returns one item per Threads post that mentions the keywords. Actor id: nice_dev/threads-search-scraper; MCP server with this Actor only: https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/threads-search-scraper.

Smallest input, for a cheap first call:

{
"keywords": ["apify"],
"maxItemsPerKeyword": 10,
"includeViews": false,
"includeAuthorProfiles": false
}

Key output fields: text, createdAt, url, authorUsername, likeCount, replyCount, engagementRate, matchedKeywords and authorFollowerCount.

Cost: per post saved, plus a small run start fee and, when on, per author looked up and per AI label (includeSentiment, aiLabels, both off by default); see the pricing section above. Cap each call with maxItems and, through the API, with the run option maxTotalChargeUsd.

❓ FAQ

The Actor only reads what Threads shows publicly to any visitor without an account. It logs in to nothing and uses no account or cookie of yours. With Contacts from the author's website it also opens the public website an author itself cites in its bio, and nothing else. Results contain personal data (usernames, names, bios, posts, and the e-mails or phone numbers people wrote in their bio or published on their website), which is protected by GDPR: do not store it without a legitimate reason, and delete what an author has deleted. You are responsible for using the data in compliance with Threads' Terms of Use and applicable law. This Actor is not affiliated with Threads or Meta.

Does it need a Threads account or a proxy?

No account. The proxy is included in the price: leave the default setting (the residential proxy is not available). When Threads refuses a request, it is sent again at once on a new proxy session.

Why do other Actors return posts without my keyword?

Threads adds loosely related popular posts to the results it shows visitors (tested on nike: 50 of 185 threads contained the word). This Actor keeps only the posts that contain your keyword — untick Only posts that contain a keyword to get them all.

Is the data safe to open in Excel or to show on a web page?

Posts and bios are their authors' own words, copied as they are. A text can begin with -, +, = or @ (a mention, -20% today): Excel and Google Sheets may read such a cell of a CSV file as a formula. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. Every URL field holds an http(s) URL or null. On a web page, escape every field like any text written by a stranger.

Known limitations

  • Without an account, Threads' search shows recent posts only (about 90 % from the last 24 hours) and no page after the first: the history of a keyword is not reachable. Deep search widens what it shows; a rare keyword still gives a few dozen posts. To search further back, use fromUsers (the whole history of chosen accounts).
  • Threads ignores its own "Recent" order, dates and author filters for visitors without an account: this Actor applies the date, author, verified and media-type filters itself, and sortByRecent orders the posts of each page.
  • Views are shown by Threads a little while after a post is published: a very new post can have viewCount null.
  • Followers and following lists need a Threads account: not available.
  • Replies under a post: Threads shows visitors about 80 % of the replies it counts.
  • onlyNew remembers post ids, not their content: a post whose likes changed is not returned again.
  • Files kept with Download photos and videos weigh on the run's storage and memory: a photo is a fraction of a MB, a video can be tens. With less than 1 GB (the default is 512 MB) the files are copied 4 at a time and none over 50 MB is kept; for many videos, or for videos above 50 MB, give the run 1 GB or more (Run options → Memory) and raise maxMediaFileMb.

A run the platform stops without warning (out of memory, run timeout)

  • Resurrect it: it goes on from where it stood at most a minute before the stop. The results already saved are skipped: none is delivered or charged twice, and maxItems still counts them.
  • With onlyNew, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the posts it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the posts of its last 2 seconds once more.

Something doesn't work?

The last line of the log counts the results saved, filtered out, not found on Threads, and the requests that failed after every retry. Those requests are listed, with the reason, in the FAILED_REQUESTS record of the run's key-value store. A run fails when Threads changes its pages: it stops and names what it could not read, instead of ending green with empty columns or no results.

If Threads changes its pages, you are told instead of paying for blank rows: if the first 20 posts read all lack their date, author, verified badge, media type, counts or views (views are checked on posts more than 6 hours old, read on their own page: a newer post often has none yet) — or the first 20 profiles their username or followers —, the run saves nothing more, stops and fails, and its last message names the missing field. A smaller run (5 to 19 posts) is checked the same way at its end: its rows are kept, and the run fails with the field's name.

🛟 Support

Open an issue in the Issues tab with a link to your run: the run log and the FAILED_REQUESTS record of the key-value store show exactly which URLs failed and why.