> ## 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 tweet replies

> Retrieve replies for one X tweet with cursor pagination, Unix timestamp windows, author fields, engagement metrics, media, and export handoffs

<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 · Accepts [MPP](/mpp/overview)
</Callout>

<Info>
  Get tweet replies returns reply tweets for one X post by numeric tweet ID. Use
  it for conversation analysis, support queues, moderation review, giveaway
  audits, and agent handoffs. The canonical route stays
  `GET /api/v1/x/tweets/{id}/replies`.
</Info>

<CodeGroup>
  ```bash cURL theme={null}
  # First page of replies
  curl "https://xquik.com/api/v1/x/tweets/1893456789012345678/replies" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq

  # Resume with the previous next_cursor
  curl -G "https://xquik.com/api/v1/x/tweets/1893456789012345678/replies" \
    --data-urlencode "cursor=DAACCgACGE..." \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq

  # Bound a campaign or moderation window
  curl -G "https://xquik.com/api/v1/x/tweets/1893456789012345678/replies" \
    --data-urlencode "sinceTime=1777392000" \
    --data-urlencode "untilTime=1777478400" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const tweetId = "1893456789012345678";
  let pageCursor = "";

  for (let pageIndex = 0; pageIndex < 3; pageIndex += 1) {
    const params =
      pageCursor === "" ? "" : `?${new URLSearchParams({ cursor: pageCursor })}`;
    const response = await fetch(
      `https://xquik.com/api/v1/x/tweets/${tweetId}/replies${params}`,
      { headers: { "x-api-key": "xq_YOUR_KEY_HERE" } },
    );
    const page = await response.json();
    if (!response.ok) throw new Error(JSON.stringify(page));

    const replyRows = page.tweets.map((reply) => ({
      parent_tweet_id: tweetId,
      reply_id: reply.id,
      text: reply.text,
      author_id: reply.author?.id ?? null,
      author_username: reply.author?.username ?? null,
      author_name: reply.author?.name ?? null,
      author_followers: reply.author?.followers ?? null,
      author_verified: reply.author?.verified ?? null,
      author_profile_picture: reply.author?.profilePicture ?? null,
      created_at: reply.createdAt ?? null,
      in_reply_to_id: reply.inReplyToId ?? null,
      conversation_id: reply.conversationId ?? null,
      like_count: reply.likeCount ?? null,
      reply_count: reply.replyCount ?? null,
      retweet_count: reply.retweetCount ?? null,
      quote_count: reply.quoteCount ?? null,
      view_count: reply.viewCount ?? null,
      media_urls: (reply.media ?? []).map((item) => item.mediaUrl).filter(Boolean),
      page_index: pageIndex,
      page_cursor: pageCursor,
      next_cursor: page.next_cursor,
      has_next_page: page.has_next_page,
    }));
    for (const row of replyRows) process.stdout.write(`${JSON.stringify(row)}\n`);

    if (!page.has_next_page || page.next_cursor === "") break;
    pageCursor = page.next_cursor;
  }
  ```

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

  tweet_id = "1893456789012345678"
  page_cursor = ""

  for page_index in range(3):
      params = {"cursor": page_cursor} if page_cursor else {}
      response = requests.get(
          f"https://xquik.com/api/v1/x/tweets/{tweet_id}/replies",
          params=params,
          headers={"x-api-key": "xq_YOUR_KEY_HERE"},
      )
      page = response.json()
      if not response.ok:
          raise RuntimeError(page)

      for reply in page["tweets"]:
          reply_row = {
              "parent_tweet_id": tweet_id,
              "reply_id": reply["id"],
              "text": reply["text"],
              "author_id": (reply.get("author") or {}).get("id"),
              "author_username": (reply.get("author") or {}).get("username"),
              "author_name": (reply.get("author") or {}).get("name"),
              "author_followers": (reply.get("author") or {}).get("followers"),
              "author_verified": (reply.get("author") or {}).get("verified"),
              "author_profile_picture": (reply.get("author") or {}).get("profilePicture"),
              "created_at": reply.get("createdAt"),
              "in_reply_to_id": reply.get("inReplyToId"),
              "conversation_id": reply.get("conversationId"),
              "like_count": reply.get("likeCount"),
              "reply_count": reply.get("replyCount"),
              "retweet_count": reply.get("retweetCount"),
              "quote_count": reply.get("quoteCount"),
              "view_count": reply.get("viewCount"),
              "media_urls": [
                  item["mediaUrl"] for item in reply.get("media", []) if item.get("mediaUrl")
              ],
              "page_index": page_index,
              "page_cursor": page_cursor,
              "next_cursor": page["next_cursor"],
              "has_next_page": page["has_next_page"],
          }
          print(json.dumps(reply_row, separators=(",", ":")))

      if not page["has_next_page"] or not page["next_cursor"]:
          break
      page_cursor = page["next_cursor"]
  ```
</CodeGroup>

## Direct replies handoff

Use `GET /x/tweets/{id}/replies` when a support, community, moderation,
giveaway, or agent workflow needs reply rows as JSON. The examples above write
JSON Lines rows with `parent_tweet_id`, `reply_id`, `text`, author ID,
username, display name, follower count, verified state, profile image URL,
thread joins, engagement counts, media URLs, and cursor fields. Each line
represents one reply for a single tweet, so a worker can resume from the last
saved `next_cursor`.

Use [`reply_extractor`](/guides/tweet-replies-export) instead when a team needs
an estimate, durable extraction ID, stored result pages, or CSV, JSON, and XLSX
downloads after completion.

<CardGroup cols={2}>
  <Card title="Live reply page" icon="message-square-reply">
    Call `GET /x/tweets/{id}/replies` when queues, agents, or dashboards need
    current JSON rows and can store `next_cursor`.
  </Card>

  <Card title="Saved reply export" icon="archive">
    Run `reply_extractor` for estimates, job status, stored pages, and
    downloadable reply files.
  </Card>
</CardGroup>

<CardGroup cols={2}>
  <Card title="Reply rows" icon="rows-3">
    Store `tweets[]` as reply rows for moderation queues, support triage, giveaway audits, or agents.
  </Card>

  <Card title="Reply keys" icon="key-round">
    Store `tweets[].id` as the stable reply key for dedupe, labels, and follow-up actions.
  </Card>

  <Card title="Reply context" icon="message-square-text">
    Store `tweets[].text` and `tweets[].createdAt` for reply context and time ordering.
  </Card>

  <Card title="Author joins" icon="user-round">
    Store `tweets[].author.id`, `tweets[].author.username`, `tweets[].author.name`, `tweets[].author.followers`, `tweets[].author.verified`, and `tweets[].author.profilePicture` for joins, display names, trust cues, and avatars.
  </Card>

  <Card title="Thread joins" icon="git-branch">
    Store `tweets[].inReplyToId` and `conversationId` to join replies back to the parent tweet and thread.
  </Card>

  <Card title="Reply priority" icon="chart-no-axes-combined">
    Store engagement counts to prioritize high-signal or high-risk replies.
  </Card>

  <Card title="Attached context" icon="image">
    Store `tweets[].media`, `quoted_tweet`, and `retweeted_tweet` to preserve attachments and relationship context when available.
  </Card>

  <Card title="Older replies" icon="arrow-right">
    Store `has_next_page` and `next_cursor`, then pass `next_cursor` as `cursor` to fetch older reply pages.
  </Card>
</CardGroup>

`sinceTime` and `untilTime` are Unix timestamps in seconds. Use them to bound moderation windows, campaign periods, or giveaway audit ranges. Direct replies calls use the default paid page size; use `reply_extractor` with `resultsLimit` when you need a predictable file export cap.

Direct replies cost 1 credit per tweet returned. Low credit balances can return fewer replies than a full page; zero affordable results return `402 insufficient_credits`. Retry `429` with the `Retry-After` header, and retry `424` or `502` after a short backoff.

## Which replies endpoint?

* Use `GET /api/v1/x/tweets/{id}/replies` for one tweet's replies as JSON rows.
* Use [`reply_extractor`](/guides/tweet-replies-export) when you need saved CSV, JSON, or XLSX exports.
* Use `GET /api/v1/x/tweets/search` when you need keyword, operator, structured-filter, or `queryType` search.
* Use `GET /api/v1/x/tweets/{id}/thread` when you need ordered thread context around a tweet.

## Path parameters

<ParamField path="id" type="string" required>
  Numeric X tweet ID. Pass the source tweet whose replies you want to retrieve.
</ParamField>

## Query parameters

<ParamField query="cursor" type="string">
  Opaque pagination cursor for older reply pages. Omit it for the first page,
  then pass the `next_cursor` value from the previous response.
</ParamField>

<ParamField query="sinceTime" type="string">
  Unix timestamp in seconds. Only return replies after this time when a poller,
  moderation queue, or campaign report needs a bounded window.
</ParamField>

<ParamField query="untilTime" type="string">
  Unix timestamp in seconds. Only return replies before this time. Pair with
  `sinceTime` for closed campaign, support, or audit windows.
</ParamField>

### Tweet result filters

These optional filters apply to `tweets[]` returned by this route. They keep the
same parent tweet and filter rows after each page is fetched, so selective
filters can return fewer rows than an unfiltered page.

<ParamField query="fromUser" type="string">
  Filter to tweets authored by 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 tweets that mention this username.
</ParamField>

<ParamField query="language" type="string">
  Filter by tweet language code, such as `en`, `tr`, or `es`.
</ParamField>

<ParamField query="sinceDate" type="string">
  Filter to tweets created on or after this date or timestamp.
</ParamField>

<ParamField query="untilDate" type="string">
  Filter to tweets created before this date or timestamp. A `YYYY-MM-DD` value includes the whole day before the boundary.
</ParamField>

<ParamField query="mediaType" type="string">
  Filter by attached media or links. Values: `images`, `videos`, `gifs`, `media`, `links`, `none`.
</ParamField>

<ParamField query="minFaves" type="integer">
  Minimum like count.
</ParamField>

<ParamField query="minRetweets" type="integer">
  Minimum retweet count.
</ParamField>

<ParamField query="minReplies" type="integer">
  Minimum reply count.
</ParamField>

<ParamField query="minQuotes" type="integer">
  Minimum quote count.
</ParamField>

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

<ParamField query="replies" type="string">
  Reply mode. Values: `include`, `exclude`, `only`.
</ParamField>

<ParamField query="retweets" type="string">
  Retweet mode. Values: `include`, `exclude`, `only`.
</ParamField>

<ParamField query="quotes" type="string">
  Quote mode. Values: `include`, `exclude`, `only`.
</ParamField>

<ParamField query="exactPhrase" type="string">
  Exact text that must appear in the tweet.
</ParamField>

<ParamField query="excludeWords" type="string">
  Words or quoted phrases to exclude from returned tweets. Separate with spaces, commas, or lines.
</ParamField>

<ParamField query="anyWords" type="string">
  Words or quoted phrases where at least 1 term must appear in the tweet. Separate with spaces, commas, or lines.
</ParamField>

<ParamField query="hashtags" type="string">
  Hashtags to match. Separate with spaces, commas, or lines. The `#` prefix is optional.
</ParamField>

<ParamField query="cashtags" type="string">
  Cashtags to match. Separate with spaces, commas, or lines. The `$` prefix is optional.
</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">
  Filter to 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>

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

      <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="isReply" type="boolean">Whether the tweet is a reply.</ResponseField>
        <ResponseField name="inReplyToId" type="string">ID of the tweet being replied to.</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="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="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.</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">Whether more results are available.</ResponseField>
    <ResponseField name="next_cursor" type="string">Cursor for the next page.</ResponseField>

    ```json theme={null}
    {
      "tweets": [
        {
          "id": "1893456789012345679",
          "text": "I agree with this!",
          "createdAt": "2026-03-27T11:00:00.000Z",
          "isReply": true,
          "inReplyToId": "1893456789012345678",
          "author": {
            "id": "44196397",
            "username": "xquikcom",
            "name": "Xquik",
            "followers": 1200,
            "verified": true,
            "profilePicture": "https://pbs.twimg.com/profile_images/example.jpg"
          }
        }
      ],
      "has_next_page": true,
      "next_cursor": "DAACCgACGE..."
    }
    ```
  </Tab>

  <Tab title="400 Invalid tweet ID">
    ```json theme={null}
    { "error": "invalid_tweet_id" }
    ```
  </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:** [Tweet Replies Export Workflow](/guides/tweet-replies-export) when you need saved CSV, JSON, or XLSX files, [Tweet Quotes](/api-reference/x/tweet-quotes), [Tweet Thread](/api-reference/x/tweet-thread), [Retweeters](/api-reference/x/retweeters), and [Favoriters](/api-reference/x/favoriters).
</Note>
