Search public X posts with composable filters

POST /v1/x/search

Searches public posts. Every filter narrows the result, and at least one of query, phrase, hashtags, fromUsers, toUsers, mentions, listId, or quotedPostId is required. Paginate with meta.nextCursor. Billed per post returned.

Price: 1 credit per call, plus 1 credit per X post returned. Failed and refused calls cost nothing.

Rate limit: Counts as 2 requests against your per-minute rate limit.

MCP tool: search_x, on every MCP connection.

Requires an API key, sent as Authorization: Bearer <key>.

Request

curl --request POST \
  --url https://api.weirapp.io/v1/x/search \
  --header "Authorization: Bearer $WEIR_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'

Body

Field Type Required Notes
query string no Words that must all appear, in any order. · 1–200 chars
phrase string no An exact phrase that must appear. · 1–200 chars
anyWords array of string no At least one of these words must appear.
excludeWords array of string no None of these words may appear.
hashtags array of string no Any of these hashtags, with or without the #.
fromUsers array of string no Posted by any of these usernames.
toUsers array of string no Replying to any of these usernames.
mentions array of string no Mentioning any of these usernames.
language string no Language X detected, as a BCP-47 tag such as en. · 2–12 chars
minLikes integer no min 0
minReplies integer no min 0
minReposts integer no min 0
onlyLinks boolean no Only posts containing a link.
onlyOriginal boolean no Exclude replies.
onlyReplies boolean no Only replies.
onlyText boolean no Exclude posts with links.
since string (date-time) no Posted at or after this instant (UTC).
until string (date-time) no Posted before this instant (UTC).
quotedPostId string no Only posts quoting this post. getXQuotes is the dedicated endpoint for this. · matches ^\d{1,19}$
listId string no Only posts by members of this public List. · matches ^\d{1,19}$
sinceId string no Only posts newer than this post id, exclusive. The way to resume a feed: pass the newest id already seen. · matches ^\d{1,19}$
untilId string no Only posts older than this post id, exclusive. · matches ^\d{1,19}$
sort string no latest is newest first; top is X's own engagement ranking. · latest, top, default "latest"
limit integer no Most posts to return. X serves about 20 per page at most. · 1–100, default 25
cursor string no Opaque cursor from the previous page's meta.nextCursor. Pass it back unchanged, with the same path and query parameters; a cursor from another request is rejected with 400. · 1–4096 chars

Response

X posts, in X's own field names.

200

Field Type Required Notes
data array of object yes
data[].id string yes Numeric post id, as a string. It exceeds 2^53.
data[].text string yes Full post text, untruncated.
data[].url string yes
data[].lang string or null yes BCP-47 language tag detected by X.
data[].createdAt string (date-time) yes
data[].conversationId string or null yes The thread this post belongs to.
data[].inReplyToId string or null yes
data[].author object yes
data[].author.id string yes
data[].author.username string yes
data[].author.name string yes
data[].author.verified boolean yes
data[].author.followersCount integer yes min 0
data[].author.profileImageUrl string or null yes
data[].likeCount integer or null yes min 0
data[].retweetCount integer or null yes min 0
data[].replyCount integer or null yes min 0
data[].viewCount integer or null yes min 0
data[].quoteCount integer or null yes min 0
data[].bookmarkCount integer or null yes min 0
data[].media array of object yes Attached photos, videos, and GIFs, in display order.
data[].media[].id string yes
data[].media[].type string yes X's own media type names. · photo, video, animated_gif
data[].media[].url string or null yes The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
data[].media[].previewImageUrl string or null yes Poster frame for a video. Null for photos and GIFs.
data[].entities object yes
data[].entities.hashtags array of string yes Hashtags, without the #.
data[].entities.mentions array of string yes Mentioned usernames, without the @.
data[].entities.urls array of string yes Expanded link targets, not t.co short links.
data[].quotedPost object or null yes The post this one quotes, when it is a quote post.
data[].quotedPost.id string yes Numeric post id, as a string. It exceeds 2^53.
data[].quotedPost.text string yes Full post text, untruncated.
data[].quotedPost.url string yes
data[].quotedPost.lang string or null yes BCP-47 language tag detected by X.
data[].quotedPost.createdAt string (date-time) yes
data[].quotedPost.conversationId string or null yes The thread this post belongs to.
data[].quotedPost.inReplyToId string or null yes
data[].quotedPost.author object yes
data[].quotedPost.author.id string yes
data[].quotedPost.author.username string yes
data[].quotedPost.author.name string yes
data[].quotedPost.author.verified boolean yes
data[].quotedPost.author.followersCount integer yes min 0
data[].quotedPost.author.profileImageUrl string or null yes
data[].quotedPost.likeCount integer or null yes min 0
data[].quotedPost.retweetCount integer or null yes min 0
data[].quotedPost.replyCount integer or null yes min 0
data[].quotedPost.viewCount integer or null yes min 0
data[].quotedPost.quoteCount integer or null yes min 0
data[].quotedPost.bookmarkCount integer or null yes min 0
data[].quotedPost.media array of object yes Attached photos, videos, and GIFs, in display order.
data[].quotedPost.media[].id string yes
data[].quotedPost.media[].type string yes X's own media type names. · photo, video, animated_gif
data[].quotedPost.media[].url string or null yes The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
data[].quotedPost.media[].previewImageUrl string or null yes Poster frame for a video. Null for photos and GIFs.
data[].quotedPost.entities object yes
data[].quotedPost.entities.hashtags array of string yes Hashtags, without the #.
data[].quotedPost.entities.mentions array of string yes Mentioned usernames, without the @.
data[].quotedPost.entities.urls array of string yes Expanded link targets, not t.co short links.
data[].retweetedPost object or null yes Set when this post is a repost. Read the original's text and counts here: X truncates a repost's own text to RT @user: ….
data[].retweetedPost.id string yes Numeric post id, as a string. It exceeds 2^53.
data[].retweetedPost.text string yes Full post text, untruncated.
data[].retweetedPost.url string yes
data[].retweetedPost.lang string or null yes BCP-47 language tag detected by X.
data[].retweetedPost.createdAt string (date-time) yes
data[].retweetedPost.conversationId string or null yes The thread this post belongs to.
data[].retweetedPost.inReplyToId string or null yes
data[].retweetedPost.author object yes
data[].retweetedPost.author.id string yes
data[].retweetedPost.author.username string yes
data[].retweetedPost.author.name string yes
data[].retweetedPost.author.verified boolean yes
data[].retweetedPost.author.followersCount integer yes min 0
data[].retweetedPost.author.profileImageUrl string or null yes
data[].retweetedPost.likeCount integer or null yes min 0
data[].retweetedPost.retweetCount integer or null yes min 0
data[].retweetedPost.replyCount integer or null yes min 0
data[].retweetedPost.viewCount integer or null yes min 0
data[].retweetedPost.quoteCount integer or null yes min 0
data[].retweetedPost.bookmarkCount integer or null yes min 0
data[].retweetedPost.media array of object yes Attached photos, videos, and GIFs, in display order.
data[].retweetedPost.media[].id string yes
data[].retweetedPost.media[].type string yes X's own media type names. · photo, video, animated_gif
data[].retweetedPost.media[].url string or null yes The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
data[].retweetedPost.media[].previewImageUrl string or null yes Poster frame for a video. Null for photos and GIFs.
data[].retweetedPost.entities object yes
data[].retweetedPost.entities.hashtags array of string yes Hashtags, without the #.
data[].retweetedPost.entities.mentions array of string yes Mentioned usernames, without the @.
data[].retweetedPost.entities.urls array of string yes Expanded link targets, not t.co short links.
meta object yes
meta.requestId string yes
meta.nextCursor string or null no

Errors

Status Meaning What to do
400 The request failed validation. The request was malformed. The details object names the field.
401 The API key is missing, malformed, expired, or revoked. The key is missing, malformed, revoked, or expired.
402 The account is out of credit. Not retryable: this cannot clear until the billing period resets or the plan changes. Out of credits. Never retry. Only a person can clear it, by adding credits at https://weirapp.io/dashboard/billing. Retrying never will.
403 The API key does not carry the scope this route requires. The key is valid but lacks the scope this operation needs.
404 The requested resource does not exist. No such resource, or it is not public.
429 The per-minute rate limit is exhausted. Retryable: wait for Retry-After and try again. Rate limited. Retryable: wait for Retry-After, then try again.
500 An unexpected error occurred. Something failed on our side. Retryable with backoff.
503 The source is temporarily unavailable. The request is safe to retry. A source was unreachable. Retryable with backoff.

View this page as Markdown