X (Twitter) Tweet Search Scraper — Keyword, Hashtag & Account avatar

X (Twitter) Tweet Search Scraper — Keyword, Hashtag & Account

Pricing

from $1.50 / 1,000 per tweet returneds

Go to Apify Store
X (Twitter) Tweet Search Scraper — Keyword, Hashtag & Account

X (Twitter) Tweet Search Scraper — Keyword, Hashtag & Account

Search X (Twitter) for tweets by keyword, phrase, hashtag, from:account or date window — or pull an account's latest tweets. Rows carry text, author, created date, likes, replies, retweets, media, links and quoted tweet. No login, no cookies, no bought feed.

Pricing

from $1.50 / 1,000 per tweet returneds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

2

Monthly active users

6 days ago

Last modified

Share

Search X (Twitter) for tweets by keyword, exact phrase, #hashtag, from:account or date window, or pull an account's latest tweets — and get one clean row per tweet: id, url, text, createdAt, lang, authorHandle, authorName, authorId, authorVerified, likes, replies, hashtags, mentions, urls, media (direct image and MP4 URLs), reply / quote / retweet flags and targets, the Google rank and snippet that found it, plus retweet and quote counts and the author's followers, bio and website on account-mode rows. No login. No cookies. No account pool. No bought feed. No CAPTCHA solving.

Scope, measured 2026-08-22: search mode reads Google's index of x.com through Apify's Google SERP proxy and hydrates every hit from X's own public embed API — 24/24 result pages usable, 138 distinct tweets across 8 queries, 15/15 hydrations on every proxy rung. Account mode reads X's public embedded timeline — 16/16 accounts, 644 tweets, 17 seconds through the default datacenter proxy. Those are counts read off live runs, not quoted from a marketing page.

{
"searchTerms": ["bitcoin"],
"maxTweets": 100,
"maxPagesPerTerm": 10
}

Click Try for free and press Start — that block is the input the Actor ships with. A run on exactly those defaults returned 71 tweets in 75 seconds (10 Google pages, 71 links, 71 hydrated, 0 failures, 0 duplicates), with text 100%, likes 100%, replies 100%, and media on 62.9% of rows in the fill measurement below.


Read this before you buy rows — what "search" means here

X shut logged-out search in 2023. x.com/search is a JavaScript shell, the guest-token GraphQL search operation answers 404, the official /2/tweets/search endpoint is 401 without a paid bearer, and X's logged-out web client ships zero GraphQL operations (all measured on 2026-08-22 on direct, Apify datacenter and residential). That leaves the other tweet-search Actors on the Store two choices: resell a licensed feed (the 256 MB "no proxy required" ones), or run a pool of logged-in accounts. This Actor does neither.

  1. Search mode returns the tweets Google has indexed, not the live firehose. Google indexes the popular and recent tweets from active accounts — on the shipped bitcoin run the rows spanned 2017 to today, with a median of ~860 likes (a few big accounts pull the mean above 2,000). If you need every tweet posted in the last ten minutes, this is the wrong tool; if you need the tweets people actually saw, it is the cheap and honest one.
  2. retweets and quotes are null on search-mode rows. X's embed API publishes likes and reply counts, not retweet or quote counts. Account-mode rows carry all four (68.3% of the mixed-run rows below had real retweet counts — exactly the account-mode share).
  3. Account mode is the newest 20 tweets for most accounts, up to 100 for high-volume ones (elonmusk, nytimes, sama and reuters returned 99-100; nasa, github, stripe returned 20-21). That is what X's embedded-timeline page publishes; there is no pagination beyond it.
  4. views does not exist in this dataset. Neither public surface publishes impression counts, so there is no views column rather than an always-null one.
  5. A bare #hashtag is quoted for you. Google drops a bare #ai; the Actor sends "#ai", which measured 9 tweet links on page 1 against 4 for the bare form.

The wedge: an open, logged-out transport with zero upstream cost

Every number in this section was measured through Apify's proxies on 2026-08-22.

  • No feed licence, no account pool. The two Store leaders run at 256 MB with "no proxy required" — that is a bought search feed, resold at $0.25-0.40 per 1,000 tweets with the margin of a reseller and the fragility of one (the biggest of them aborts or times out on 5.7% of its runs — Apify store stats, 2026-08-27). This Actor's two surfaces are the ones X serves to every embedded tweet and timeline on the web, so there is nothing to expire, nothing to ban and nothing to re-license.
  • A real date window. since / until become Google after: / before: — verified live: before:2025-01-01 returned tweets dated Feb 2024 and Sep 2021, after:2026-08-15 returned only that week. recency adds Google's past-day/week/month/year window.
  • A real language filter. language: "es" sends lr=lang_es; measured, the page returned Spanish-language accounts only (Udelalibertad, elEconomistaes, Forbes_Mexico …).
  • X search operators that just work. from:OpenAI gpt, "#bitcoin" etf since:2026-08-01, lang:de, min_faves:1000 and Google's -word are all translated for you (from: becomes site:x.com/handle).
  • Account-mode rows are the richest public tweet record there is: likes, replies, retweets, quotes, conversation id, reply target, quoted tweet, retweet origin, full media with MP4 URLs, and the author's followers, following, tweet count, bio, website and account creation date.
  • Author enrichment as a success-billed event. Turn on enrichAuthors and search-mode rows get the same author block (followers, bio, website, location, account age) — charged once per unique author whose profile was found, never per tweet, never on a miss.

As of 2026-08-22, "twitter search" on the Apify Store is held by feed resellers and account-pool scrapers; none documents a logged-out transport. Judge this page on the measurements below rather than on that claim.


What you get — one row per tweet, one schema for both modes

GroupFieldsExample
Identityid, url, text, createdAt, lang2085434712429052386 · 2026-08-06T18:35:55.000Z · en
AuthorauthorHandle, authorName, authorId, authorVerified, authorProfileImageOpenAI · 4398626122 · true
Author profile (account mode / enriched)authorFollowers, authorFollowing, authorTweetCount, authorBio, authorWebsite, authorLocation, authorCreatedAt, authorEnriched5121285 · https://openai.com · 2015-12-06
Engagementlikes, replies, retweets, quotes21311 · 1384 · 1919 · 1116
StructureisRetweet, isReply, isQuote, inReplyToHandle, inReplyToTweetId, quotedTweetId, quotedTweetUrl, retweetedTweetId, retweetedFromHandle, conversationId
Entitieshashtags[], mentions[], urls[] (expanded, t.co stripped), media[] {type, url, videoUrl, width, height}, mediaCount, possiblySensitivevideo · …/vid/avc1/1672x942/….mp4
Provenancesource (search | account), searchTerm, googleRank, googleSnippet, scrapedAtsearch · bitcoin · null

All dates are ISO-8601 UTC. Counts are integers; null means the surface did not publish the number (see the limits), 0 is a real zero. The dataset ships two saved table views: Tweets (the overview) and Authors (handle, followers, bio, website, location — populated on account-mode rows, and on search-mode rows when enrichAuthors is on).


Field fill — measured on real rows

Search mode — the shipped default (bitcoin, 62 rows, 2026-08-22). Sorted by fill; the sparse fields are the ones to plan around.

FieldFillNotes
id / url / text / createdAt / lang100%
authorHandle / authorName / authorId / authorVerified / authorProfileImage100%
likes / replies100%from X's embed API
googleRank / googleSnippet56-100%Google now hides every result URL behind an opaque /goto?url= redirect, so the Actor reads the page's embedded results array instead: every tweet that was an organic result gets its true SERP position (non-tweet results consume their slot, so ranks read 1, 4, 5, 6, 7, 9, 10 — not 1-7) and Google's own excerpt. Ids that appear only in a video/"posts" carousel carry no title or snippet triple and ship with null rank. Measured 22/22 ranks correct across 4 live queries.
mediaCount / isRetweet / isReply / isQuote100%booleans and counts, never null
possiblySensitive77.4%the embed API omits the flag on some tweets → null
media62.9%39 of 62 tweets carried a photo, GIF or video
hashtags17.7%
urls17.7%external links only — t.co media links are stripped
quotedTweetId / quotedTweetUrl12.9%
mentions8.1%
retweets / quotes0% — not published by the embed APIreal numbers in account mode
authorFollowers / authorFollowing / authorTweetCount / authorBio / authorWebsite / authorCreatedAt0% unless enrichAuthors is on100% on account-mode rows; authorLocation is always empty — X's syndication surface does not publish it
inReplyTo* / retweeted*~1%Google mostly indexes original posts, not replies
conversationId~95%the embed API does not publish conversation_id_str, so it is derived: a root tweet's conversation is itself (conversation_id_str == id_str on 498 of 498 root tweets measured across 7 real timelines), and a reply directly under a root roots at the parent. Deeper thread replies are left null rather than guessed.

Mixed run — 2 search terms + 2 accounts with enrichAuthors: true (60 rows: 41 account, 19 search). authorFollowers, authorFollowing, authorTweetCount, authorBio, authorCreatedAt ~85% (enrichment misses some authors — a live "series a" fintech run resolved 8 of 10) · authorWebsite 96.7% · retweets / quotes 68.3% (= every account-mode row) · media 65.0% · inReplyToHandle 25.0% · retweetedFromHandle 20.0% (with includeRetweets: true) · authorLocation 0% — X's syndication surface never publishes a location, so this field is always null.

The headline that could mislead you: this is a "what people saw" product, not a firehose. Google's index decides which tweets search mode can see; the median tweet on the default run carried ~860 likes because that is what gets indexed. For a complete recent record of one account, use account mode.

Every run prints its own transport counts in the log — SERP pages usable / stub / failed, tweets hydrated / gone / failed, timelines read / failed, authors enriched / missed, and the number of rows your filters removed.


How to run it

1. Keyword, phrase or hashtag search (the usual choice)

{
"searchTerms": ["bitcoin etf", "\"climate change\"", "#nvidia"],
"maxTweets": 300,
"maxPagesPerTerm": 10
}

Each term becomes a site:x.com … Google query; each result page yields 2-10 tweet links (7-10 per page on recent runs), and every link is hydrated from X's embed API. Pages are fetched three at a time; the Actor stops a term when a page brings nothing new.

2. A date window, a language or a recency window

{
"searchTerms": ["openai"],
"since": "2026-08-01",
"until": "2026-08-22",
"language": "en"
}

since / until go to Google as after: / before:; language as lr=lang_xx; recency (day, week, month, year) as Google's time filter when no window is set.

3. Tweets from one account about one thing

{ "searchTerms": ["from:OpenAI gpt", "from:elonmusk tesla since:2026-06-01"] }

from:handle becomes site:x.com/handle, so you get that account's indexed tweets matching the words. Measured: from:OpenAI gpt returned 27 links over 3 pages, 18 delivered under the cap.

4. An account's latest tweets, with full engagement counts

{
"twitterHandles": ["NASA", "https://x.com/OpenAI", "@sama"],
"includeRetweets": false,
"includeReplies": true,
"maxTweets": 300
}

One request per account, newest first, with retweets, quotes, replies and the author profile. Retweets are dropped by default. includeRetweets: true keeps them as rows with isRetweet: true, retweetedFromHandle and the original tweet's text, counts and media. On those rows the author block (authorHandle, authorFollowers, authorBio …) is the account you asked for — the one that did the retweeting, matching the tweet url — and the original poster is in retweetedFromHandle. An unknown handle is reported in the log and skipped; it never fails the run.

5. Author enrichment for search results

{
"searchTerms": ["\"series a\" fintech"],
"enrichAuthors": true,
"maxAuthorsToEnrich": 100,
"maxTweets": 200
}

Each unique author is looked up once (cached within the run) and their rows get followers, bio, website, tweet count and account age (location is not published by this surface). Measured on a live "series a" fintech run: 8 of 10 unique authors resolved, 10 of 12 rows enriched. The author-enriched event bills once per author found, on top of the per-tweet price; misses and authors past the cap are free.

Filters

minLikes · onlyWithMedia · since / until · includeRetweets / includeReplies (account mode). Filters run after the tweet is fetched and before it is billed — a filtered-out tweet costs you nothing.

Scheduling and integrations

Save the input as a Task and attach a Schedule (0 */6 * * * for a six-hourly brand monitor); read the dataset over the REST API or any Apify integration (Zapier, Make, n8n, webhooks, MCP). From the API:

curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~x-tweet-search-scraper/runs?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"searchTerms":["\"#bitcoin\" etf"],"since":"2026-08-01","maxTweets":200}'

Sample row

A real account-mode row from the mixed run, captured 2026-08-22 17:39 UTC.

{
"id": "2085434712429052386",
"url": "https://x.com/OpenAI/status/2085434712429052386",
"text": "We're making better intelligence easier to access in ChatGPT for everyone:\n\n- GPT-5.6 Sol now powers both Instant and deep reasoning for Plus & Pro users, delivering more factual, focused responses.\n\n- Free & Go users get unlimited text chats with GPT-5.6 Luna starting tomorrow. https://t.co/JXhmj5GLTH",
"createdAt": "2026-08-06T18:35:55.000Z",
"lang": "en",
"authorHandle": "OpenAI",
"authorName": "OpenAI",
"authorId": "4398626122",
"authorVerified": true,
"authorProfileImage": "https://pbs.twimg.com/profile_images/1885410181409820672/ztsaR0JW_400x400.jpg",
"authorFollowers": 5121285,
"authorFollowing": 4,
"authorTweetCount": 2079,
"authorBio": "OpenAI's mission is to ensure that artificial general intelligence benefits all of humanity. We're hiring: https://t.co/dJGr6LgzPA",
"authorWebsite": "https://openai.com",
"authorLocation": null,
"authorCreatedAt": "2015-12-06T22:51:08.000Z",
"authorEnriched": false,
"likes": 21311,
"replies": 1384,
"retweets": 1919,
"quotes": 1116,
"isRetweet": false,
"isReply": false,
"isQuote": false,
"inReplyToHandle": null,
"inReplyToTweetId": null,
"quotedTweetId": null,
"quotedTweetUrl": null,
"retweetedTweetId": null,
"retweetedFromHandle": null,
"conversationId": "2085434712429052386",
"hashtags": [],
"mentions": [],
"urls": [],
"media": [
{
"type": "video",
"url": "https://pbs.twimg.com/amplify_video_thumb/2085433949489377280/img/4uce3Ngds5vczB6t.jpg",
"videoUrl": "https://video.twimg.com/amplify_video/2085433949489377280/vid/avc1/1672x942/q_oTUaxOVBAP_2XY.mp4",
"width": 1672,
"height": 942
}
],
"mediaCount": 1,
"possiblySensitive": false,
"source": "account",
"searchTerm": "from:OpenAI",
"googleRank": null,
"googleSnippet": null,
"scrapedAt": "2026-08-22T17:39:28.287Z"
}

Fields people misread:

  • retweets: null on a search-mode row means "not published by X's embed API", not zero. On an account-mode row it is a real count.
  • text keeps X's trailing https://t.co/… media link exactly as X renders it; the actual image or MP4 is in media[]. urls[] holds only external links, already expanded.
  • authorEnriched: true marks a search-mode row whose author block came from the enrichment lookup (and was billed once for that author). Account-mode rows carry the block for free and stay false.
  • googleRank is the tweet's true position on the Google result page that found it (1-10 per page, counted over all organic results — so a page whose slots 2, 3 and 8 are profile pages yields ranks 1, 4, 5, 6, 7, 9, 10). It is null in account mode, and null for the handful of ids Google exposes only inside a video/"posts" carousel, which carries no snippet either. googleSnippet is Google's own excerpt for that result and follows the same rule.
  • conversationId is the thread root. It is derived on search-mode rows (see the fill table) and is null on deep-thread replies, where the root is not in the payload.

Input

Fields in the order the Console shows them.

FieldTypeDefaultWhat it does
🔎 What to search
searchTermsstring list["bitcoin"]Words, "phrases", #hashtags, from:handle, since: / until:, lang:xx, min_faves:N, -word. One search per line.
twitterHandlesstring list[]Accounts (handle or profile URL) for their latest 20-100 tweets with full counts.
🎚️ Filters
since / untilYYYY-MM-DDblankDate window — Google after: / before: in search mode, a filter in account mode.
recencyselectanyPast day / week / month / year (search mode, when no window is set).
languagestringblankTwo-letter code → lr=lang_xx (search mode).
minLikesinteger0Applied after fetch, before billing.
onlyWithMediabooleanfalseKeep only tweets with a photo, GIF or video.
includeRetweetsbooleanfalseAccount mode.
includeRepliesbooleantrueAccount mode.
👤 Author enrichment
enrichAuthorsbooleanfalseSearch mode: look up each unique author once; bills author-enriched per author found.
maxAuthorsToEnrichinteger50Hard cap on enrichment events per run.
💵 Limits & cost
maxTweetsinteger100Your hard cost cap. 100 = $0.15, 1,000 = $1.50.
maxTweetsPerTerminteger100Per-term / per-account ceiling.
maxPagesPerTerminteger10Google pages per term (max 30); 7-10 tweets per page on recent runs.
⚙️ Advanced
proxyConfigurationproxyApify datacenterFor the X requests. Google always goes through Apify's GOOGLE_SERP group.

Pricing

$0.0015 per tweet returned — $1.50 per 1,000. Charged on the tweet-scraped event. Optional $0.003 per author enriched (author-enriched), only with enrichAuthors: true and only when the profile is found. No monthly fee from this Actor.

RunTweetsCost
The shipped default (bitcoin, 10 pages)~70$0.11
Three terms at the default cap100$0.15
Five accounts' full latest timelines~150$0.23
A 1,000-tweet monitor1,000$1.50
200 tweets + 100 authors enriched200 + 100$0.60
  • You are charged for rows delivered. A tweet Google listed but X no longer serves (deleted, protected, suspended) is skipped and never charged; so is anything your filters remove.
  • Duplicates are dropped before billing. A tweet found by two terms, or by a term and an account, is one row and one charge; uniqueness is asserted on every run.
  • Rows are charged as they are pushed (Actor.pushData(items, 'tweet-scraped')), so a run that hits your budget cap delivers whole rows and stops — never a half-billed dataset. The Actor reads the cap at startup and will not fetch tweets it cannot bill.
  • Why not the $0.25-0.40 / 1,000 floor? Those prices are feed resellers' margins on a licensed search API. This Actor pays Google SERP proxy cost (roughly $0.0005 per tweet found) to stay logged-out and licence-free, and prices at the upper-middle of the lane for it.

Honest limits

  • Search mode = Google's index of x.com. Coverage is the popular and recent tweets Google has crawled, not every tweet ever posted. Narrow queries run out after 2-3 pages; broad ones keep going to the 30-page cap. Expect hours-to-days of indexing lag on brand-new tweets.
  • No views / impression counts anywhere — neither public surface publishes them.
  • retweets, quotes, isRetweet, retweetedTweetId and retweetedFromHandle are null-or- false in search mode. X's embed API does not publish them (verified on 78 live payloads, and on 8 alternate syndication endpoints) and a retweet permalink resolves to the original tweet, so search mode can never surface a retweet wrapper. Real values only in account mode.
  • Long-form tweets arrive truncated. About 24% of search-mode rows are long-form posts whose text is X's ~280-character version, cut mid-sentence. The full body is not retrievable from any logged-out surface — X's embed payload carries only an opaque id for it. Account-mode rows are subject to the same X limit.
  • Account mode is X's embedded timeline: the newest 20 tweets for most accounts, up to 100 for high-volume ones, no pagination beyond that. Protected accounts return nothing.
  • No replies-to-a-tweet / conversation threads. That is a different function and belongs in a different Actor.
  • Google pages are billed by Apify's SERP proxy to the developer, not to you — but it does mean maxPagesPerTerm: 30 on a term that runs dry after page 3 costs nothing extra; the Actor stops as soon as a page brings no new tweet.
  • Two rate limits you might meet. Google's SERP proxy occasionally returns a JavaScript stub (the Actor rotates the session and retries, up to 5 times per page — 0 of 34 pages needed it in measurement). X's timeline host 429'd 2 of 16 accounts on residential IPs and 0 of 16 on datacenter — the default is datacenter, with one residential retry if datacenter fails.
  • No login, no cookies, no CAPTCHA service, no account pool. Everything here is the logged-out public surface X serves to embedded tweets and timelines. Nothing behind a login is touched, and the Actor will never ask you for a session cookie.

How it works, and what it cost to make reliable

Two logged-out routes, one schema:

  1. Search: http://www.google.com/search?q=site:x.com+<terms> through Apify's GOOGLE_SERP proxy group — the only tier that returns a rendered Google page, and only over plain HTTP (it is a reverse proxy). Tweet ids are read from the result page by four tiers that union rather than fall through — the organic anchors where Google still exposes a direct URL, the page's embedded results array (the usual path now that Google wraps every link in a /goto?url= redirect; this is what carries googleRank and googleSnippet), stray anchors, and finally a bare /status/ id scan so a carousel-only id is never dropped; each /status/<id> is hydrated from https://cdn.syndication.twimg.com/tweet-result?id=<id>&token=<t> — X's own embed API, the endpoint every embedded tweet on the web loads from.
  2. Account: https://syndication.twitter.com/srv/timeline-profile/screen-name/<handle> — the page behind X's embedded timelines; its __NEXT_DATA__ blob carries 20-100 full tweet objects with every engagement counter and the author record.

Transport ladder, measured 2026-08-22 through Apify:

RouteRungResult
x.com/search?q= HTMLdirect / datacenter / residential200, 277 KB JS shell, 0 tweets on every rung
guest-token GraphQL SearchTimelineall rungs404; the logged-out client bundle (20 KB) contains no GraphQL operations at all
official api.x.com/2/tweets/search/recentall rungs401 — licensed only
Bing / DuckDuckGo site:x.comdirect0 tweet links (Bing RSS ignores site:; DDG serves a challenge to datacenter IPs)
Google site:x.com via GOOGLE_SERPGOOGLE_SERP (http)24/24 pages usable, 138 distinct tweet ids over 8 queries × 3 pages, 2-10 links per page
embed API tweet-resultdirect / datacenter / residential5/5, 5/5, 5/5 — JSON with text, author, likes, replies, media
embedded timeline timeline-profiledatacenter16/16 accounts, 644 tweets, 17.0 s total
embedded timeline timeline-profileRESIDENTIAL + US14/16 (two HTTP 429), 36.9 s
embedded timeline timeline-profiledirect, plain urllib429 × 3 — it is fingerprint-sensitive; a Chrome-class client clears it

So the default is the cheap datacenter rung for X and the GOOGLE_SERP group for Google, and you are never billed for residential IPs the Actor does not need.

Reliability is built in rather than hoped for: a wall-clock budget read from the run's own timeout gates every request (a run that is about to hit its limit pushes what it has, sets a status message and ends SUCCEEDED); every request timeout is clamped to the time left; an unhandled error ends the run cleanly instead of FAILED; a bare {} input runs the documented sample; an empty result ends with an explanation in the status message and bills nothing. Duplicates are removed on tweet id before billing and uniqueness is asserted before the run may succeed.

robots.txt on x.com, syndication.twitter.com and cdn.syndication.twimg.com all carry a blanket User-agent: * / Disallow: /; x.com's file allows Google and Bing to crawl /i/api/, hashtag and cashtag searches and every /status/ page, which is why Google has the index this Actor reads. The Actor reads only what X serves logged-out to every embed on the web, paces itself, and never touches an authenticated path.


Duplicates — measured

Google re-serves some results across pages: over 24 measured pages, 17 of 155 tweet links were repeats of an earlier page of the same query (11.0%), and a tweet about bitcoin can surface under bitcoin and #bitcoin alike. The Actor keeps a run-wide set keyed on tweet id, drops repeats before hydration (so they are never fetched, never billed), and then asserts uniqueness across everything it pushed before the run is allowed to succeed. Both measured runs: 0 duplicates in 62 and 60 rows. Across runs, narrow with since — dedupe is per-run by design.


When a run fails

This Actor ends SUCCEEDED with an explanation on every transient condition and throws only where output would be silently wrong:

  • 0 rows → a status message naming the cause: time budget, Google stub/blocked, no indexed tweets for the query, all accounts unreadable, or everything removed by your filters. Nothing billed.
  • Unknown handle / deleted tweet → logged and skipped, never billed, never fatal.
  • Time budget → pushes what it has, sets "Stopped early to stay inside this run's time limit — N tweets delivered and charged", ends SUCCEEDED.
  • Charge cap → stops at the last whole row it can bill, says so in the status message.
  • Duplicate leak → the uniqueness assertion fails the run (this is the one deliberate throw).

Who buys this

  • Social-listening and brand-monitoring teams — a scheduled searchTerms task with since set to yesterday gives you the indexed conversation about a brand, with likes and replies to rank it.
  • PR and commstwitterHandles of journalists, analysts and competitors: their latest posts with retweet and quote counts, every six hours, no account risk.
  • Lead-gen and GTM"series a" fintech, "hiring" "head of growth" with enrichAuthors: true: who is saying it, how many follow them and what website they link.
  • AI agents — a keyword in, JSON tweets out, pay per tweet, no credentials to hold; the text field is ready for summarisation.
  • Researchers and analysts — language- and date-windowed samples of the public conversation on a topic, with media URLs for multimodal work.

FAQ

Does this need an X account, login or cookies? No. Both surfaces are logged-out and public. The Actor never asks for, stores or uses a session cookie, and there is no account pool behind it.

Is this the full X search? No — see Read this before you buy rows. Search mode is Google's index of x.com, hydrated from X. It is the tweets people saw, not every tweet. Account mode is complete for the newest 20-100 tweets of an account.

Why are retweets and quotes null on some rows? Because X's embed API (search mode) publishes likes and reply counts only — checked on 78 live payloads and on 8 alternate syndication endpoints, none of which carries them. Account-mode rows have all four counts from X's timeline JSON.

Can I get views? No. Neither public surface publishes impressions, so the field does not exist here.

How fresh is search mode? As fresh as Google's index — hours to a few days for active accounts. recency: "day" asks Google for the past 24 hours. For minute-level freshness on specific accounts use account mode.

Do hashtags work? Yes. #bitcoin is sent to Google as "#bitcoin" (9 tweet links on page 1 in measurement, against 4 for the bare form).

Do I need a residential proxy? No. Datacenter measured 16/16 timelines and 5/5 hydrations; residential measured worse on the timeline host (two 429s). The Actor retries a failed timeline once through residential on its own.

Two runs — will I get duplicates? Within a run, never: dedupe is on tweet id and asserted before success. Across runs, use since.

Do I get charged for rows a filter removed, or for deleted tweets? No. Filters run before billing; a tweet X no longer serves is skipped and never charged.

Will a run ever fail on an empty result? No. Zero rows ends SUCCEEDED with the cause in the status message and nothing billed. The only deliberate failure is the uniqueness assertion.


This Actor reads logged-out public pages and public embed endpoints that X serves to every website embedding a tweet or a timeline, plus Google's public index of x.com. It does not log in, does not use cookies or accounts, and collects nothing behind authentication. Tweets and author profiles are public posts but can contain personal data; you are responsible for complying with X's Terms of Service, Google's Terms and applicable privacy law (GDPR, CCPA …) in how you use the data. Note that x.com and its syndication hosts publish a blanket Disallow: / in robots.txt for unnamed crawlers.

X® and Twitter® are trademarks of their owner. This Actor is not affiliated with, endorsed by, or connected to X Corp. or Google LLC.


Feedback

Found a missing field or want a new filter? Open an issue on the Issues tab, and if the Actor earns it, a review on the Reviews tab helps other buyers find it.