GUIDE
Twitter Search API and Advanced Operators (2026 Guide)
Twitter Search API guide for 2026, every advanced search operator (from:, to:, min_faves:, since:, until:) with working code in curl, Python, JavaScript.

Most developers waste their first week on the Twitter Search API chasing operators that quietly do nothing. The reason is rarely a typo. Twitter ships two separate operator vocabularies, X's official docs only describe the smaller one, and the bigger, more useful set is documented mostly by the community. This page is the practical, tested reference for the operators that still work on Twitter/X in 2026, organized so you can copy a query, run it, and trust the result. The operator definitions here are cross-checked against the community-maintained igorbrigadir/twitter-advanced-search repo and live calls.
TL;DR: The web operator vocabulary (
from:,to:,since:,until:,min_faves:,min_retweets:,filter:, exact phrases, boolean logic) lets you pre-filter exactly which tweets you pull before you spend a cent. X's official v2 endpoint honors only a slice of it. The TwitterAPIs Advanced Search endpoint accepts the entire web vocabulary, including the engagement thresholds the official API refuses, at $0.0008 per call (roughly 20 tweets a call).
Want the product, the endpoint spec, and pricing tiers instead? Those live on the Twitter Search API page. What follows is the operator manual: each filter and how to wire it into code.
These operators run in two places. You can type them straight into Twitter's search box, or you can pass them programmatically to the TwitterAPIs Advanced Search endpoint (GET /twitter/tweet/advanced_search) at $0.0008 per call. The official X API only honors a fraction of them; TwitterAPIs forwards the full web set, which is why engagement gates like min_faves: and min_retweets: work here but never on v2.
The split that quietly kills queries
Before any operator table, internalize one thing, because it explains most of the "my filter is being ignored" tickets: Twitter runs two different operator dialects.
- Web search operators are the full vocabulary on this page. They power twitter.com/search, the old TweetDeck, and scraper-style providers such as TwitterAPIs.
- Official v2 operators are a trimmed subset. They lack the heavy hitters,
min_faves:,min_retweets:,within_time:, andfilter:blue_verifiedamong them.
So if you point a query full of engagement gates at X's v2 /2/tweets/search/recent, half of it evaporates with no warning. Send the same string to TwitterAPIs Advanced Search and every operator fires. Pick the lane before you debug a "broken" filter.
The lane confusion is exactly why threads on the engagement gates keep resurfacing in community forums, where people compare what min_faves: returns against what they expected and discover the operator behaves differently depending on which search index they hit.
Twitter Advanced Search inaccurate? "min_faves" doesn't show all the tweets it should. from r/Twitter
Three ways to run a Twitter search in 2026
"Twitter Search API" is a loose label for any programmatic route into Twitter's search index. There are three real choices today, and they differ wildly on cost and operator coverage:
| Route | Endpoint | Price | Operators honored |
|---|---|---|---|
| TwitterAPIs | GET /twitter/tweet/advanced_search | $0.0008 per call (~20 tweets) | Entire web set, min_faves: and min_retweets: included |
| X API v2 | GET /2/tweets/search/recent | $0.005 per post read | Trimmed, no engagement gates; from:, to:, lang, and basics only |
| X API v2 full-archive | GET /2/tweets/search/all | Enterprise tier only | Full set, but the floor runs into the tens of thousands a month |
For the everyday jobs (research, monitoring, dashboards, ETL backfills), the TwitterAPIs endpoint is the cheapest pay-as-you-go production Twitter Search API in 2026 at $0.04 per 1,000 tweets, with no developer-account review and the complete operator set live from your first request. The syntax is identical to what you would type into Twitter's web search, so throughout this guide "Twitter Search API" and the TwitterAPIs advanced search passthrough mean the same thing.
1. Engagement thresholds (the operators v2 will never give you)
Start here, because this is the category developers leave the official API for. Minimum and maximum gates on likes, retweets, and replies let you skip the noise floor before you pay to pull anything. None of these exist on X API v2 at any tier.
| Operator | Effect | Try it |
|---|---|---|
min_faves:N | N likes or more | openai min_faves:2000 |
min_retweets:N | N retweets or more | ethereum min_retweets:250 |
min_replies:N | N replies or more | tesla min_replies:75 |
-min_faves:N | Fewer than N likes (a ceiling) | -min_faves:25 |
-min_retweets:N | Fewer than N retweets | -min_retweets:10 |
-min_replies:N | Fewer than N replies | -min_replies:1 |
filter:has_engagement | Any likes, RTs, replies, or quotes | from:nasa filter:has_engagement |
-filter:has_engagement | Tweets with zero engagement | from:me -filter:has_engagement |
Worked example: pull the genuinely viral AI tweets of the year with AI since:2026-01-01 min_faves:5000 lang:en. The floor alone strips out an estimated 95% of the volume.
The engagement gate is old enough to have been passed around the platform for years, yet most users have never typed it once. One of the most-shared explanations frames from:handle min_faves:500 as the single most underused feature on Twitter, and the reaction it drew is a fair measure of how few people knew the operator existed at all.
https://x.com/dickiebush/status/1376914228288847875
2. Authors and mentions
Narrow a query by who wrote a tweet, who it answers, or who it names.
| Operator | Effect | Try it |
|---|---|---|
from:handle | Posts authored by that account | from:nasa |
to:handle | Replies pointed at that account | to:nasa |
@handle | Any tweet that names the account | @nasa |
@handle -from:handle | Mentions only, dropping the account's own posts | @nasa -from:nasa |
list:owner/slug | Posts from members of a named list | list:twitter/team |
list:<id> | Same, addressed by the list's numeric id | list:84839422 |
filter:verified | Legacy (pre-2023) verified accounts | space filter:verified |
filter:blue_verified | Paid X Premium accounts | space filter:blue_verified |
filter:follows | Restricted to accounts you follow | news filter:follows |
Heads up: you cannot negate list: or filter:follows. There is no -list:twitter/team.
Isolating old verification: to find accounts that were verified before X Premium existed, stack filter:verified -filter:blue_verified.
3. Time windows
Date filters are what turn a casual search into a reproducible dataset, and they are your main weapon against Twitter's flaky pagination (covered further down).
| Operator | Effect | Try it |
|---|---|---|
since:YYYY-MM-DD | From this day onward (inclusive) | since:2026-02-01 |
until:YYYY-MM-DD | Up to this day (exclusive) | until:2026-11-30 |
since:YYYY-MM-DD_HH:MM:SS_UTC | A timezone-aware timestamp | since:2026-02-01_09:00:00_UTC |
since_time:<unix> | Start bound as epoch seconds | since_time:1769904000 |
until_time:<unix> | End bound as epoch seconds | until_time:1769990400 |
since_id:<tweet_id> | From a tweet id forward (Snowflake-ordered) | since_id:1888888888 |
max_id:<tweet_id> | Up to a tweet id | max_id:1999999999 |
within_time:2d | A rolling 2-day window | bitcoin within_time:2d |
within_time:3h / 5m / 30s | Rolling hours, minutes, or seconds | within_time:5m |
The gotcha that traps everyone: a time operator on its own returns nothing. since:2026-01-01 must ride alongside a keyword, a handle, or a hashtag. Twitter treats a bare date filter as an empty query.
For fast-moving topics: when a trend shifts minute to minute, switch to the _HH:MM:SS_UTC form so you can slice below the day boundary.
Two id-based bounds worth understanding: since_id: and max_id: lean on the fact that tweet ids are Snowflake ids, monotonically increasing and time-sortable, so a higher id is always a later tweet. The since_time: and until_time: operators take Unix epoch seconds instead, which is handy when your upstream system already stores timestamps that way. If you are pulling a window by tweet id, the scrape tweet history guide shows how to anchor a backfill on a known id rather than a calendar date.
4. Keywords and boolean logic
The plumbing under every query. These compose with everything above and below.
| Operator | Effect | Try it |
|---|---|---|
term1 term2 | Both terms required (AND is assumed) | mars rover |
term1 OR term2 | Either side; OR must be capitalized | mars OR moon |
"locked phrase" | Exact wording in order, spell-fix off | "machine learning" |
"start * end" | Asterisk stands in for any one word | "best * of 2026" |
+word | Pin the literal spelling, no autocorrect | +kubernetes |
-word | Exclude tweets carrying the word | apple -fruit |
-"phrase" | Exclude tweets carrying the phrase | -"hot take" |
#tag | Match a hashtag | #opensource |
$SYM | Cashtag for a ticker | $NVDA |
url:host.com | Tokenized domain anywhere in the body | url:github.com |
:) / :( | Crude positive or negative sentiment | airlines :( |
Tip: AND is implicit, so (mars rover) and mars rover resolve to the same set.
Tip: hyphenated domains need underscores: write url:t_mobile.com, not url:t-mobile.com.
5. Tweet kind
Sort by whether a tweet is original, a reply, a retweet, a quote, or part of a self-thread.
| Operator | Effect |
|---|---|
filter:replies | The tweet is a reply |
-filter:replies | Strip replies out |
filter:self_threads | Author's own reply threads |
filter:quote | Carries a quoted tweet |
filter:retweets | Old-style "RT" plus quote tweets |
filter:nativeretweets | Retweet-button RTs (last 7-10 days only) |
include:nativeretweets | Adds RTs back in (off by default) |
conversation_id:<tweet_id> | Every tweet in one conversation |
quoted_tweet_id:<tweet_id> | Tweets quoting a given tweet |
quoted_user_id:<user_id> | Tweets quoting a given account |
Note: filter:nativeretweets and include:nativeretweets reach back only about 7 to 10 days. For anything older, fall back to filter:retweets.
Start building with TwitterAPIs
$0.04 per 1,000 tweets. $0.50 free credits. No credit card required.
6. Attached media
Keep only tweets carrying a particular attachment type.
| Operator | Effect |
|---|---|
filter:media | Any attachment |
filter:images | Has an image, from any source |
filter:twimg | Native Twitter images only (pic.twitter.com) |
filter:videos | Any video, embeds included |
filter:native_video | Twitter-hosted video |
filter:consumer_video | Standard native video |
filter:pro_video | Amplify / pro video |
filter:spaces | Twitter Spaces audio |
filter:links | Contains any URL |
filter:hashtags | Contains a hashtag |
filter:mentions | Contains an @mention |
filter:news | Links to whitelisted news domains |
filter:safe | Drops NSFW and sensitive content |
Handy combination: from:NASA filter:media -filter:images returns NASA's videos and GIFs while excluding stills.
7. Language codes
Restrict by Twitter's auto-detected language using ISO 639-1 two-letter codes. The detection is Twitter's own classifier, not yours, so on short or mixed-language tweets it occasionally guesses wrong, which is why the pseudo-codes below exist for the cases the classifier cannot resolve.
| Operator | Effect |
|---|---|
lang:en | English |
lang:es | Spanish |
lang:ja | Japanese |
lang:hi | Hindi |
lang:fr, lang:de, lang:pt, lang:ru, lang:zh, lang:ar, lang:ko, and so on | Standard two-letter codes |
The pseudo-language codes nobody documents
Twitter also exposes a handful of codes that sort by content shape rather than spoken language:
| Code | Matches tweets that contain only |
|---|---|
lang:und | Language it could not classify |
lang:qam | @mentions, nothing else |
lang:qct | Cashtags, nothing else |
lang:qht | Hashtags, nothing else |
lang:qme | Media links, nothing else |
lang:qst | Very short text (often under 3 chars) |
lang:zxx | Media or cards with no text at all |
Why bother: to grab an account's image-only posts with zero text noise, run from:user lang:zxx filter:images.
8. Posting client
Filter by the app that published a tweet. Spaces and hyphens in the client name become underscores.
| Operator | Effect |
|---|---|
source:twitter_for_iphone | Sent from iPhone |
source:twitter_for_android | Sent from Android |
source:twitter_web_app | Sent from the web |
source:tweetdeck | Sent from TweetDeck |
source:twitter_ads | A paid, promoted tweet |
Syntax note: Twitter for iPhone becomes twitter_for_iphone. Underscores everywhere a space or dash would sit.
9. Location
Match tweets by attached geo data. Treat this category as best-effort, not authoritative (see the warning).
| Operator | Effect |
|---|---|
near:"City Name" | Geotagged to a city |
near:me | Around your own location |
within:10km | A radius modifier (km or mi) |
geocode:37.7764,-122.4172,10km | Latitude, longitude, radius |
place:<Place ID> | A Twitter Place object |
Warning: X retired exact-coordinate geotagging for the bulk of text tweets, so geo coverage is thin. Never make a location filter the backbone of a query you need to be complete.
10. Stacking operators
The leverage is in combinations. One string can constrain topic, engagement, language, and date at once, for example AI min_faves:5000 lang:en since:2026-01-01. Here are high-signal stacks worth saving:
| Query | What it surfaces |
|---|---|
from:nasa min_faves:50000 since:2026-01-01 | NASA's most viral 2026 posts |
(bitcoin OR eth) min_faves:1000 lang:en -filter:retweets | Popular English crypto talk, no RTs |
"$NVDA" filter:blue_verified min_replies:20 | NVDA chatter from paid-verified accounts with discussion |
#AI filter:images min_faves:100 since:2026-01-01 | Popular 2026 AI tweets carrying images |
from:NASA filter:media -filter:images | NASA videos and GIFs |
list:twitter/team since:2026-01-01 lang:en | Recent posts from a list's members |
to:openai min_faves:10 | Replies aimed at OpenAI that got traction |
conversation_id:1888888888 | A full thread around one tweet |
How grouping and precedence actually resolve
When you mix OR into a longer string, parentheses are not optional polish, they decide what the query means. Twitter evaluates an unparenthesized OR loosely, so bitcoin OR eth min_faves:1000 does not read the way most people expect: the engagement floor binds to the eth side only, leaving the bitcoin side ungated. Wrap the alternation to fix it: (bitcoin OR eth) min_faves:1000 applies the floor to both. The same logic governs exclusions. apple -fruit OR juice will not exclude what you think; group the intent explicitly as apple (-fruit) (juice OR drink). The safe habit is to parenthesize every OR cluster and treat each parenthesized group as a single unit toward the 22-to-23-operator ceiling, because a grouped alternation counts as one expression rather than several. Build long queries from the inside out, validate each group on web search first, then assemble, and you sidestep the most common cause of a query that parses cleanly but returns the wrong set.
What is flaky or dead in 2026
Plenty of operators that appear in old reference lists no longer behave. Knowing the dead ends up front saves an afternoon.
| Operator | State | Reason |
|---|---|---|
filter:vine | Dead | Vine closed in 2017 |
filter:periscope | Dead | Periscope closed in 2021 |
near:, within:, geocode: | Thin coverage | Exact geo retired for most tweets |
filter:nativeretweets | 7-10 day window | Twitter's retention cap |
card_name:* | 7-8 day window | Short retention |
filter:verified | Inconsistent | Tangled with Blue after the rebrand |
Operator ceiling: Twitter caps a query at roughly 22 to 23 operators. Go past it and the whole query fails silently with no error.
The silent-failure behavior is a frequent source of frustration, and the broader complaint that the native search index drops results or behaves inconsistently comes up often enough that it has its own running threads.
Twitter Search is Broken from r/Twitter
A few of these deserve a sentence of context. The filter:vine and filter:periscope operators still parse without error, which is the trap: they return nothing rather than failing loudly, so a pipeline can sit on an empty result set for days before anyone notices. The geo trio (near:, within:, geocode:) is not fully dead, it simply matches a shrinking pool of tweets, so use it only as a secondary narrowing filter on top of a keyword, never as the primary lever. And filter:verified is the subtle one: since the rebrand folded legacy verification and paid verification together in places, the same query can return different account mixes depending on Twitter's current handling, which is exactly why the explicit filter:verified -filter:blue_verified stack from the authors section is the safer way to isolate legacy accounts.
Calling the endpoint from code
The TwitterAPIs Advanced Search endpoint forwards every web operator at $0.0008 per call. Put your URL-encoded operator string in q, set product to Latest or Top, and walk pages with cursor until next_cursor comes back empty. No $200 floor (X API pricing), no developer-account approval, and the engagement gates are live on request one. Nothing caps the endpoint per minute or per day; the only ceiling is your credit balance and the concurrency your own client drives. For how that sits against X's published per-window ceilings in the X rate-limit reference, the Twitter API rate limit guide runs the side-by-side.
| Detail | Value |
|---|---|
| Endpoint | GET /twitter/tweet/advanced_search |
| Base URL | https://api.twitterapis.com |
| Query param | q (URL-encoded operator string) |
| Product param | product=Latest (default) or product=Top |
| Price | $0.0008 per call (~20 tweets) |
| Rate limit | None per window; bounded by your credit balance and client concurrency |
| Pagination | Cursor-based; feed next_cursor back into cursor |
| Auth | Authorization: Bearer <YOUR_API_KEY> |
curl
curl "https://api.twitterapis.com/twitter/tweet/advanced_search?query=ethereum+min_faves%3A500+since%3A2026-02-01&product=Top" \
-H "Authorization: Bearer YOUR_API_KEY"
Python
The requests library is all you need; there is no SDK to install and no OAuth dance, since the endpoint authenticates on a single Bearer header. If you do not yet have a key, the Twitter API key walkthrough covers signup, and the complete Python tutorial extends this snippet into a full client.
import requests
ENDPOINT = "https://api.twitterapis.com/twitter/tweet/advanced_search"
API_KEY = "YOUR_API_KEY"
response = requests.get(
ENDPOINT,
params={"query": "ethereum min_faves:500 since:2026-02-01", "product": "Top"},
headers={"Authorization": f"Bearer {API_KEY}"},
)
payload = response.json()
print(f"got {len(payload['tweets'])} tweets; more pages: {payload.get('next_cursor') is not None}")
JavaScript / Node.js
The same call from Node uses only the built-in fetch, with query params assembled via URLSearchParams, no client library required. For the full server-side build with paging, environment-based key handling, and error retries, the Node.js Twitter API tutorial takes this snippet to production.
const ENDPOINT = "https://api.twitterapis.com/twitter/tweet/advanced_search";
const query = new URLSearchParams({
query: "ethereum min_faves:500 since:2026-02-01",
product: "Top",
});
const reply = await fetch(`${ENDPOINT}?${query}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const payload = await reply.json();
console.log(`got ${payload.tweets.length} tweets; more pages: ${payload.next_cursor != null}`);
Every response comes back as { tweets: [...], next_cursor }. To advance a page, hand the prior response's next_cursor to the next call's cursor param.
Reading the response payload
Each item in tweets carries the fields you would expect off a tweet object: the tweet id, its text, the createdAt timestamp, the engagement counts (likeCount, retweetCount, replyCount, quoteCount, viewCount), and a nested author block with userName, name, followers, and the verification flags. Two practical habits save downstream pain. First, key your storage on the tweet id rather than position, so a duplicate that slips through during deep paging gets overwritten instead of double-counted. Second, treat next_cursor as the stop signal: it is the token you send to keep going, and when it comes back null or empty you have reached the end of the chain and stop, do not retry the same cursor.
What a search job actually costs
The pricing makes back-of-envelope math easy, so size a job before you run it. Reads bill at $0.0008 per call, and a call returns roughly 20 tweets, which works out to $0.04 per 1,000 tweets. A few common jobs, modeled out:
- Pulling 10,000 tweets for a one-off study: about 500 calls, an estimated $0.40.
- A daily brand-monitoring cron that grabs 2,000 tweets a day: about 100 calls a day, an estimated $0.08 daily, under $2.50 a month.
- A 100,000-tweet historical backfill split into date windows: about 5,000 calls, an estimated $4.00.
Every new account starts with $0.50 in free credits, which is about 625 calls or 12,500 tweets, enough to run a real pilot before you ever attach a card. These figures are a planning model, not a quote; actual call counts move with how dense each window is and how many tweets a given query returns per page. For a wider price comparison against other providers on a real per-1,000-tweet basis, the cheapest Twitter API ranking and the Twitter API cost benchmark both model the same workloads end to end.
The cheapest pay-as-you-go Twitter API. Try it free.
$0.04 per 1,000 tweets. $0.50 free credits. No credit card required.
Why deep pagination breaks, and the fix
Twitter's own cursor pagination for Advanced Search is unreliable upstream in 2026. Push past ten or so pages on a single cursor chain and you start seeing repeats or an early stop. This is not a TwitterAPIs bug; it is a Twitter-side defect that every scraping provider inherits the same way. The mechanics of cursor tokens are spelled out in X's own pagination documentation, but the stability ceiling on deep chains is a real-world limit no provider can document away.
The fix: stop leaning on deep cursors. Slice the query into date windows instead.
Rather than one query that grinds through 50 pages, fire several narrower queries, each covering a shorter span:
q=AI min_faves:100 lang:en since:2026-01-01 until:2026-01-08q=AI min_faves:100 lang:en since:2026-01-08 until:2026-01-15q=AI min_faves:100 lang:en since:2026-01-15 until:2026-01-22
Each window opens a fresh cursor chain. When a window is still too dense, drop to hourly slices with timestamp precision: since:2026-01-01_12:00:00_UTC until:2026-01-01_13:00:00_UTC. The result is steadier and fully reproducible, which deep pagination never is.
Production code patterns
The three patterns below cover what teams actually build: a paginator that backs off on transient errors, a window-splitter that sidesteps the cursor bug, and an async fetcher that runs windows side by side.
Paginate with retry (Python)
import requests
import time
ENDPOINT = "https://api.twitterapis.com/twitter/tweet/advanced_search"
API_KEY = "YOUR_API_KEY"
def collect_pages(query: str, page_cap: int = 20) -> list[dict]:
"""Walk every page, backing off exponentially on transient errors."""
harvested: list[dict] = []
cursor = None
auth = {"Authorization": f"Bearer {API_KEY}"}
for _ in range(page_cap):
args = {"query": query, "product": "Latest"}
if cursor:
args["cursor"] = cursor
for try_num in range(3):
reply = requests.get(ENDPOINT, params=args, headers=auth, timeout=15)
if reply.status_code == 200:
break
if reply.status_code in (429, 502, 503):
time.sleep(2 ** try_num)
else:
reply.raise_for_status()
body = reply.json()
harvested.extend(body.get("tweets", []))
cursor = body.get("next_cursor")
if not cursor:
break
return harvested
# Pull every viral AI tweet from January 2026
batch = collect_pages("AI min_faves:1000 lang:en since:2026-01-01 until:2026-02-01")
print(f"pulled {len(batch)} tweets")
Split a long range into windows (Python)
from datetime import date, timedelta
def split_by_window(base_query: str, opens: date, closes: date, span_days: int = 7) -> list[dict]:
"""Break a wide date range into weekly windows so the cursor stays stable."""
harvested: list[dict] = []
cursor_day = opens
while cursor_day < closes:
window_end = min(cursor_day + timedelta(days=span_days), closes)
windowed_q = f"{base_query} since:{cursor_day.isoformat()} until:{window_end.isoformat()}"
harvested.extend(collect_pages(windowed_q, page_cap=5))
cursor_day = window_end
return harvested
q1 = split_by_window("openai min_faves:500 lang:en", date(2026, 1, 1), date(2026, 4, 1))
print(f"Q1 2026: {len(q1)} viral OpenAI tweets")
Run windows concurrently (Python + httpx)
This pattern uses httpx for its native async client, so independent date windows fetch in parallel instead of one after another. Keep concurrency modest to stay under the rate ceiling, and if you are running heavy concurrent jobs from one machine, route them through rotating egress per the residential proxy guide for Twitter scraping so a single IP does not absorb every request.
import asyncio
import httpx
from datetime import date, timedelta
ENDPOINT = "https://api.twitterapis.com/twitter/tweet/advanced_search"
API_KEY = "YOUR_API_KEY"
async def pull_window(client: httpx.AsyncClient, query: str) -> list[dict]:
reply = await client.get(
ENDPOINT,
params={"query": query, "product": "Latest"},
headers={"Authorization": f"Bearer {API_KEY}"},
)
reply.raise_for_status()
return reply.json().get("tweets", [])
async def gather_windows(base_query: str, opens: date, weeks: int = 4) -> list[dict]:
queries = []
for week in range(weeks):
start = opens + timedelta(weeks=week)
finish = start + timedelta(weeks=1)
queries.append(f"{base_query} since:{start.isoformat()} until:{finish.isoformat()}")
async with httpx.AsyncClient(timeout=15) as client:
windows = await asyncio.gather(*[pull_window(client, q) for q in queries])
return [tweet for window in windows for tweet in window]
harvest = asyncio.run(gather_windows("bitcoin min_faves:200 lang:en", date(2026, 1, 1), weeks=12))
print(f"{len(harvest)} tweets across 12 weeks, fetched in parallel")
Field-tested workflows
Operators on their own are trivia. The value shows up when you wire them into a repeating job. Five patterns cover most of what teams actually run.
Brand monitoring
Watch what people say about your brand, gated to meaningful engagement and stripped of your own posts:
"YourBrand" OR "@yourhandle" min_faves:5 lang:en -from:yourhandle -filter:retweets since:2026-01-01
Chunk it into weekly windows, run it on a cron, and store each pull with its window date. Comparing week to week is how you spot a sentiment swing before it turns into a PR fire. To actually score the tone of the results, the Twitter sentiment analysis guide walks through that exact pipeline.
Influencer discovery
Surface accounts posting high-engagement content in a niche, with a paid-verification gate:
#niche OR "keyword1" OR "keyword2" min_faves:500 min_retweets:100 lang:en filter:blue_verified -filter:retweets since:2026-01-01
The min_faves:500 min_retweets:100 floor clears the noise, and filter:blue_verified keeps it to accounts that pay for verification. Page through, lift author.userName off each tweet, and you have a seed list. The pagination code for this is in the Python Twitter API tutorial. Once you have the seed accounts, the export Twitter followers guide shows how to expand each one into its audience for deeper network mapping.
Competitor intelligence
Track conversation about a competitor while excluding the competitor's own posts:
"CompetitorName" OR "@competitor" -from:competitor min_faves:10 lang:en -filter:retweets
Bolt on filter:replies to zero in on complaint threads, or -filter:replies to see organic mentions. The min_faves:10 floor clears the low-signal chatter that would otherwise drown the dataset. To turn this query into a recurring pull rather than a one-off, the how to scrape tweets walkthrough covers the storage and dedupe scaffolding around it.
Historical event research
Rebuild the public reaction to a launch, a headline, or a market move with window slicing:
"event keyword" lang:en since:2026-03-01 until:2026-03-02
"event keyword" lang:en since:2026-03-02 until:2026-03-03
... (go hourly when volume is high)
Each window's until: is an exclusive upper bound. For sub-hour detail during a fast event, switch to timestamps: since:2026-03-01_09:00:00_UTC until:2026-03-01_10:00:00_UTC. That rebuilds the reaction hour by hour. The math on a large historical sweep is in the Twitter API cost guide.
Scraping one specific thread
Have a tweet id and want every reply and quote on it:
conversation_id:1888888888
Want every tweet that quoted a given post:
quoted_tweet_id:1888888888
Add min_faves:5 to keep the thread to the parts that got traction. This captures a full public reaction to a single post, which on the official X API would take several separate calls to assemble.
Buyer-intent lead generation
Find people actively asking for what you sell, before a competitor answers them first:
("looking for" OR "any recommendations" OR "anyone know a") "your category" min_faves:1 lang:en -filter:retweets within_time:3d
The phrase cluster catches intent language, min_faves:1 clears empty noise without setting the bar so high you miss fresh posts, and within_time:3d keeps the list to tweets recent enough to still be worth a reply. Run it a few times a day on a tight window, dedupe on tweet id, and route new hits to whoever owns replies. Because the volume on a sharp intent query is usually low, a single window normally fits inside one or two pages, so you rarely need the chunker here. If you want this to fire automatically and post replies on a schedule, the guide to building a Twitter bot wires the search into a send loop, and the bot detection guide covers the pacing and behavior limits that keep an automated account healthy.
Operators people get wrong
A few operators do something other than what their name suggests, and that mismatch causes most of the off-target datasets.
filter:blue_verified is not filter:verified. filter:verified catches the pre-Blue legacy badge, the journalists, public figures, and organizations verified before 2023. filter:blue_verified catches anyone paying for X Premium. For editorial signal in a brand watch, you usually want filter:verified, not the paid pool.
-filter:retweets already covers both retweet styles. It drops manual "RT @user" text and native retweet-button RTs together. include:nativeretweets puts native RTs back (most queries exclude them by default). For a clean original-content set, -filter:retweets. To trace how far one tweet spread, filter:nativeretweets inside a tight window.
within_time:Xd is relative, not anchored. A window like within_time:7d counts back from the moment you run the query, so the same string returns a different set next week. For a dataset you need to reproduce, use explicit since: and until: dates instead.
@user is broader than a reply filter. from:user returns only that account's own tweets. @user returns anything naming the account, including other people's replies and quotes. Use from:user for timeline work and @user for mention tracking, and OR them for full context. If the handle is also a common word, add lang:en or min_faves:1 so unrelated tweets do not flood the stream.
A test routine before you trust a query
Validating a new operator combination before it goes into a pipeline takes three quick steps and prevents the classic failure: a query that looks right but returns empty or off-target at scale.
Step 1: eyeball it on web search, free. Paste the string into twitter.com/search and check the results match your intent. Web search runs the same operator set TwitterAPIs forwards, so this costs nothing and catches obvious logic errors.
Step 2: fire one API call. Run the string once and read the response. Skim the first five tweet texts and confirm they are what you expected. This is where you catch a query whose syntax is valid but whose logic is subtly wrong.
Step 3: check the count before paging. On call one, look at next_cursor and the tweet count. If next_cursor comes back null or empty and you got fewer than five tweets, the query is too narrow or the window is off. Fix it before you spin up a full paginated job.
Cheat sheet
The categories developers reach for most: authors (from:, to:, @, list:), time (since:, until:, within_time:), engagement (min_faves:, min_retweets:, min_replies:), tweet kind (filter:replies, filter:media, filter:quote), language (lang:en, lang:zxx), and exclusions (-word, -"phrase", -filter:retweets).
Quick picks:
- Authors:
from:,to:,@,list: - Time:
since:,until:,within_time: - Engagement:
min_faves:,min_retweets:,min_replies: - Kind:
filter:replies,filter:media,filter:quote - Language:
lang:en,lang:zxx(media-only) - Exclude:
-word,-"phrase",-filter:retweets
Lead-generation stack:
#yourkeyword min_faves:10 lang:en -filter:retweets since:2026-01-01
Sentiment stack:
$TICKER (":)" OR ":(") min_faves:5 lang:en since:2026-01-01
Competitor-watch stack:
@competitor -from:competitor filter:has_engagement since:2026-01-01
If you want the whole vocabulary on a single card you can screenshot and keep, this widely-shared cheat sheet collects the operators most people actually reach for, the author gate, the boolean OR, the engagement floors, the media filters, and the date bounds, in one compact list.
https://x.com/thatroblennon/status/1554935283736403970
For anyone who would rather watch the operators typed into the search box before wiring them into code, this walkthrough builds advanced-search queries step by step and shows what each filter does to the result set in real time, which is the fastest way to develop an intuition for how the gates stack.
https://www.youtube.com/watch?v=5z3rlmFmeLI
Get started
These operators hand you roughly 10x the filtering reach of the official X API, including the engagement floors and full boolean logic that v2 simply will not expose. TwitterAPIs gives every new account $0.50 in free credits at signup, no developer account and no card, enough to exercise every category on this page before you commit a dollar.
- Sign up at twitterapis.com, instant key, no developer-account review
- Hit
GET /twitter/tweet/advanced_searchwith your operator string inq - Read the full API docs for paging, rate limits, and the response schema
For the exhaustive operator list, including the obscure ones this page skips, the community-maintained twitter-advanced-search repository is the canonical reference. For production scraping technique, cost control, and proxy strategy, see the Twitter scraping best practices guide. For a precise account of what v2 supports versus the full web set, Twitter API v2 vs TwitterAPIs lays it out. And the per-call cost math at scale is in the Twitter API cost guide. If date bounding is the only part you need, how to search tweets by date covers the day, timestamp, epoch and identifier forms without the rest of the operator set.
Operator behavior cross-checked against the community-maintained igorbrigadir/twitter-advanced-search repository (updated regularly), the official X API documentation as of May 2026, and the X Developer Community forums for operator-behavior changes.
// sources
Where these numbers come from
Each row is a figure in this post and the artefact it was read from. Prices and limits on this platform move, so check the date on the source before you plan against it.
- igorbrigadir twitter-advanced-search repository
- The community-maintained operator catalog the post says every operator definition on the page was cross-checked against, alongside live calls.
- X API v2 build-a-query operator reference
- The official v2 operator list the post uses to show the trimmed subset, which lacks min_faves, min_retweets, within_time, and filter blue_verified.
- X API pricing page
- The source for the $0.005 per post read figure in the route comparison table, and for the point that the official search route carries a spend floor.
- X API rate-limit reference
- The published X ceilings the post sets against the TwitterAPIs Advanced Search endpoint, which carries no per-window request cap of its own.
- X API search pagination documentation
- Documents the cursor token mechanics the post relies on, and is the contrast for its finding that deep cursor chains past roughly ten pages return repeats or stop early.
- Snowflake ID scheme
- Explains why tweet ids are monotonically increasing and time-sortable, which is what makes the since_id and max_id bounds in the post behave as time windows.
Frequently Asked Questions
It is the umbrella label for any programmatic route into Twitter's search index. The cheapest pay-as-you-go production option in 2026 is the TwitterAPIs /twitter/tweet/advanced_search endpoint at $0.0008 per call (about 20 tweets), forwarding the full web operator set. X's own /2/tweets/search/recent is also a search API, but at $0.005 per post read and a trimmed operator list that drops the engagement gates entirely.
X's official API has no real free tier in 2026; search reads run $0.005 per post. TwitterAPIs drops $0.50 in free credits on every new account at signup with no card, which buys about 625 search calls (roughly 12,500 tweets), plenty to validate the API before you commit a dollar to it.
Engagement gates (min_faves:, min_retweets:, min_replies:) work on Twitter's web search and on the TwitterAPIs advanced search endpoint, but not on X API v2 at any tier. It is a long-running gap that makes v2 far weaker for engagement filtering. The TwitterAPIs endpoint forwards these gates intact, which is the main reason teams leave v2 for it in the first place.
X's official API allows 450 search requests per 15 minutes on a Bearer token, dropping to 300 under user-context OAuth. The TwitterAPIs advanced_search endpoint runs no platform window at all, so analytics, monitoring, and research jobs are bounded only by their credit balance and the concurrency they drive. If you want to go faster, split the query into parallel date windows across separate processes.
Yes, but there is a hard ceiling. Twitter caps a query around 22 to 23 operators; go further and it fails silently or returns empty with no error. In practice most useful queries land between 5 and 10. When you need something complex, group related conditions in parentheses to keep the count down, for example (bitcoin OR eth OR crypto) reads as one expression, not three operators.
Install the requests library with pip install requests, then send a GET to https://api.twitterapis.com/twitter/tweet/advanced_search with your operator string in the q param and your key in an Authorization Bearer header. Read tweets and next_cursor off the JSON response, and feed next_cursor back into cursor to walk pages. The full tutorial with retry, paging, and async patterns moves you from a single call to a production paginator step by step.
The v2 /2/tweets/search/recent endpoint is one specific search API. The TwitterAPIs /twitter/tweet/advanced_search endpoint is a separate one with very different economics (about 100x cheaper) and a much wider operator set, the full web vocabulary versus v2's slice. The biggest practical gap is that v2 silently ignores engagement gates such as min_faves:, while the TwitterAPIs passthrough honors them on the first request.
Cursor paging: feed each response's next_cursor into the next call's cursor, and stop when next_cursor comes back null or empty. For deep pulls (50-plus pages), split the query into date windows with since: and until: to dodge duplicates and early stops, since Twitter's upstream cursor chain grows unreliable past about ten pages on a single chain.
Cursor paging is the only dependable method: hand each response's next_cursor back as cursor, stop when next_cursor comes back null or empty, and set a maxPages cap so a runaway loop cannot happen. For deep historical work, slice into date windows with since: and until: rather than grinding one cursor chain, which is where the upstream cursor-stability bug produces duplicates past 50 pages.
Check out similar blogs
More guides on the Twitter/X API, scraping, and pricing.







