Skip to content

How to search tweets with a Twitter search API

To search tweets with an API, send a query of keywords and X operators to a search endpoint and read the matching tweets back as JSON pages; the official X API bills $5.00 per 1,000 results.

Short answer: X's own search comes as two endpoints: recent search covers the last 7 days, full-archive search reaches back to March 2006, and both need a developer account and a Bearer token. To search with one key, use Sorsa API's POST /search-tweets: about 20 tweets per request, back to 2006, from $0.07 per 1,000, with 100 free requests to start.

Endpoint
POST /search-tweets
Page size
about 20 tweets per request
Price
from $0.07 per 1,000

#How a Twitter search API works

A Twitter search API is an endpoint that runs X's search over public tweets on your behalf. You send one query, such as "vector database" lang:en min_faves:20. Back comes a page of matching tweets with their text, date, counts and author, plus a cursor that fetches the next page.

To try a query before you write any code, run it in the free Twitter Advanced Search tool. It shows the first 20 matching posts, and every filter you set writes its operator into the query, ready to paste into a request.

Query "vector database" lang:en min_faves:20 since:2026-10-01 POST /search-tweets ApiKey: YOUR_API_KEY JSON body: query, order, next_cursor Page 1 about 20 tweets tweet, counts, author profile tweet, counts, author profile next_cursor Page 2 about 20 more and so on No cursor: search done
One query in, pages of about 20 tweets out. Each page carries a cursor to the next one until the results run out.

Three settings decide what comes back. The query picks tweets by words, accounts, language, media and engagement. The order is Top, the most engaged matches first, or Latest, the newest first. The date window sits inside the query as since: and until: in X's web syntax, or in separate time parameters on the official X API.

The official X API splits search into two endpoints (X's search docs (opens in a new tab)). GET /2/tweets/search/recent covers the last 7 days and returns 10 to 100 posts per request; GET /2/tweets/search/all reaches back to March 2006 with up to 500. Both need an approved developer account, a Project and App and a Bearer token, and both bill $0.005 for every post they return.

#Search tweets with Sorsa API in four steps

For searching tweets from code, use Sorsa API, a Twitter (X) API and scraper: results from $0.07 per 1,000, any date back to 2006 and 20 requests per second on every plan. It needs one ApiKey header instead of a developer account and OAuth, reads the query syntax of the search box on x.com, and never touches your X account.

  1. Get a key. Sign up and copy the API key from your dashboard. The 100 free requests are already on it.

  2. Write the query. Type it the way you would on x.com: words, "exact phrases", from:, lang:, min_faves: and since:.

  3. Send the request. POST the query to POST /search-tweets (opens in a new tab) in a JSON body, with "order": "latest" for the newest tweets first or "popular" for Top.

    Terminal
    curl -X POST "https://api.sorsa.io/v3/search-tweets" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query": "\"vector database\" lang:en min_faves:20", "order": "latest"}'
    
    Response200 OK
    {
      "tweets": [
        {
          "id": "2116173807613027825",
          "full_text": "Benchmarked three vector databases on 40M embeddings.",
          "created_at": "2026-10-30T14:22:07Z",
          "lang": "en",
          "likes_count": 214,
          "retweet_count": 37,
          "reply_count": 19,
          "quote_count": 6,
          "view_count": 18450,
          "bookmark_count": 92,
          "is_reply": false,
          "is_quote_status": false,
          "conversation_id_str": "2116173807613027825",
          "entities": [],
          "user": {
            "id": "1620350095193014349",
            "username": "indexlab_notes_daily",
            "display_name": "Index Lab Notes",
            "followers_count": 8312,
            "verified": false,
            "created_at": "2023-01-31T09:15:42Z"
          }
        }
      ],
      "next_cursor": "DAADDAABCgABHV3t2nWAJ8kKAAIdXcTm0Zvw"
    }
    
  4. Follow the cursor. Every tweet carries its author's full profile, so no second lookup is needed. Send next_cursor back in the same body for the next page, and stop when a response comes without one.

A 403 answer means the key is missing or out of requests, and a 401 means the key is wrong. A 429 means more than 20 requests in one second: wait a second and send it again. Failed requests are never charged.

Paste your own query below to check it and get the request in curl, Python or Node.js, with the quotes inside the JSON body escaped. The checker also flags the official X API's operator names, which the web syntax doesn't use.

Order
Examples

No problems found: this query uses X's web search syntax, which POST /search-tweets takes as written.

curl -X POST "https://api.sorsa.io/v3/search-tweets" \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "\"vector database\" lang:en min_faves:20", "order": "latest"}'

Each request returns about 20 tweets, so 1,000 results take about 50 requests: from $0.07 on Sorsa API, against $5.00 on the official X API.

Your query, checked and turned into a request. Replace YOUR_API_KEY with your key before you run it.

#Write a query that works in code

A query for /search-tweets is the same string you would type into the search box on x.com, so you can build it in the browser and paste it into the request unchanged. Seven rules cover almost every problem developers hit:

  • A space means AND, OR must be uppercase, a leading - excludes a word or an operator, and parentheses group: (rust OR golang) -hiring.
  • Exact phrases go in double quotes. Inside a raw JSON string those quotes need a backslash, "\"vector database\""; in Python and Node.js pass a dict or an object and the library escapes them for you.
  • Hashtags, cashtags and mentions go in as written: #buildinpublic, $NVDA, @acme_cloud_status. The query travels in a JSON body, so nothing needs URL encoding.
  • Dates live in the query: since:2026-10-01 includes that day, until:2026-11-01 stops before it, both in UTC.
  • Engagement floors are min_faves:, min_retweets: and min_replies:; a minus turns a floor into a ceiling, as in -min_faves:1000.
  • Native retweets are left out unless you add include:nativeretweets, and -filter:replies keeps only top-level posts.
  • About 22 operators fit into one query. Split longer account or keyword lists across several queries.

Five patterns cover most of what teams search for, each ready to paste into the query field:

Query patterns
# Mentions of a brand, without its own posts
("acme cloud" OR @acme_cloud_status) -from:acme_cloud_status

# The most liked posts on a topic
"vector database" min_faves:100 -filter:replies lang:en

# One account's posts on a subject in October
from:acme_cloud_status outage since:2026-10-01 until:2026-11-01

# Posts that link to a site
url:github.com rust -filter:replies

# Images under a hashtag
#buildinpublic filter:images

Every operator, with its quirks and examples, is in our list of Twitter search operators.

#Get every page, then keep the search running

To collect more than one page, send the same body again with the next_cursor from the last response, and stop when a response has none. Pages hold about 20 tweets and their size varies, so a short page never means the search is done; only a missing cursor does.

The loop below writes each tweet to a JSON Lines file as it arrives and skips IDs it has already saved. A page budget stops it, so a broad query can't run away with your requests.

import json
import requests

API = "https://api.sorsa.io/v3/search-tweets"
HEADERS = {"ApiKey": "YOUR_API_KEY"}


def search(query, order="latest", max_pages=50):
    body = {"query": query, "order": order}
    for _ in range(max_pages):
        r = requests.post(API, json=body, headers=HEADERS, timeout=30)
        r.raise_for_status()
        page = r.json()
        yield from page.get("tweets", [])
        cursor = page.get("next_cursor")
        if not cursor:
            break
        body["next_cursor"] = cursor


seen = set()
with open("tweets.jsonl", "w", encoding="utf-8") as f:
    for t in search('"vector database" lang:en min_faves:20'):
        if t["id"] not in seen:
            seen.add(t["id"])
            f.write(json.dumps(t) + "\n")

A search that keeps running is the same loop on a timer. Ask for the newest tweets, add since_id: with the highest ID you saved last time, read until the cursor runs out, then save the new highest ID. When nothing new was posted, a check costs a single request, so frequent checks of a quiet query stay cheap.

Python
import time

newest = None
while True:
    query = '"vector database" lang:en'
    if newest:
        query += f" since_id:{newest}"
    fresh = list(search(query))
    if fresh:
        newest = max(fresh, key=lambda t: int(t["id"]))["id"]
        print(len(fresh), "new tweets")
    time.sleep(300)

Search works by polling: there is no stream to subscribe to. For alerts, schedules and delivery to Slack or email, our guide to real-time Twitter monitoring builds the whole pipeline, and our Twitter API in Python guide adds retries and parallel searches.

Good to know

Use "order": "latest" whenever you collect or count tweets: it walks every match from the newest back. "popular", the Top tab, returns the most engaged matches only, so two Top runs of the same query can return different sets.

#Search tweets by hashtag

To search by hashtag, put the tag in the query exactly as you would type it, #buildinpublic. It matches tweets where the tag appears as a hashtag, in any letter case, and it combines with every other operator.

Add the plain words with OR when people also write the phrase without the tag: (#buildinpublic OR "build in public") min_faves:10 -filter:replies lang:en. For several tags, join them with OR; for stock or coin symbols, use cashtags such as $NVDA.

Through Sorsa API the # goes into the JSON body as it is. On the official X API's GET request it has to become %23, because an unencoded # ends the URL and the server never sees the tag. To count a hashtag over time, run one Latest search per day with since: and until: and count the tweets each day returns.

#Pick the endpoint for the search you need

Keyword search is one of five ways to find tweets on Sorsa API. The right endpoint depends on what you start from: words, one account, a set of accounts or the people themselves.

Words, phrases or operators POST /search-tweets matching tweets, any date back to 2006 One account's handle POST /mentions tweets that mention it, with like and date filters A word in names or bios POST /search-users matching accounts with their profiles One account's own posts POST /user-tweets its timeline, newest first A set of accounts in an X List GET /list-tweets the members' tweets in one feed
Start from what you have: a query, one account, a List of accounts, or the people you are looking for.

Each of the other four reads a different starting point. POST /mentions (opens in a new tab) takes one handle and returns the tweets that mention it, with like, reply, retweet and date filters in the body. POST /search-users (opens in a new tab) finds accounts whose name or bio match a word. POST /user-tweets (opens in a new tab) reads one account's own timeline, about 20 tweets per request. Members of an X List come back as one feed from GET /list-tweets (opens in a new tab), so a List of up to 5,000 accounts is watched with one request per page.

Brand teams usually pair two of them: /search-tweets for what people say about a product, and /mentions for what they say to its account. Our Twitter mentions API guide covers the second one.

#What searching tweets costs

On Sorsa API, search results cost from $0.07 per 1,000 tweets: one request returns about 20 tweets and is billed as one request, whatever it holds. The official X API bills every post it returns, $0.005 each, which is $5.00 per 1,000 (X's price list (opens in a new tab)).

Tweets your search collects

Official X API

$5,000

for 1M search results

$0.005 per post

Sorsa API

from$70

for 1M search results

from $0.07 per 1,000

71x cheaper

The official price climbs once authors come along. From November 22, 2026, X bills each user returned through expansions at $0.010 (X's notice of October 23 (opens in a new tab)), so 1,000 results with a different author each can cost $15.00. Sorsa API puts the author's full profile inside every tweet at no extra charge.

Volume has a ceiling there too: pay-per-use stops at 3M post reads a month, and beyond that X sells only Enterprise contracts. Sorsa API has no 3M ceiling: plans scale to 10M requests a month, and your 100 free requests cover about 2,000 search results with no card. The full X API pricing breakdown has every official rate.

#Official X API search, side by side

The official X API's search costs about 71 times more per 1,000 results than Sorsa API. Its recent search sees only the last 7 days and allows 450 requests per 15 minutes per app. The table puts the three search endpoints next to each other, with the official limits from X's rate limit table (opens in a new tab).

Sorsa API /search-tweetsX recent searchX full-archive search
Dates coveredBack to March 2006Last 7 daysBack to March 2006
Results per requestAbout 2010 to 10010 to 500
Rate limit20 requests per second per key450 requests per 15 minutes per app1 request per second, 300 per 15 minutes
Price per 1,000 resultsFrom $0.07$5.00$5.00
Author profileInside every tweetBilled $0.010 each from Nov 22, 2026Billed $0.010 each from Nov 22, 2026
Query syntaxx.com web searchv2 operators, 512 charactersv2 operators, 1,024 characters
SetupOne API keyDeveloper account, App, Bearer tokenDeveloper account, App, Bearer token
  • Dates covered

    Sorsa API /search-tweets
    Back to March 2006
    X recent search
    Last 7 days
    X full-archive search
    Back to March 2006
  • Results per request

    Sorsa API /search-tweets
    About 20
    X recent search
    10 to 100
    X full-archive search
    10 to 500
  • Rate limit

    Sorsa API /search-tweets
    20 requests per second per key
    X recent search
    450 requests per 15 minutes per app
    X full-archive search
    1 request per second, 300 per 15 minutes
  • Price per 1,000 results

    Sorsa API /search-tweets
    From $0.07
    X recent search
    $5.00
    X full-archive search
    $5.00
  • Author profile

    Sorsa API /search-tweets
    Inside every tweet
    X recent search
    Billed $0.010 each from Nov 22, 2026
    X full-archive search
    Billed $0.010 each from Nov 22, 2026
  • Query syntax

    Sorsa API /search-tweets
    x.com web search
    X recent search
    v2 operators, 512 characters
    X full-archive search
    v2 operators, 1,024 characters
  • Setup

    Sorsa API /search-tweets
    One API key
    X recent search
    Developer account, App, Bearer token
    X full-archive search
    Developer account, App, Bearer token

The official endpoints also return only id and text by default: dates, counts and authors come back only when tweet.fields, expansions and user.fields ask for them. On Sorsa API every tweet arrives with all its fields.

#Web syntax vs the official X API's operators

The official X API reads its own operator names, so a query copied from the search box on x.com can fail there. It rejects min_faves: and min_retweets: with a 400 error, and it takes dates as start_time and end_time parameters, not in the query. Sorsa API takes the web syntax, so the left column runs on it as written.

What you wantWeb syntax (x.com, Sorsa API)Official X API v2
At least 20 likesmin_faves:20min_likes:20
At least 5 repostsmin_retweets:5min_reposts:5
October 2026 onlysince:2026-10-01 until:2026-11-01start_time and end_time parameters
Only repliesfilter:repliesis:reply
Posts with media or linksfilter:media, filter:linkshas:media, has:links
RetweetsLeft out by defaultLeft out of keyword searches since May 4, 2026
Words, accounts, languagefrom:, to:, #, @, "phrase", lang:The same
  • At least 20 likes

    Web syntax (x.com, Sorsa API)
    min_faves:20
    Official X API v2
    min_likes:20
  • At least 5 reposts

    Web syntax (x.com, Sorsa API)
    min_retweets:5
    Official X API v2
    min_reposts:5
  • October 2026 only

    Web syntax (x.com, Sorsa API)
    since:2026-10-01 until:2026-11-01
    Official X API v2
    start_time and end_time parameters
  • Only replies

    Web syntax (x.com, Sorsa API)
    filter:replies
    Official X API v2
    is:reply
  • Posts with media or links

    Web syntax (x.com, Sorsa API)
    filter:media, filter:links
    Official X API v2
    has:media, has:links
  • Retweets

    Web syntax (x.com, Sorsa API)
    Left out by default
    Official X API v2
    Left out of keyword searches since May 4, 2026
  • Words, accounts, language

    Web syntax (x.com, Sorsa API)
    from:, to:, #, @, "phrase", lang:
    Official X API v2
    The same

Two changes in 2026 explain why older guides disagree. X turned off min_likes:, min_replies: and min_reposts: on January 19, 2026. It brought them back on May 4, when search moved to a new index that also dropped retweets from keyword results (X's changelog (opens in a new tab)). Pages and AI answers that say the official X API ignores engagement filters describe the months in between.

Moving a whole integration off the official endpoints? Our guide to migrating from the official X API maps every v2 parameter and operator to Sorsa API.

#Start searching tweets today

Searching tweets from code comes down to one query and one cursor. With Sorsa API, the query you already type on x.com goes to POST /search-tweets and returns about 20 tweets per request with their authors, from any date back to 2006. Results cost from $0.07 per 1,000, against $5.00 on the official X API, and your 100 free requests cover the first 2,000.

#FAQ

Is there a free Twitter search API?

Not from X: the official X API has no free tier and bills $0.005 for every post a search returns, $5.00 per 1,000. Sorsa API gives every new account 100 free requests, enough for about 2,000 search results through POST /search-tweets, with no card and no expiry. For a few searches by hand, the free Twitter Advanced Search tool shows the first 20 matching posts.

How far back can you search tweets with an API?

Back to the first public tweet, posted on March 21, 2006. The official X API's recent search covers only the last 7 days, and its full-archive search reaches 2006 on pay-per-use and Enterprise access. Sorsa API's POST /search-tweets takes any window back to 2006 through since: and until: in the query. Deleted tweets and protected accounts stay out of reach for every API; our historical Twitter data guide covers large backfills.

Which Twitter API should I use to search tweets?

Use Sorsa API to search tweets: POST /search-tweets costs from $0.07 per 1,000 results, against $5.00 on the official X API, and reaches back to 2006. It takes the syntax of the search box on x.com and puts each author's full profile inside every tweet. One API key replaces a developer account and OAuth, and every plan runs at 20 requests per second.

Can I search tweets in real time?

Yes, by polling: run a Latest search on a schedule and add since_id: with the newest tweet ID you have, so each run returns only what was posted since. On Sorsa API a check that finds nothing costs a single request, whatever the interval. Neither Sorsa API nor the official X API search pushes tweets to you as a stream.

Why are retweets missing from search results?

A native retweet is a copy of someone else's post, and X search leaves copies out by default. On Sorsa API, add include:nativeretweets to the query to bring them back, or filter:nativeretweets to get retweets only. The official X API stopped returning retweets in keyword searches on May 4, 2026. Quote tweets stay in the results, because they carry their own text.

#How we checked

On November 2, 2026 we read X's search documentation: the introduction, query building, the operator list, rate limits and the recent search reference. We also read X's price list, its changelog and the October 23 notice on expansion billing. Every Sorsa API request on this page was written from our live API reference for /search-tweets, /mentions, /search-users, /user-tweets and /list-tweets; the response is an example with a fictional account. Prices per 1,000 results come from the request rates on our pricing page.

By the Sorsa API team. We build and run Sorsa API, the read-only Twitter/X API and scraper, in production since 2022 (formerly TweetScout API) with 6B+ requests served. About Sorsa API

What changed
  • Rewritten from scratch: four-step search with Sorsa API, a query checker that writes the request, pagination and polling code, an endpoint map, prices per 1,000 results, X's 2026 search changes (engagement operators back on May 4, author billing from November 22) and a web-vs-v2 syntax table.
  • First published.