Skip to main content

Search X

Search public X posts by keyword or boolean query. Results are relevance/recency-ranked and carry full post metadata.

GET /v1/x/search

Building a query​

Supply either a single query or the structured boolean parameters — not both (if query is set, it wins).

X's own search operators work directly inside query:

OperatorExampleMatches
AND (space)tesla model3both terms
ORmodel3 OR modelyeither term
-tesla -recallexcludes a term
"…""climate change"exact phrase
from:from:nasaposts from an account
##AIa hashtag
lang:lang:ena language
min_faves:min_faves:100minimum likes

Query parameters​

ParameterTypeDefaultDescription
querystring—A full query with X operators (max 512 characters; over-length queries return 400 query_too_long). Omit to use the structured params below.
allstring[]—Every term must appear (AND).
anystring[]—At least one term must appear (OR).
nonestring[]—None of these terms may appear.
exactstring[]—Exact phrase(s), matched verbatim.
fromstring[]—Only posts from these accounts.
hashtagstring[]—Posts containing these hashtags.
langstring—Language code, e.g. en, tr.
min_likesinteger—Minimum like count.
productstringLatestTab to pull: Latest, Top, or Media.
sincedate or timestamp—Oldest point to reach. A date (YYYY-MM-DD) enables deep-history mode (see below); a full UTC timestamp (2024-01-01T14:30:00Z) applies second-precise filtering. Dates are interpreted in UTC.
untildate or timestamptodayNewest point to search — a date (YYYY-MM-DD) or a full UTC timestamp. Used with since.
window_daysinteger1Date-slice width for deep-history mode (smaller = deeper, more pages). Max 31.
max_pagesinteger1Pages to fetch (max 15). Each page ≈ 20 posts. To go further, send another request with the returned next_cursor. Billed per page.
cursorstring—Resume token from a previous response's next_cursor. Continues a standard search exactly where the last request stopped (ignored in deep-history mode).

Deep history​

A single X query only surfaces a shallow slice of recent posts. Set since to pull far deeper history: the service slides a date window backwards across [since, until], searching each slice with date operators, and deduplicates across windows. max_pages then caps the total pages fetched across all windows.

Paging further​

Each response returns a next_cursor. To continue a standard search beyond max_pages, send the same request again with cursor set to that value — it resumes exactly where the previous response stopped, with no gaps or duplicates. next_cursor is null once results are exhausted. (Deep-history since-date searches page by date window instead and do not return a cursor.)

curl -G "$LISTENX_BASE/v1/x/search" \
-H "X-API-Key: $LISTENX_KEY" \
--data-urlencode 'query=tesla min_faves:50' \
--data-urlencode 'max_pages=10' \
--data-urlencode 'cursor=PASTE_NEXT_CURSOR_HERE'

Precise time window​

Give since/until full UTC timestamps (instead of dates) to filter to an exact, second-precise window — useful for incremental polling. Timestamps run a standard search (with cursor), not deep-history windowing.

curl -G "$LISTENX_BASE/v1/x/search" \
-H "X-API-Key: $LISTENX_KEY" \
--data-urlencode 'query=tesla' \
--data-urlencode 'since=2026-10-23T09:00:00Z' \
--data-urlencode 'until=2026-10-23T12:00:00Z'

Long or non-Latin queries (POST)​

When a query is long or has many non-Latin keywords that inflate once URL-encoded, send it in the JSON body with POST /v1/x/search to avoid the request-URL length limit. The body accepts the same fields as the query parameters; the 512-character query limit still applies.

curl -X POST "$LISTENX_BASE/v1/x/search" \
-H "X-API-Key: $LISTENX_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "特斯拉 OR 比亚迪 min_faves:50", "max_pages": 5}'

Examples​

Boolean query with operators:

curl -G "$LISTENX_BASE/v1/x/search" \
-H "X-API-Key: $LISTENX_KEY" \
--data-urlencode 'query=tesla (model3 OR modely) -recall min_faves:50' \
--data-urlencode 'max_pages=3'

Structured boolean params:

curl -G "$LISTENX_BASE/v1/x/search" \
-H "X-API-Key: $LISTENX_KEY" \
--data-urlencode 'all=tesla' \
--data-urlencode 'any=model3' --data-urlencode 'any=modely' \
--data-urlencode 'none=recall' \
--data-urlencode 'lang=en'

Deep history over a date range:

curl -G "$LISTENX_BASE/v1/x/search" \
-H "X-API-Key: $LISTENX_KEY" \
--data-urlencode 'query=from:nasa artemis' \
--data-urlencode 'since=2024-01-01' \
--data-urlencode 'until=2024-02-01' \
--data-urlencode 'window_days=3' \
--data-urlencode 'max_pages=20'

Response​

{
"query": "tesla (model3 OR modely) -recall min_faves:50",
"product": "Latest",
"pages_requested": 3,
"pages_fetched": 3,
"returned": 54,
"next_cursor": "DAABCgAB...",
"fetched_at": "2026-10-30T12:00:00+00:00",
"results": [
{
"id": "1234567890123456789",
"created_at": "Mon Oct 27 10:00:00 +0000 2025",
"text": "The Model 3 refresh is excellent …",
"lang": "en",
"type": "post",
"url": "https://x.com/example/status/1234567890123456789",
"is_quote": false,
"metrics": {
"replies": 12, "retweets": 30, "likes": 240,
"quotes": 4, "bookmarks": 18, "views": 15400
},
"entities": {
"hashtags": ["Tesla"], "symbols": ["TSLA"],
"mentions": ["Tesla"], "urls": ["https://…"]
},
"media": [
{ "type": "photo", "media_url": "https://…", "alt_text": null }
],
"author": {
"id": "44196397", "screen_name": "example", "name": "Example",
"verified": false, "blue_verified": true,
"followers": 10500, "following": 300, "tweets": 8700
}
}
],
"billing": { "endpoint": "x.search", "units": 3, "unit_price": "0.010000", "amount": "0.030000", "balance_after": "97.00", "request_id": "…" }
}

fetched_at is the UTC timestamp when the result set was captured — engagement metrics are a snapshot from that moment, so use it to compare the same post across requests over time. For a deep-history request the response also carries since, until, window_days, and windows_searched.

Billing​

Search is billed per page fetched — units = pages_fetched, minimum 1. In deep-history mode this is the total pages across all date windows. See Billing.

Notes​

  • To pull a single post's full record, call the post endpoint with a result's id or url.
  • Search is a discovery surface; results are not exhaustive and can shift over time.