> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xquik.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Twitter community search API & keyword tweet results

> Search posts inside one known X (Twitter) community by keyword. Export matching tweets, authors, replies, reposts, likes, media, and cursor pages for reviews.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-community-search-200">
      ```json theme={null}
      {
        "tweets": [],
        "has_next_page": false,
        "next_cursor": ""
      }
      ```
    </Tab>

    <Tab title="400" id="response-x-community-search-400">
      ```json theme={null}
      {
        "error": "invalid_input",
        "message": "Invalid input. Check the request body."
      }
      ```
    </Tab>

    <Tab title="401" id="response-x-community-search-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required."
      }
      ```
    </Tab>

    <Tab title="402" id="response-x-community-search-402">
      ```json theme={null}
      {
        "error": "insufficient_credits",
        "message": "Insufficient credits. Top up or subscribe to continue."
      }
      ```
    </Tab>

    <Tab title="424" id="response-x-community-search-424">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "X data source temporarily unavailable. Try again later."
      }
      ```
    </Tab>

    <Tab title="429" id="response-x-community-search-429">
      ```json theme={null}
      {
        "error": "rate_limit_exceeded",
        "message": "Too many requests. Try again later.",
        "retryAfter": 60
      }
      ```
    </Tab>

    <Tab title="502" id="response-x-community-search-502">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "X data source temporarily unavailable. Try again later."
      }
      ```
    </Tab>

    <Tab title="503" id="response-x-community-search-503">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "Xquik is busy right now. Retry shortly."
      }
      ```
    </Tab>
  </Tabs>
</Panel>

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

<ParamField query="fromUser" type="string">
  Filter to posts from this username. The `@` prefix is optional.
</ParamField>

<ParamField query="toUser" type="string">
  Filter to replies directed to this username.
</ParamField>

<ParamField query="mentioning" type="string">
  Filter to posts that mention this username.
</ParamField>

<ParamField query="language" type="string">
  Only include posts with this language code.
</ParamField>

<ParamField query="sinceDate" type="string">
  Include posts created on or after this date or timestamp.
</ParamField>

<ParamField query="untilDate" type="string">
  Include posts up to this date or timestamp. A date is a UTC day, inclusive, so its own posts count.
</ParamField>

<ParamField query="mediaType" type="string">
  Use `images`, `videos`, `gifs`, `media`, `links`, or `none`.
</ParamField>

<ParamField query="minLikes" type="integer">
  Require this minimum like count.
</ParamField>

<ParamField query="minRetweets" type="integer">
  Require this minimum repost count.
</ParamField>

<ParamField query="minReplies" type="integer">
  Require this minimum reply count.
</ParamField>

<ParamField query="minQuotes" type="integer">
  Require this minimum quote count.
</ParamField>

<ParamField query="minViews" type="integer">
  Require this minimum view count.
</ParamField>

<ParamField query="minBookmarks" type="integer">
  Require this minimum bookmark count.
</ParamField>

<ParamField query="maxFaves" type="integer">
  Allow this maximum like count. Missing counts pass.
</ParamField>

<ParamField query="maxRetweets" type="integer">
  Allow this maximum repost count. Missing counts pass.
</ParamField>

<ParamField query="maxReplies" type="integer">
  Allow this maximum reply count. Missing counts pass.
</ParamField>

<ParamField query="maxQuotes" type="integer">
  Allow this maximum quote count. Missing counts pass.
</ParamField>

<ParamField query="blueVerifiedOnly" type="boolean">
  When `true`, only return posts from Blue-verified authors.
</ParamField>

<ParamField query="verifiedOnly" type="boolean">
  When `true`, only return posts from verified authors.
</ParamField>

<ParamField query="replies" type="string">
  Use `include`, `exclude`, or `only` for replies.
  This setting overrides `includeReplies` when the endpoint supports both.
</ParamField>

<ParamField query="retweets" type="string">
  Use `include`, `exclude`, or `only` for reposts.
</ParamField>

<ParamField query="exactPhrase" type="string">
  Match this literal phrase, including any hyphens.
</ParamField>

<ParamField query="excludeWords" type="string">
  Exclude comma-separated or whitespace-separated terms.
</ParamField>

<ParamField query="anyWords" type="string">
  Require at least 1 comma-separated or whitespace-separated term.
</ParamField>

<ParamField query="hashtags" type="string">
  Match these hashtags. Separate values with commas or spaces.
</ParamField>

<ParamField query="cashtags" type="string">
  Match these cashtags. Separate values with commas or spaces.
</ParamField>

<ParamField query="quotes" type="string">
  Use `include`, `exclude`, or `only` for quote posts.
</ParamField>

<ParamField query="url" type="string">
  URL substring or domain that must appear in tweet URL entities.
</ParamField>

<ParamField query="conversationId" type="string">
  Filter to tweets in this conversation thread.
</ParamField>

<ParamField query="inReplyToTweetId" type="string">
  Only include replies to this tweet ID.
</ParamField>

<ParamField query="quotesOfTweetId" type="string">
  Filter to quote tweets of this tweet ID.
</ParamField>

<ParamField query="retweetsOfTweetId" type="string">
  Filter to retweets of this tweet ID.
</ParamField>

<ParamField query="sinceId" type="string">
  Return Tweets whose IDs exceed this ID.
</ParamField>

<ParamField query="maxId" type="string">
  Return Tweets at or below this ID.
</ParamField>

<ParamField query="nativeRetweets" type="boolean">
  When `true`, only return native reposts.
</ParamField>

<ParamField query="withinTime" type="string">
  Match Tweets from this recent window, such as `90m` or `7d`. Use a whole number & `s`, `m`, `h` or `d`.
</ParamField>

Use Twitter community search to filter posts inside one known Community. Run a
Twitter search in community posts with a numeric Community ID and query. Store
Tweet IDs, authors, engagement counts, media, and cursors for exports.

## Filter one community by query

This endpoint requires a search expression. It filters one community. It does
not return the unfiltered feed. Keep the query beside every saved row.

| Search decision | Request field | Result boundary |
| - | - | - |
| Community scope | `communityId` | Search only the selected community. |
| Text filter | `q` | Return posts matching the exact search expression. |
| Ranking mode | `queryType=Latest` | Build a recent moderation or monitoring queue. |
| Ranking mode | `queryType=Top` | Build a relevance-ranked research set. |
| Continuation | `cursor` | Resume the same community, query, and ranking mode. |
| Saved export | `community_search` extraction | Produce CSV, JSON, or XLSX query results. |

Use the community tweets endpoint when no keyword filter is required.

## Twitter community search questions

### Does this endpoint find communities to join?

No. This endpoint searches posts after you provide a numeric Community ID. It
does not join Communities or change membership.

To find Communities by keyword, use [Find communities](/api-reference/x/community-find).
To browse Communities by topic, use [Popular communities](/api-reference/x/community-popular).
Read the official [X Communities guide](https://help.x.com/en/using-x/communities)
for current visibility and membership rules.

### How do I search community posts by keyword?

Send `communityId` and `q`. Omit `queryType` to use `Latest`. Set `Top` for
relevance-ranked matches.

Keep each cursor tied to the same values. Start a new search when the query
changes. Store the query beside every returned Tweet ID.

### Why does Twitter community search return no results?

First, verify the Community ID, query, and read visibility. An empty match set
differs from authentication, credit, dependency, rate-limit, or request errors.

Use the [Community Tweets API](/api-reference/x/community-tweets) to inspect the
visible, unfiltered feed. Zero matches do not prove an inactive Community.

### Can I find active authors in matching tweets?

Group matching posts by stable author ID. Count matches, replies, reposts,
likes, quotes, and views separately. Store follower counts with collection
times when returned.

These measures describe captured matches. They do not prove influence,
audience reach, Community membership, or total posting activity.

<Note>
  `GET /x/communities/search` and `GET /x/communities/tweets` accept the same
  community search parameters. This page documents both supported REST paths.
</Note>

Requested result counts are upper bounds for paid authenticated calls. When remaining credits cannot cover the full page or ID list, Xquik returns fewer results. If zero paid results are affordable, it returns `402 insufficient_credits`.

<Callout icon="coins" color="#5c3327">
  **1 credit per tweet returned** · [All plans](https://xquik.com/#pricing) from \$0.00012/credit
</Callout>

<CodeGroup>
  ```bash cURL theme={null}
  curl -G https://xquik.com/api/v1/x/communities/search \
    --data-urlencode "communityId=1234567890" \
    --data-urlencode "q=web development" \
    -H "x-api-key: xq_your_api_key_here" | jq
  ```

  ```javascript Node.js theme={null}
  const communityId = "1234567890";
  const searchQuery = "web development";
  const queryType = "Latest";
  const pageSize = "100";
  const params = new URLSearchParams({ communityId, q: searchQuery, queryType, pageSize });
  const response = await fetch(`https://xquik.com/api/v1/x/communities/search?${params}`, {
    headers: { "x-api-key": "xq_your_api_key_here" },
  });
  const data = await response.json();
  const tweetRows = data.tweets.map((tweet) => {
    const author = tweet.author ?? {};

    return {
      community_id: communityId,
      search_query: searchQuery,
      query_type: queryType,
      tweet_id: tweet.id,
      text: tweet.text,
      author_id: author.id ?? null,
      author_username: author.username ?? null,
      author_name: author.name ?? null,
      author_followers: author.followers ?? null,
      author_verified: author.verified ?? null,
      author_profile_picture: author.profilePicture ?? null,
      created_at: tweet.createdAt ?? null,
      like_count: tweet.likeCount ?? null,
      reply_count: tweet.replyCount ?? null,
      retweet_count: tweet.retweetCount ?? null,
      media_urls: tweet.media?.map((item) => item.mediaUrl).filter(Boolean) ?? [],
    };
  });
  const nextCursor = data.has_next_page ? data.next_cursor : null;

  for (const row of tweetRows) {
    process.stdout.write(`${JSON.stringify(row)}\n`);
  }
  if (nextCursor !== null) {
    const checkpoint = {
      community_id: communityId,
      search_query: searchQuery,
      query_type: queryType,
      page_size: Number(pageSize),
      next_cursor: nextCursor,
    };
    process.stdout.write(`${JSON.stringify(checkpoint)}\n`);
  }
  ```

  ```python Python theme={null}
  import json
  import requests

  community_id = "1234567890"
  search_query = "web development"
  query_type = "Latest"
  page_size = 100
  response = requests.get(
      "https://xquik.com/api/v1/x/communities/search",
      params={
          "communityId": community_id,
          "q": search_query,
          "queryType": query_type,
          "pageSize": page_size,
      },
      headers={"x-api-key": "xq_your_api_key_here"},
  )
  data = response.json()
  tweet_rows = []
  for tweet in data["tweets"]:
      author = tweet.get("author") or {}
      tweet_rows.append(
          {
              "community_id": community_id,
              "search_query": search_query,
              "query_type": query_type,
              "tweet_id": tweet["id"],
              "text": tweet.get("text"),
              "author_id": author.get("id"),
              "author_username": author.get("username"),
              "author_name": author.get("name"),
              "author_followers": author.get("followers"),
              "author_verified": author.get("verified"),
              "author_profile_picture": author.get("profilePicture"),
              "created_at": tweet.get("createdAt"),
              "like_count": tweet.get("likeCount"),
              "reply_count": tweet.get("replyCount"),
              "retweet_count": tweet.get("retweetCount"),
              "media_urls": [
                  item["mediaUrl"]
                  for item in tweet.get("media", [])
                  if item.get("mediaUrl")
              ],
          }
      )

  next_cursor = data["next_cursor"] if data["has_next_page"] else None

  for row in tweet_rows:
      print(json.dumps(row))
  if next_cursor is not None:
      print(json.dumps({
          "community_id": community_id,
          "search_query": search_query,
          "query_type": query_type,
          "page_size": page_size,
          "next_cursor": next_cursor,
      }))
  ```
</CodeGroup>

The Node.js & Python snippets build one row per matching community
tweet. They do not print the full response page. Store the final
`next_cursor` row when `has_next_page` is true, then pass it back as `cursor`
with the same `communityId`, `q`, `queryType`, and `pageSize`.

## Direct community search handoff

Use `GET /x/communities/search` when a monitoring job, research queue,
moderation review, social listening workflow, or agent needs matching tweets
from one known X community.

Store `community_id`, `search_query`, `query_type`, `tweet_id`, `text`, `author_id`,
`author_username`, `author_name`, `author_followers`, `author_verified`,
`author_profile_picture`, `created_at`, engagement counts, & `media_urls` for
each row. Keep
`has_next_page` & `next_cursor` with the export checkpoint. The next run can
then continue the same scoped search without duplicating earlier rows.

Set `queryType=Latest` for recent queues or backfills. Set `queryType=Top` for
relevance-ranked review.

<CardGroup cols={2}>
  <Card title="Search row checkpoint" icon="search">
    Store `community_id`, `search_query`, `query_type`, `page_size`,
    `has_next_page`, and `next_cursor` with the tweet rows.
  </Card>

  <Card title="Sort mode" icon="arrow-down-up">
    Use `Latest` for recent collection and `Top` for relevance-ranked review.
    Keep the same `queryType` when you pass a cursor.
  </Card>

  <Card title="Default page" icon="rows-3">
    Request 1 to 100 tweets with `pageSize`. The default is 20. The value
    is an upper bound because filters, source results, or credits can return fewer.
  </Card>

  <Card title="Saved export" icon="file-spreadsheet">
    Use `community_search` with `targetCommunityId` and `searchQuery` when the
    workflow needs a saved job with CSV, JSON, or XLSX output.
  </Card>
</CardGroup>

## Plan a community search export

Choose this route for repeatable research across one known community. Define
the question before choosing the query. A narrow query returns fewer irrelevant tweet
rows to review.

Start each export with these values:

* The numeric community ID.
* The exact search expression.
* Either `Latest` or `Top`.
* A stable page size.
* The time when collection started.

Keep those values beside every saved cursor. Resume with the same values.
Changing the query during pagination starts a different result set.

Use `Latest` for incident review, event coverage, and recent topic monitoring.
Use `Top` for relevance-ranked discovery. Do not combine both orders inside one
export file. Create separate exports when reviewers need both orders.

Normalize each tweet into named columns. Useful columns include tweet ID,
text, author username, creation time, likes, replies, reposts, and media URLs.
Keep the community ID and query on every row. Those columns keep context
after CSV or XLSX handoff.

Stop when `has_next_page` becomes false. Store the final checkpoint with the
row count. Deduplicate resumed exports by tweet ID. A worker that retries the last completed page
then adds no duplicate spreadsheet rows.

## Write precise community queries

Use concrete terms that match the research question. Combine keywords with
supported search operators when required. Test the first page before starting
a large export.

For moderation, search the specific phrase or hashtag under review. For
research, separate broad themes into independent queries. For event coverage,
record the chosen sort order and collection time.

Avoid changing `q` after receiving a cursor. Start a new search. Each
cursor then belongs to one result set.

## Validate a completed research file

Count unique tweet IDs after the final page. Compare that count with the
written row count. Any difference means repeated rows.

Check that every row carries the same community ID, query, and sort mode.
Reject a mixed file before analyst handoff. Keep media URLs as arrays or
separate child rows.

Write a short export manifest. Include collection time, page count, unique
tweet count, final cursor state, and output format. A reader can then understand the CSV or XLSX
file without the original job logs.

When a run stops early, label it partial. Keep the last saved cursor to
resume. Do not present a partial export as the community's complete search
result.

## Schedule independent searches

Give every community-and-query pair its own checkpoint. Never share cursors
between 2 terms.

Run urgent moderation searches more frequently than broad research queries.
Record the schedule beside the export manifest.

If a query changes, start a new series. Compare only
runs that used the same query.

Use separate output names for each community. Include a short query slug and
collection date. Keep the full query inside the manifest.

Archive successful manifests beside their CSV, JSON, or XLSX files. Another
analyst can then reproduce the search parameters without opening application
logs.

Version the manifest when a query changes. Do not edit earlier exports.
Comparisons between research periods depend on them.

## Compare latest and top results without mixing datasets

Run `Latest` and `Top` as independent searches when research needs both views.
The 2 orders rank different tweets first and may return overlapping tweets.

Give each run its own manifest, cursor chain, and output file. Keep the same
community ID and query when comparing the 2 modes. Changing another input
would invalidate the comparison.

Use `Latest` to capture recent discussion. Record when you requested the
first page. New tweets can appear while you collect later pages.

Use `Top` to capture relevance-ranked discussion. Record the collection time,
but do not treat rank as a permanent score. The order can change later.

After both runs finish, join rows by tweet ID. Label every tweet as
`latest_only`, `top_only`, or `both`. Keep the original engagement counts from
each run when collection times differ.

Do not append one mode beneath the other without a source column. Analysts
could mistake duplicated tweets for extra community activity.

Validate each dataset before comparison:

* Every row uses the intended community ID.
* Every row stores the exact search query.
* Every cursor belongs to one sort mode.
* Each run removes duplicate tweet IDs.
* Partial runs remain labeled.

Use the combined view to decide what to research first. Keep the separate
exports so others can reproduce and audit the work.

## Query parameters

<ParamField query="communityId" type="string" required>
  Numeric ID of the community whose tweets you want to search.
</ParamField>

<ParamField query="q" type="string" required>
  Search query for community tweets.
</ParamField>

<ParamField query="queryType" type="string">
  Sort order. `Top` returns most relevant tweets, `Latest` returns most recent. Defaults to `Latest`.
</ParamField>

<ParamField query="cursor" type="string">
  Pagination cursor from a previous response. Omit for the first page.
</ParamField>

<ParamField query="pageSize" type="number">
  Upper bound for tweets per page. Range: 1-100. Default: `20`.
</ParamField>

## Which community search route?

<CardGroup cols={2}>
  <Card title="Community search route" icon="list-filter">
    Use `GET /x/communities/search` with `communityId` and `q` for scoped search.
  </Card>

  <Card title="Equivalent scoped route" icon="search">
    Use `GET /x/communities/tweets` when your integration already uses that
    path. It accepts the same `communityId`, `q`, `queryType`, `cursor`, and
    `pageSize` shape.
  </Card>

  <Card title="Known community posts" icon="message-square-text">
    Use [`GET /x/communities/{id}/tweets`](/api-reference/x/community-tweets)
    for posts from one known community ID.
  </Card>

  <Card title="Bulk community jobs" icon="file-spreadsheet">
    Use [`Create extraction`](/api-reference/extractions/create) with
    `community_search` with `targetCommunityId` and `searchQuery` when the
    workflow needs a saved filtered export. Use `community_post_extractor` for
    all posts from a known community.
  </Card>
</CardGroup>

## Build a live community review queue

Choose either documented path for direct, page-by-page tweet retrieval. Both
paths work behind moderation screens, support consoles, and analyst dashboards.

Show the active community ID, query, and sort mode above the results. Reviewers
should always know why each tweet appeared. Render concrete tweet fields:

* Tweet text, Tweet ID, and creation time.
* Author name, username, user ID, and verification state.
* Reply, repost, like, quote, and view counts when returned.
* Attached photo, video, or animated GIF URLs.
* A source URL for opening the original tweet.

Bind `next_cursor` to the community, query, sort mode, and page size. Stop
paging when `has_next_page` is false. An empty page is a valid result, not a
missing community.

## Keep decisions across a live moderation queue

Key the queue on the community ID, query, and sort mode. Store each decision
against `tweet.id`, never a row position. When a page fails, keep its rows and
cursor. Retry with the same parameters.

`Latest` rows change as new tweets arrive, so deduplicate them by Tweet ID.
`Top` ranking changes too, so record each collection time.

## Build a query-specific community review batch

Save the exact query before requesting tweets. Give each batch 1 purpose.

Store Tweet ID, author ID, text, creation time, engagement, and media for every
match. Add the request time and cursor. Keep reviewer fields in a separate
table keyed by Tweet ID.

Record 1 terminal state: completed, capped, credit-bounded, or interrupted. A
live search page never proves a complete community archive.

## Separate search matches from community feed coverage

Community search returns tweets matching one expression. It does not return
every recent post. Use the community feed route for an unfiltered timeline.

Keep match counts separate from total community activity. A narrow query can
return zero tweets while the community remains active. A broad query can
create more review work without improving relevance.

## Headers

<ParamField header="x-api-key" type="string">
  Full account key. Sessions and OAuth also work.
</ParamField>

<ParamField header="Authorization" type="string">
  `Bearer xq_your_guest_key_here` for `paid_reads`.
</ParamField>

## Response

### 200 OK

<ResponseField name="tweets" type="object[]">
  Array of matching community tweets.
  **Tweet object fields.**

  <ResponseField name="id" type="string">Tweet ID.</ResponseField>
  <ResponseField name="text" type="string">Contains the complete Tweet text.</ResponseField>
  <ResponseField name="type" type="string">Classifies the Tweet when X returns a type.</ResponseField>
  <ResponseField name="createdAt" type="string">ISO 8601 creation timestamp.</ResponseField>
  <ResponseField name="isNoteTweet" type="boolean">Whether this is a Note Tweet. Omitted if unavailable.</ResponseField>
  <ResponseField name="isPinned" type="boolean">Whether the author pinned this post to their profile. Omitted if unavailable.</ResponseField>
  <ResponseField name="likeCount" type="number">Reports the number of likes when available.</ResponseField>
  <ResponseField name="retweetCount" type="number">Reports the number of reposts when available.</ResponseField>
  <ResponseField name="replyCount" type="number">Reports the number of replies when available.</ResponseField>
  <ResponseField name="quoteCount" type="number">Reports the number of quotes when available.</ResponseField>
  <ResponseField name="viewCount" type="number">Reports the number of views when available.</ResponseField>
  <ResponseField name="bookmarkCount" type="number">Reports the number of bookmarks when available.</ResponseField>
  <ResponseField name="url" type="string">Permalink URL on X. Omitted if unavailable.</ResponseField>
  <ResponseField name="lang" type="string">Reports the Tweet language code when available.</ResponseField>
  <ResponseField name="isReply" type="boolean">Whether the tweet is a reply. Omitted if unavailable.</ResponseField>
  <ResponseField name="inReplyToId" type="string">Tweet ID being replied to. Omitted if not a reply.</ResponseField>
  <ResponseField name="inReplyToUserId" type="string">Identifies the replied-to user when available.</ResponseField>
  <ResponseField name="inReplyToUsername" type="string">Reports the replied-to username when available.</ResponseField>
  <ResponseField name="conversationId" type="string">Conversation thread ID. Omitted if unavailable.</ResponseField>
  <ResponseField name="source" type="string">Client used to post the tweet. Omitted if unavailable.</ResponseField>
  <ResponseField name="displayTextRange" type="number[]">Start and end offsets for rendered tweet text. Omitted if unavailable.</ResponseField>
  <ResponseField name="isLimitedReply" type="boolean">Whether replies are limited. Omitted if unavailable.</ResponseField>
  <ResponseField name="isQuoteStatus" type="boolean">Whether this tweet quotes another tweet. Omitted if unavailable.</ResponseField>
  <ResponseField name="isRetweet" type="boolean">Whether this row is a retweet. `text` carries the original post in full.</ResponseField>
  <ResponseField name="entities" type="object">Parsed entities. Omitted if unavailable.</ResponseField>
  <ResponseField name="contentDisclosure" type="object">Returns paid-promotion and AI-generated-media labels when available. Includes `advertising.isPaidPromotion` and `aiGenerated.hasAiGeneratedMedia`.</ResponseField>

  <ResponseField name="author" type="object">
    Tweet author profile. Omitted if unavailable.
    **Author object fields.**
    <ResponseField name="id" type="string">Author user ID.</ResponseField>
    <ResponseField name="username" type="string">Author X username.</ResponseField>
    <ResponseField name="name" type="string">Author display name.</ResponseField>
    <ResponseField name="followers" type="number">Reports the author's follower count when available.</ResponseField>
    <ResponseField name="verified" type="boolean">Whether the author is verified. Omitted if unavailable.</ResponseField>
    <ResponseField name="profilePicture" type="string">Profile picture URL. Omitted if unavailable.</ResponseField>
  </ResponseField>

  <ResponseField name="media" type="object[]">
    Lists media items attached to the Tweet. Omitted when none exist.
    **Media object fields.**
    <ResponseField name="mediaUrl" type="string">Provides the direct media URL.</ResponseField>
    <ResponseField name="videoVariants" type="object[]">Lists available video renditions and playback details. Omitted for images.</ResponseField>
    <ResponseField name="type" type="string">Identifies the attached media type.</ResponseField>
    <ResponseField name="url" type="string">Shortened URL from the tweet text.</ResponseField>
  </ResponseField>

  <ResponseField name="quoted_tweet" type="object">Embedded quoted tweet. Omitted if not a quote tweet.</ResponseField>
  <ResponseField name="retweeted_tweet" type="object">Original retweeted tweet. Omitted if not a retweet.</ResponseField>
</ResponseField>

<ResponseField name="has_next_page" type="boolean">Whether more results are available.</ResponseField>
<ResponseField name="next_cursor" type="string">Cursor for the next page. Pass as the `cursor` query parameter.</ResponseField>

```json theme={null}
{
  "tweets": [
    {
      "id": "1893456789012345678",
      "text": "Great discussion about web development",
      "createdAt": "2026-02-24T10:00:00.000Z",
      "likeCount": 75,
      "retweetCount": 12,
      "replyCount": 8,
      "viewCount": 5400,
      "author": {
        "id": "987654321",
        "username": "devuser",
        "name": "Developer",
        "followers": 25000,
        "verified": false,
        "profilePicture": "https://pbs.twimg.com/profile_images/example.jpg"
      }
    }
  ],
  "has_next_page": true,
  "next_cursor": "DAACCgACGE..."
}
```

### 400 Missing query

```json theme={null}
{ "error": "missing_query" }
```

The `q` query parameter is empty or missing.

### 401 Unauthenticated

Anonymous requests get `WWW-Authenticate: Bearer` and a guest wallet checkout action. This is not a Payment challenge.

```json theme={null}
{ "error": "unauthenticated" }
```

Missing or invalid API key.

### 402 Payment required

Account keys get account options. Guest keys get guest top-up only.
No checkout starts automatically. Confirm any payment action.

### 502 X API unavailable

```json theme={null}
{ "error": "x_api_unavailable" }
```

The read service returned an error. Retry after a short delay.

### 429 Rate limit exceeded

```json theme={null}
{ "error": "rate_limit_exceeded", "retryAfter": 60 }
```

You exceeded your tier rate limit. Wait for the `Retry-After` header before retrying.

### 424 Dependency failed

```json theme={null}
{ "error": "x_api_unavailable" }
```

The normalized v1 response contract can return 424 when the read service is unavailable.

<Note>
  **Next steps.** [Community Info](/api-reference/x/community-info) to look up a community, or [Search Tweets](/api-reference/x/search-tweets) for general tweet search.
</Note>

<div className="related-api-links">
  <Accordion title="Related follower, list & community APIs" icon="link">
    * Profiles: [Search users](/api-reference/x/search-users) · [Search autocomplete](/api-reference/x/search-autocomplete) · [Get user](/api-reference/x/twitter-profile-lookup) · [Batch users](/api-reference/x/batch-users)
    * Followers: [Followers](/api-reference/x/followers) · [Following](/api-reference/x/following) · [Follower IDs](/api-reference/x/follower-ids) · [Following IDs](/api-reference/x/following-ids) · [Creator subscriptions](/api-reference/x/user-subscriptions) · [Affiliates](/api-reference/x/user-affiliates) · [Similar accounts](/api-reference/x/user-similar) · [Verified followers](/api-reference/x/verified-followers) · [Followers you know](/api-reference/x/followers-you-know) · [Check follower](/api-reference/x/check-follower)
    * Lists: [Search lists](/api-reference/x/search-lists) · [User lists](/api-reference/x/user-lists) · [List memberships](/api-reference/x/user-list-memberships) · [List members](/api-reference/x/list-members) · [List followers](/api-reference/x/list-followers)
    * Communities: [Find](/api-reference/x/community-find) · [Popular](/api-reference/x/community-popular) · [Topics](/api-reference/x/community-topics) · [Suggested](/api-reference/x/community-suggested) · [Details](/api-reference/x/community-info) · [Members](/api-reference/x/community-members) · [Moderators](/api-reference/x/community-moderators) · [Timeline](/api-reference/x/community-tweets) · [Media](/api-reference/x/community-media) · [Keyword search](/api-reference/x/community-search)
  </Accordion>
</div>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.