---
title: "Search public X posts with composable filters"
method: POST
path: "/v1/x/search"
tags: ["X"]
---

# Search public X posts with composable filters

`POST /v1/x/search`

## Request

- Base URL: `https://api.weirapp.io`
- URL: `https://api.weirapp.io/v1/x/search`
- Auth: HTTP bearer

Searches public X (Twitter) posts by keyword, phrase, account, hashtag, language, date and engagement. 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.

## Request body

- object
  - `query` string: Words that must all appear, in any order. X search operators pass through as typed, so filters without a field of their own work here: `filter:media`, `url:example.com`, `conversation_id:123`, `-filter:replies`.
  - `phrase` string: An exact phrase that must appear.
  - `anyWords` string[]: At least one of these words must appear.
  - `excludeWords` string[]: None of these words may appear.
  - `hashtags` string[]: Any of these hashtags, with or without the `#`.
  - `fromUsers` string[]: Posted by any of these usernames.
  - `toUsers` string[]: Replying to any of these usernames.
  - `mentions` string[]: Mentioning any of these usernames.
  - `language` string: Language X detected, as a BCP-47 tag such as `en`.
  - `minLikes` integer
  - `minReplies` integer
  - `minReposts` integer
  - `onlyLinks` boolean: Only posts containing a link.
  - `onlyOriginal` boolean: Exclude replies.
  - `onlyReplies` boolean: Only replies.
  - `onlyText` boolean: Exclude posts with links.
  - `since` string, date-time: Posted at or after this instant (UTC).
  - `until` string, date-time: Posted before this instant (UTC).
  - `quotedPostId` string: Only posts quoting this post. `getXQuotes` is the dedicated endpoint for this.
  - `listId` string: Only posts by members of this public List.
  - `sinceId` string: Only posts newer than this post id, exclusive. The way to resume a feed: pass the newest id already seen.
  - `untilId` string: Only posts older than this post id, exclusive.
  - `sort` 'latest' | 'top': `latest` is newest first; `top` is X's own engagement ranking.
  - `limit` integer: Most posts to return. X serves about 20 per page at most.
  - `cursor` string: 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.

## Response `200`

X posts, in X's own field names.

- object
  - `data` object[], required
    - `id` string, required: Numeric post id, as a string. It exceeds 2^53.
    - `text` string, required: Full post text, untruncated.
    - `url` string, required
    - `lang` string, nullable, required: BCP-47 language tag detected by X.
    - `createdAt` string, date-time, required
    - `conversationId` string, nullable, required: The thread this post belongs to.
    - `inReplyToId` string, nullable, required
    - `author` object, required
      - `id` string, required
      - `username` string, required
      - `name` string, required
      - `verified` boolean, required
      - `followersCount` integer, required
      - `profileImageUrl` string, nullable, required
    - `likeCount` integer, nullable, required
    - `retweetCount` integer, nullable, required
    - `replyCount` integer, nullable, required
    - `viewCount` integer, nullable, required
    - `quoteCount` integer, nullable, required
    - `bookmarkCount` integer, nullable, required
    - `media` object[], required: Attached photos, videos, and GIFs, in display order.
      - `id` string, required
      - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
      - `url` string, nullable, required: The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
      - `previewImageUrl` string, nullable, required: Poster frame for a video. Null for photos and GIFs.
    - `entities` object, required
      - `hashtags` string[], required: Hashtags, without the `#`.
      - `mentions` string[], required: Mentioned usernames, without the `@`.
      - `urls` string[], required: Expanded link targets, not t.co short links.
    - `article` object, nullable, required: Set when the post is an X Article; its `text` is then only a link to it.
      - `id` string, required: The Article's own id, distinct from the id of the post carrying it.
      - `url` string, required
      - `title` string, required
      - `previewText` string, nullable, required: The opening lines X shows in a feed.
      - `coverImage` object, nullable, required
        - `id` string, required: X's media id; blocks refer to media by this id.
        - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
        - `url` string, nullable, required: The original image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
        - `width` integer, nullable, required
        - `height` integer, nullable, required
      - `publishedAt` string, date-time, nullable, required
      - `updatedAt` string, date-time, nullable, required
      - `text` string, nullable, required: The full body as plain text. Null in lists of posts, where X sends only the preview: get the post, or its article, for the body.
      - `markdown` string, nullable, required: The full body as Markdown — headings, emphasis, lists, quotes, code, links, images, and embedded posts — for reading or for a model. Null wherever `text` is.
      - `blocks` object[], nullable, required: The body in X's own block structure. Null wherever `text` is.
        - `type` string, required: X's block type: `unstyled` (paragraph), `header-one`, `header-two`, `header-three`, `unordered-list-item`, `ordered-list-item`, `blockquote`, `code-block`, or `atomic` (an embed: see `entities`).
        - `text` string, required
        - `depth` integer, required: Nesting level for list items; 0 otherwise.
        - `styles` object[], required: Inline styles over spans of `text`.
          - `offset` integer, required: Start, in UTF-16 code units of `text`.
          - `length` integer, required
          - `style` string, required: X's inline style name: `Bold`, `Italic`, `Strikethrough`, …
        - `entities` object[], required: Links and embeds attached to spans of `text`.
          - `offset` integer, required: Start, in UTF-16 code units of `text`.
          - `length` integer, required
          - `type` string, required: X's entity type: `LINK`, `MEDIA`, `TWEET` (an embedded post), `DIVIDER`, `MARKDOWN` (a code or formatted snippet), or another X adds later.
          - `url` string, nullable, required: The target of a `LINK`.
          - `mediaIds` string[], required: For `MEDIA`: ids into the Article's `media` list, in display order.
          - `postId` string, nullable, required: For `TWEET`: the embedded post's id.
          - `markdown` string, nullable, required: For `MARKDOWN`: the snippet's source.
      - `media` object[], required: Images and videos in the body, in order. Empty in lists of posts.
        - `id` string, required: X's media id; blocks refer to media by this id.
        - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
        - `url` string, nullable, required: The original image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
        - `width` integer, nullable, required
        - `height` integer, nullable, required
    - `quotedPost` object, nullable, required: The post this one quotes, when it is a quote post.
      - `id` string, required: Numeric post id, as a string. It exceeds 2^53.
      - `text` string, required: Full post text, untruncated.
      - `url` string, required
      - `lang` string, nullable, required: BCP-47 language tag detected by X.
      - `createdAt` string, date-time, required
      - `conversationId` string, nullable, required: The thread this post belongs to.
      - `inReplyToId` string, nullable, required
      - `author` object, required
        - `id` string, required
        - `username` string, required
        - `name` string, required
        - `verified` boolean, required
        - `followersCount` integer, required
        - `profileImageUrl` string, nullable, required
      - `likeCount` integer, nullable, required
      - `retweetCount` integer, nullable, required
      - `replyCount` integer, nullable, required
      - `viewCount` integer, nullable, required
      - `quoteCount` integer, nullable, required
      - `bookmarkCount` integer, nullable, required
      - `media` object[], required: Attached photos, videos, and GIFs, in display order.
        - `id` string, required
        - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
        - `url` string, nullable, required: The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
        - `previewImageUrl` string, nullable, required: Poster frame for a video. Null for photos and GIFs.
      - `entities` object, required
        - `hashtags` string[], required: Hashtags, without the `#`.
        - `mentions` string[], required: Mentioned usernames, without the `@`.
        - `urls` string[], required: Expanded link targets, not t.co short links.
      - `article` object, nullable, required: Set when the post is an X Article; its `text` is then only a link to it.
        - `id` string, required: The Article's own id, distinct from the id of the post carrying it.
        - `url` string, required
        - `title` string, required
        - `previewText` string, nullable, required: The opening lines X shows in a feed.
        - `coverImage` object, nullable, required
          - `id` string, required: X's media id; blocks refer to media by this id.
          - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
          - `url` string, nullable, required: The original image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
          - `width` integer, nullable, required
          - `height` integer, nullable, required
        - `publishedAt` string, date-time, nullable, required
        - `updatedAt` string, date-time, nullable, required
        - `text` string, nullable, required: The full body as plain text. Null in lists of posts, where X sends only the preview: get the post, or its article, for the body.
        - `markdown` string, nullable, required: The full body as Markdown — headings, emphasis, lists, quotes, code, links, images, and embedded posts — for reading or for a model. Null wherever `text` is.
        - `blocks` object[], nullable, required: The body in X's own block structure. Null wherever `text` is.
          - `type` string, required: X's block type: `unstyled` (paragraph), `header-one`, `header-two`, `header-three`, `unordered-list-item`, `ordered-list-item`, `blockquote`, `code-block`, or `atomic` (an embed: see `entities`).
          - `text` string, required
          - `depth` integer, required: Nesting level for list items; 0 otherwise.
          - `styles` object[], required: Inline styles over spans of `text`.
            - `offset` integer, required: Start, in UTF-16 code units of `text`.
            - `length` integer, required
            - `style` string, required: X's inline style name: `Bold`, `Italic`, `Strikethrough`, …
          - `entities` object[], required: Links and embeds attached to spans of `text`.
            - `offset` integer, required: Start, in UTF-16 code units of `text`.
            - `length` integer, required
            - `type` string, required: X's entity type: `LINK`, `MEDIA`, `TWEET` (an embedded post), `DIVIDER`, `MARKDOWN` (a code or formatted snippet), or another X adds later.
            - `url` string, nullable, required: The target of a `LINK`.
            - `mediaIds` string[], required: For `MEDIA`: ids into the Article's `media` list, in display order.
            - `postId` string, nullable, required: For `TWEET`: the embedded post's id.
            - `markdown` string, nullable, required: For `MARKDOWN`: the snippet's source.
        - `media` object[], required: Images and videos in the body, in order. Empty in lists of posts.
          - `id` string, required: X's media id; blocks refer to media by this id.
          - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
          - `url` string, nullable, required: The original image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
          - `width` integer, nullable, required
          - `height` integer, nullable, required
    - `retweetedPost` object, nullable, required: 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: …`.
      - `id` string, required: Numeric post id, as a string. It exceeds 2^53.
      - `text` string, required: Full post text, untruncated.
      - `url` string, required
      - `lang` string, nullable, required: BCP-47 language tag detected by X.
      - `createdAt` string, date-time, required
      - `conversationId` string, nullable, required: The thread this post belongs to.
      - `inReplyToId` string, nullable, required
      - `author` object, required
        - `id` string, required
        - `username` string, required
        - `name` string, required
        - `verified` boolean, required
        - `followersCount` integer, required
        - `profileImageUrl` string, nullable, required
      - `likeCount` integer, nullable, required
      - `retweetCount` integer, nullable, required
      - `replyCount` integer, nullable, required
      - `viewCount` integer, nullable, required
      - `quoteCount` integer, nullable, required
      - `bookmarkCount` integer, nullable, required
      - `media` object[], required: Attached photos, videos, and GIFs, in display order.
        - `id` string, required
        - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
        - `url` string, nullable, required: The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
        - `previewImageUrl` string, nullable, required: Poster frame for a video. Null for photos and GIFs.
      - `entities` object, required
        - `hashtags` string[], required: Hashtags, without the `#`.
        - `mentions` string[], required: Mentioned usernames, without the `@`.
        - `urls` string[], required: Expanded link targets, not t.co short links.
      - `article` object, nullable, required: Set when the post is an X Article; its `text` is then only a link to it.
        - `id` string, required: The Article's own id, distinct from the id of the post carrying it.
        - `url` string, required
        - `title` string, required
        - `previewText` string, nullable, required: The opening lines X shows in a feed.
        - `coverImage` object, nullable, required
          - `id` string, required: X's media id; blocks refer to media by this id.
          - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
          - `url` string, nullable, required: The original image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
          - `width` integer, nullable, required
          - `height` integer, nullable, required
        - `publishedAt` string, date-time, nullable, required
        - `updatedAt` string, date-time, nullable, required
        - `text` string, nullable, required: The full body as plain text. Null in lists of posts, where X sends only the preview: get the post, or its article, for the body.
        - `markdown` string, nullable, required: The full body as Markdown — headings, emphasis, lists, quotes, code, links, images, and embedded posts — for reading or for a model. Null wherever `text` is.
        - `blocks` object[], nullable, required: The body in X's own block structure. Null wherever `text` is.
          - `type` string, required: X's block type: `unstyled` (paragraph), `header-one`, `header-two`, `header-three`, `unordered-list-item`, `ordered-list-item`, `blockquote`, `code-block`, or `atomic` (an embed: see `entities`).
          - `text` string, required
          - `depth` integer, required: Nesting level for list items; 0 otherwise.
          - `styles` object[], required: Inline styles over spans of `text`.
            - `offset` integer, required: Start, in UTF-16 code units of `text`.
            - `length` integer, required
            - `style` string, required: X's inline style name: `Bold`, `Italic`, `Strikethrough`, …
          - `entities` object[], required: Links and embeds attached to spans of `text`.
            - `offset` integer, required: Start, in UTF-16 code units of `text`.
            - `length` integer, required
            - `type` string, required: X's entity type: `LINK`, `MEDIA`, `TWEET` (an embedded post), `DIVIDER`, `MARKDOWN` (a code or formatted snippet), or another X adds later.
            - `url` string, nullable, required: The target of a `LINK`.
            - `mediaIds` string[], required: For `MEDIA`: ids into the Article's `media` list, in display order.
            - `postId` string, nullable, required: For `TWEET`: the embedded post's id.
            - `markdown` string, nullable, required: For `MARKDOWN`: the snippet's source.
        - `media` object[], required: Images and videos in the body, in order. Empty in lists of posts.
          - `id` string, required: X's media id; blocks refer to media by this id.
          - `type` 'photo' | 'video' | 'animated_gif', required: X's own media type names.
          - `url` string, nullable, required: The original image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream.
          - `width` integer, nullable, required
          - `height` integer, nullable, required
  - `meta` object, required
    - `requestId` string, required
    - `nextCursor` string, nullable

## Other responses

- `400`: The request failed validation.
- `401`: The API key is missing, malformed, expired, or revoked.
- `402`: The account is out of credit. Not retryable: this cannot clear until the billing period resets or the plan changes.
- `403`: The API key does not carry the scope this route requires.
- `404`: The requested resource does not exist.
- `429`: The per-minute rate limit is exhausted. Retryable: wait for Retry-After and try again.
- `500`: An unexpected error occurred.
- `503`: The source is temporarily unavailable. The request is safe to retry.

---

[API](https://skmtc.dev/weirapp/apis/weir-api.md) · [All operations](https://skmtc.dev/weirapp/apis/weir-api/llms.txt) · [OpenAPI document](https://skmtc.dev/weirapp/apis/weir-api/revisions/4c6a9ae0bfca?raw)
