How do I search tweets by keyword with an API?
Last updated August 31, 2026
Keyword search is one GET request carrying a query in X operator syntax. Combine from, since, until, quoted phrases, hashtags, a language filter and a minus sign to exclude terms, then a product parameter picks Latest, Top, People, Photos or Videos. Each page bills $0.0008 and returns about 20 matches, which is $0.04 per 1,000 tweets.
Every rate here is the pricing TwitterAPIs publishes. The billed rate is $0.0008 per call; $0.04 per 1,000 tweets is derived from it at a full 20-tweet page, which is the default page size rather than a guaranteed yield (source: twitterapis.com/pricing).
Writing the query string
The query is a single parameter, and it uses the operator syntax people already type into X search. Words separated by spaces combine with an implicit AND, so launch day matches posts holding both words in any order. Wrap a phrase in double quotes to demand the exact sequence. Prefix a term with a minus sign to exclude it. Group alternatives with OR and parentheses when a term has several spellings. The whole expression goes into one parameter, url encoded, and nothing else about the request changes as the expression grows.
The operators worth knowing
Scope to an account with from, or to replies aimed at one with to. Bound a period with since and until, both taking a date. Narrow to one language with lang. Match a tag with the hash symbol or a mention with the at symbol. Put a floor under engagement with min_faves when you want signal instead of volume. These compose, so an exact phrase from one account inside a two week window with a like floor is a single query rather than four passes and a filter written in your own code.
Choosing a result ranking
A second parameter, product, decides what the endpoint ranks for. Latest returns matches in reverse chronological order and is the default, which is what a monitoring job wants. Top returns the ranked selection X surfaces for that query, which suits a sample of the most visible posts. People returns accounts rather than posts. Photos and Videos restrict matches to those carrying that media type. Picking the right one is usually cheaper than filtering afterwards, because a result you discard was still part of a billed page.
What a match looks like when it comes back
The response echoes the query and the product you asked for, then carries a tweets array, a count for that page, next_cursor and has_more. Each match holds id, text, created_at, url, lang and an author object, alongside favorite_count, retweet_count, reply_count, quote_count, bookmark_count and view_count. Flags mark whether an item is a retweet, a quote or a reply, and conversation_id ties a reply back to the post that started it. Entities and media arrive parsed, so links, tags and attachments are addressable fields rather than substrings to pull out of the text.
Paging a sweep and keeping it clean
Each page is one billed call. Send the next_cursor from a response back as cursor and continue while has_more is true, rather than stopping when the cursor looks empty. Two habits keep a long sweep honest. Deduplicate on tweet id as you write, because a query run twice across overlapping periods returns the same post twice. And slice a wide date range into narrower since and until windows instead of paging one enormous expression, so a failure costs one window and the rerun targets exactly the period that failed.
Search operators and what each one narrows
| Operator | Example | What it narrows |
|---|---|---|
| from | from:naval | Posts authored by one account |
| to | to:naval | Replies addressed to one account |
| Quoted phrase | "launch day" | The exact word sequence, in order |
| Minus sign | -giveaway | Drops every match holding the term |
| since and until | since:2026-08-01 until:2026-08-15 | A date window |
| lang | lang:en | One language |
| min_faves | min_faves:1000 | An engagement floor |
| product | product=Top | Ranking: Latest, Top, People, Photos or Videos |
The recent search endpoint returns Tweets from the last seven days that match a search query.
Questions and answers
- How do I search for an exact phrase?
- Wrap it in double quotes inside the query parameter. A quoted launch day matches only that exact sequence, where the same two words unquoted match any post holding both. Quotes compose with everything else, so an exact phrase from one account inside a date window is still one request.
- How do I exclude a word from a keyword search?
- Prefix it with a minus sign. A query of pricing minus giveaway drops every match holding giveaway. Excluding server side is cheaper than filtering afterwards, because a result thrown away in your own code was still part of a billed page.
- What does the product parameter do?
- It picks the ranking. Latest is reverse chronological and the default. Top returns the ranked selection X surfaces for the query. People returns accounts instead of posts, and Photos and Videos restrict matches to those carrying that media type.
- What fields come back on each match?
- id, text, created_at, url, lang, an author object, and six engagement counts covering favorites, retweets, replies, quotes, bookmarks and views. Flags mark retweets, quotes and replies, conversation_id links a reply to its parent, and entities and media arrive already parsed.
- How do I page through a large keyword sweep?
- Send next_cursor back as cursor and continue while has_more is true. Deduplicate on tweet id as you write, since overlapping runs repeat posts, and split a wide date range into narrower since and until windows so a failure costs one window rather than the whole sweep.
Keep reading
- Twitter Search API endpoint and reference
- Quickstart: your first Twitter API call in 2 minutes
- TwitterAPIs REST documentation
- How to get tweets programmatically
- How do you search tweets by date?
- How do I stream tweets in real time?
- Twitter advanced search operators
- How do you search for Twitter users by keyword?
Start with $0.50 in free credits
No credit card. Roughly 12,500 tweets to test every endpoint.