> ## 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.

# Get tweets (batch)

> Retrieve multiple tweets by ID in a single request, up to 100 at a time

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

<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`.
</Note>

<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 "https://xquik.com/api/v1/x/tweets?ids=1893456789012345678,1893456789012345679" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const ids = ["1893456789012345678", "1893456789012345679"];
  const response = await fetch(
    `https://xquik.com/api/v1/x/tweets?ids=${ids.join(",")}`,
    {
      headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
    }
  );
  const data = await response.json();
  const tweetsById = new Map(data.tweets.map((tweet) => [tweet.id, tweet]));
  const tweetRows = data.tweets.map((tweet) => {
    const author = tweet.author ?? {};

    return {
      requested_ids: ids,
      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,
      conversation_id: tweet.conversationId ?? null,
      like_count: tweet.likeCount ?? null,
      reply_count: tweet.replyCount ?? null,
      retweet_count: tweet.retweetCount ?? null,
      quote_count: tweet.quoteCount ?? null,
      media_urls: tweet.media?.map((item) => item.mediaUrl).filter(Boolean) ?? [],
      has_next_page: data.has_next_page,
      next_cursor: data.next_cursor || null,
    };
  });
  const missingIds = ids.filter((id) => !tweetsById.has(id));
  ```

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

  ids = ["1893456789012345678", "1893456789012345679"]
  response = requests.get(
      "https://xquik.com/api/v1/x/tweets",
      params={"ids": ",".join(ids)},
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
  )
  data = response.json()
  tweets_by_id = {tweet["id"]: tweet for tweet in data["tweets"]}
  tweet_rows = []
  for tweet in data["tweets"]:
      author = tweet.get("author") or {}
      tweet_rows.append(
          {
              "requested_ids": ids,
              "tweet_id": tweet["id"],
              "text": tweet["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"),
              "conversation_id": tweet.get("conversationId"),
              "like_count": tweet.get("likeCount"),
              "reply_count": tweet.get("replyCount"),
              "retweet_count": tweet.get("retweetCount"),
              "quote_count": tweet.get("quoteCount"),
              "media_urls": [
                  item["mediaUrl"]
                  for item in tweet.get("media", [])
                  if item.get("mediaUrl")
              ],
              "has_next_page": data["has_next_page"],
              "next_cursor": data["next_cursor"] or None,
          }
      )

  missing_ids = [tweet_id for tweet_id in ids if tweet_id not in tweets_by_id]
  ```
</CodeGroup>

The Node.js and Python snippets shape durable tweet rows instead of printing
full response pages. Persist `tweetRows` or `tweet_rows` and `missingIds` or
`missing_ids` with the original ID list so retries only request missing tweets.

## Direct batch tweet handoff

Use `GET /x/tweets` when a CRM, warehouse, newsroom, moderation queue, or agent
workflow already has tweet IDs and needs tweet text, authors, metrics, media
URLs, and missing-ID handling in one response. Use [Get Tweet](/api-reference/x/get-tweet)
when you need one tweet by ID, or [Search Tweets](/api-reference/x/search-tweets)
when you need to find tweets by query.

Store `requested_ids`, `tweet_id`, `text`, `author_id`, `author_username`,
`author_name`, `author_followers`, `author_verified`,
`author_profile_picture`, `created_at`, `conversation_id`, engagement counts,
media URLs, `has_next_page`, and `next_cursor`. Join returned tweets by
`tweet_id` instead of relying on response order. Send at most 100 IDs per request. Batch requests
always return `has_next_page: false` and `next_cursor: ""`; zero affordable
results return `402 insufficient_credits`.

## Query parameters

<ParamField query="ids" type="string" required>
  Comma-separated tweet IDs. Maximum 100 per request.
</ParamField>

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key. Session cookie authentication is also supported.
</ParamField>

## Response

<Tabs>
  <Tab title="200 OK">
    <ResponseField name="tweets" type="object[]">
      Array of tweets matching the requested IDs.

      <Expandable title="Tweet object fields">
        <ResponseField name="id" type="string">Tweet ID.</ResponseField>
        <ResponseField name="text" type="string">Tweet text.</ResponseField>
        <ResponseField name="type" type="string">Tweet type. Omitted if unavailable.</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="likeCount" type="number">Like count. Omitted if unavailable.</ResponseField>
        <ResponseField name="retweetCount" type="number">Retweet count. Omitted if unavailable.</ResponseField>
        <ResponseField name="replyCount" type="number">Reply count. Omitted if unavailable.</ResponseField>
        <ResponseField name="quoteCount" type="number">Quote tweet count. Omitted if unavailable.</ResponseField>
        <ResponseField name="viewCount" type="number">View count. Omitted if unavailable.</ResponseField>
        <ResponseField name="bookmarkCount" type="number">Bookmark count. Omitted if unavailable.</ResponseField>
        <ResponseField name="url" type="string">Permalink URL on X. Omitted if unavailable.</ResponseField>
        <ResponseField name="lang" type="string">Tweet language code. Omitted if unavailable.</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">User ID being replied to. Omitted if unavailable.</ResponseField>
        <ResponseField name="inReplyToUsername" type="string">Username being replied to. Omitted if unavailable.</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="entities" type="object">Parsed entities. Omitted if unavailable.</ResponseField>
        <ResponseField name="contentDisclosure" type="object">Disclosure metadata for paid partnership and AI-generated media labels. Includes `advertising.isPaidPromotion` and `aiGenerated.hasAiGeneratedMedia` when X returns them. Omitted if unavailable.</ResponseField>

        <ResponseField name="author" type="object">
          Tweet author profile. Omitted if unavailable.

          <Expandable title="Author object fields">
            <ResponseField name="id" type="string">Author user ID.</ResponseField>
            <ResponseField name="username" type="string">Author handle without `@`.</ResponseField>
            <ResponseField name="name" type="string">Author display name. Omitted if unavailable.</ResponseField>
            <ResponseField name="followers" type="number">Follower count. Omitted if unavailable.</ResponseField>
            <ResponseField name="verified" type="boolean">Whether the author is verified. Omitted if unavailable.</ResponseField>
            <ResponseField name="profilePicture" type="string">Author profile image URL. Omitted if unavailable.</ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="media" type="object[]">
          Media attachments. Omitted when the tweet has no media.

          <Expandable title="Media object fields">
            <ResponseField name="mediaUrl" type="string">Direct media URL.</ResponseField>
            <ResponseField name="type" type="string">Media type.</ResponseField>
            <ResponseField name="url" type="string">Shortened URL from the tweet text.</ResponseField>
          </Expandable>
        </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>
      </Expandable>
    </ResponseField>

    <ResponseField name="has_next_page" type="boolean">Always `false` for batch requests.</ResponseField>
    <ResponseField name="next_cursor" type="string">Always empty for batch requests.</ResponseField>

    ```json theme={null}
    {
      "tweets": [
        {
          "id": "1893456789012345678",
          "text": "Hello world!",
          "createdAt": "2026-03-27T10:00:00.000Z",
          "likeCount": 42,
          "retweetCount": 5,
          "author": {
            "id": "9876543210",
            "username": "xquikcom",
            "name": "Xquik",
            "followers": 12000,
            "verified": true,
            "profilePicture": "https://pbs.twimg.com/profile_images/example.jpg"
          }
        }
      ],
      "has_next_page": false,
      "next_cursor": ""
    }
    ```
  </Tab>

  <Tab title="400 Missing IDs">
    ```json theme={null}
    { "error": "missing_ids", "message": "ids parameter required" }
    ```
  </Tab>

  <Tab title="400 Too many IDs">
    ```json theme={null}
    { "error": "too_many_ids", "message": "Max 100 IDs per request" }
    ```
  </Tab>

  <Tab title="401 Unauthenticated">
    ```json theme={null}
    { "error": "unauthenticated" }
    ```
  </Tab>

  <Tab title="402 Subscription required">
    ```json theme={null}
    { "error": "no_subscription" }
    ```

    No active subscription or insufficient credits. Possible error values: `no_subscription`, `subscription_inactive`, `no_credits`, `insufficient_credits`.
  </Tab>

  <Tab title="502 X API unavailable">
    ```json theme={null}
    { "error": "x_api_unavailable" }
    ```

    The read service returned an error. Retry after a short delay.
  </Tab>

  <Tab title="429 Rate Limit Exceeded">
    ```json theme={null}
    { "error": "rate_limit_exceeded", "retryAfter": 60 }
    ```

    Your tier rate limit was exceeded. Wait for the `Retry-After` header before retrying.
  </Tab>

  <Tab title="424 Dependency Failed">
    ```json theme={null}
    { "error": "x_api_unavailable" }
    ```

    The normalized v1 response contract can return 424 when the read service is unavailable.
  </Tab>
</Tabs>

<Note>
  **Related:** [Batch Users](/api-reference/x/batch-users) · [Get Tweet](/api-reference/x/get-tweet)
</Note>
