> ## 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 API get replies to a tweet & author fields

> Get replies to a tweet by ID with cursors, author profiles, engagement metrics, media, and time filters. Complete mode reports coverage. 1 credit per reply.

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

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

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

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

    <Tab title="404" id="response-x-tweet-replies-404">
      ```json theme={null}
      {
        "error": "tweet_not_found",
        "message": "Tweet not found. Check the tweet ID."
      }
      ```
    </Tab>

    <Tab title="409" id="response-x-tweet-replies-409">
      ```json theme={null}
      {
        "error": "coverage_cursor_unavailable",
        "message": "Cursor busy. Retry after the indicated delay."
      }
      ```
    </Tab>

    <Tab title="410" id="response-x-tweet-replies-410">
      ```json theme={null}
      {
        "error": "coverage_cursor_gone",
        "message": "Cursor finished, expired, or superseded. Restart pagination without cursor."
      }
      ```
    </Tab>

    <Tab title="424" id="response-x-tweet-replies-424">
      ```json theme={null}
      {
        "error": "replies_incomplete",
        "message": "Replies are incomplete. Retry complete mode later."
      }
      ```
    </Tab>

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

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

    <Tab title="503" id="response-x-tweet-replies-503">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "Maximum coverage is busy. Retry shortly."
      }
      ```
    </Tab>
  </Tabs>
</Panel>

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

<Note>
  Repost records include `retweetedAt`, the repost event's UTC ISO 8601 timestamp. It is `null` when
  that timestamp is unavailable. The API omits it for original posts. The nested original post keeps
  its own creation date. This field does not report every account that reposted a post. [Request
  per-account timestamps with Get retweeters.](/api-reference/x/retweeters#retweet-timestamps)
</Note>

Result counts cap paid authenticated calls. Low credits reduce the page or ID list. Zero affordable results return `402 insufficient_credits`.

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

<Info>
  Omit `mode` for automatic maximum coverage. Xquik combines available views
  within a short request window. It keeps the existing response shape.
  Pass `next_cursor` back unchanged as `cursor`. Keep the same endpoint, target,
  query, and filters.
</Info>

Existing unprefixed cursors keep their legacy behavior. `after`, `limit`, and
`pageSize` aliases also keep working. Billing still counts only returned rows.
Use `mode=standard` only to force legacy single-view pagination.

A page can be empty or underfilled. Continue while `has_next_page` is `true`.
Stop only after the response reports `has_next_page=false`.

First-page requests do not support `Idempotency-Key` retries.
Repeating a cursorless request starts a separate extraction.
Results returned by that extraction incur their normal charges.
Save each response before requesting its next page.
You cannot replay earlier or terminal responses after their cursors become unavailable.

If automatic coverage is busy, an initial request returns a standard data page.
Live coverage cursors remain atomic. Concurrent use returns
`409 coverage_cursor_unavailable` with exact `Retry-After` seconds. Wait, then
retry the same cursor once.
Repeated busy responses never authorize restarting with another cursor.

Finished, expired, superseded, or identity-mismatched cursors return
`410 coverage_cursor_gone`. The response omits `Retry-After`. Restart without
a cursor. Keep received results. Deduplicate restarted results by `id`.
Malformed cursors return `400 invalid_coverage_cursor`. Restart without them.

Get replies by tweet ID for analysis, support, moderation, giveaways, and agents.

<Warning>
  Reply visibility depends on X. Complete mode returns `424
      replies_incomplete` below 80% direct-reply coverage. A `sinceTime` or
  `untilTime` window read to its end returns 200. Retry only while
  `diagnostic.sourcesEnded` is `false`.
  Never treat missing rows as proof that a user did not reply.
</Warning>

See [reply coverage and optional fields](/guides/tweet-profile-api-fields).

## Twitter API reply questions

### How does the Twitter API get replies to a tweet?

Pass the original tweet's numeric ID in the path. Automatic `pageSize` accepts
`1` through `300`. Standard pages accept `1` through `100`.
Responses include replies, author profiles & engagement counts.
Save each page & `next_cursor`. Continue while `has_next_page` is `true`.
A post X does not have returns `404 tweet_not_found` & costs no credits.

### How complete is a tweet reply collection?

Protected accounts' replies count toward coverage but aren't returned.
X may omit deleted, hidden, or unavailable replies. `mode=complete` combines
timelines, rankings, cursors, hidden branches, parent windows & search.
Direct replies match `inReplyToId` to the source tweet.
Trust `diagnostic.complete` for direct coverage only. On a `sinceTime` or
`untilTime` request it means the whole window was read.
It does not prove that Xquik returned every nested reply.

Complete mode follows queued live cursors even after meeting direct coverage.
Child timelines find missing replies.
Verified reply counts & drained cursors let collection skip broader searches.
Requested limits, deadlines, and bounded collection budgets still apply.
Check `strategiesAttempted` for early stops.

### How can a team analyze or moderate replies?

Store reply IDs, text, authors, timestamps, engagement counts & media.
Create one moderation row per reply. Xquik does not infer sentiment.

### How can support teams receive new reply alerts?

Create an [account monitor](/api-reference/monitors/create) for the relevant
profile. Select `tweet.reply` events on the monitor and webhook. Verify every
webhook signature. Store each event ID before updating a support ticket. Replay
missed events through the events API. Poll this endpoint for conversation
backfills.

### Which reply fields should applications keep?

Keep author IDs separate from usernames, which can change. Save `conversationId`
and `inReplyToId` for thread joins. Store media URLs, engagement counts, time
filters, page size & cursors for audits & retries.

### How can applications control reply API costs?

Each returned reply costs 1 credit. Direct replies use the default paid page size
unless you set `pageSize`. Bound support periods with `sinceTime` and
`untilTime`, in Unix seconds. Use `reply_extractor` for fixed `resultsLimit`
exports.

<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_api_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_api_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_api_key_here" | jq

  # Request advanced nested-reply diagnostics
  curl -G "https://xquik.com/api/v1/x/tweets/1893456789012345678/replies" \
    --data-urlencode "mode=complete" \
    --data-urlencode "limit=25000" \
    -H "x-api-key: xq_your_api_key_here" | jq
  ```

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

  for (let pageCount = 0; pageCount < 3; pageCount += 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_api_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,
      created_at: reply.createdAt ?? null,
      in_reply_to_id: reply.inReplyToId ?? null,
      conversation_id: reply.conversationId ?? null,
      like_count: reply.likeCount ?? null,
      media_urls: (reply.media ?? []).map((item) => item.mediaUrl).filter(Boolean),
      page_index: pageCount,
      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_api_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"),
              "created_at": reply.get("createdAt"),
              "in_reply_to_id": reply.get("inReplyToId"),
              "conversation_id": reply.get("conversationId"),
              "like_count": reply.get("likeCount"),
              "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` for support, community, moderation, giveaway, or agent workflows.
The examples above write
JSON Lines rows with `parent_tweet_id`, `reply_id`, `text`, author IDs and
usernames, thread joins, media URLs, & cursors.
The moderation table below adds follower, verification, timing,
and engagement projections.

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

## Build a reply moderation table

Store one row per reply. Keep the parent Tweet ID and conversation ID beside
the reply. Support, moderation, campaign, and giveaway reviews can then reconstruct
each conversation branch.

| Reply column | Response source | Review use |
| - | - | - |
| `parent_tweet_id` | Requested path ID | Join every reply to the source tweet. |
| `reply_id` | `tweets[].id` | Deduplicate replies and reference one reply. |
| `text` | `tweets[].text` | Search, label, and display the reply body. |
| `author_id` | `tweets[].author.id` | Keep a stable author key when usernames change. |
| `author_username` | `tweets[].author.username` | Show the current reply author handle. |
| `author_followers` | `tweets[].author.followers` | Add audience context without using it as an identity key. |
| `author_verified` | `tweets[].author.verified` | Keep the observed verification state. |
| `created_at` | `tweets[].createdAt` | Sort replies inside the campaign or moderation window. |
| `in_reply_to_id` | `tweets[].inReplyToId` | Join nested replies to their immediate parent. |
| `conversation_id` | `tweets[].conversationId` | Group replies that belong to the same X conversation. |
| `like_count` | `tweets[].likeCount` | Prioritize replies with more visible engagement. |
| `media_urls` | `tweets[].media[].mediaUrl` | Keep image or video evidence attached to the reply. |

| Collection checkpoint | Stored value | Recovery rule |
| - | - | - |
| Page identity | `page_index` and `page_cursor` | Save both before writing the next reply page. |
| Resume cursor | `next_cursor` | Send it as `cursor` only when `has_next_page` is `true`. |
| Time window | `sinceTime` and `untilTime` | Keep both time values unchanged when retrying. |
| Completion state | `has_next_page` plus the terminal cursor | Mark the export complete only after the final page. |
| Incomplete complete-mode run | `424 replies_incomplete` plus `diagnostic` | Keep rows, inspect evidence, and follow `recommendedFallback`. |

## 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>
  Post ID or URL-encoded post URL, such as `x.com/nasa/status/20`. See [path IDs](/api-reference/overview#path-ids).
  A retweet ID returns the original post's replies.
</ParamField>

## Query parameters

<ParamField query="mode" type="string">
  Omit it for automatic maximum direct-reply coverage. Use `standard` for
  legacy pagination. Use `complete` for nested replies and detailed diagnostics.
</ParamField>

<ParamField query="limit" type="number">
  Complete mode defaults to `25000` combined direct and nested replies.
  Set a smaller or larger total with `limit`, starting at `1`.
</ParamField>

<ParamField query="pageSize" type="number" default="20">
  Automatic pages accept `1` through `300`. Standard pages accept `1` through
  `100`. Omit this field in complete mode. `limit`, `count`, `max_results`,
  `maxItems`, `max_items` & `per_page` also work outside complete mode.
</ParamField>

<ParamField query="cursor" type="string">
  Pass `next_cursor` back unchanged. New Xquik cursors resume automatic
  coverage. Existing unprefixed cursors keep legacy behavior.
</ParamField>

<ParamField query="after" type="string">
  Legacy `cursor` alias on automatic pages.
</ParamField>

<ParamField query="sinceTime" type="string">
  Unix timestamp in seconds. Only return replies after this time.
</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>

<ParamField query="scope" type="string">
  In complete mode, select `all`, `direct`, or `nested` replies.
</ParamField>

<ParamField query="maxDepth" type="integer">
  In complete mode, set the maximum reply depth from the source post.
</ParamField>

<ParamField query="sort" type="string">
  Sort by `relevance`, `latest`, `oldest`, or `likes`. Complete mode defaults to
  relevance. Automatic pages list the newest first unless you set `sort`.
  `latest` & `oldest` sort every row by date. If some rows come from X views
  without date order, the answer sets `orderPartial: true`.
</ParamField>

<ParamField query="excludeOriginalAuthor" type="boolean">
  In complete mode, exclude replies from the source-post author.
</ParamField>

<ParamField query="includeOriginalPost" type="boolean">
  In complete mode, include the source post and count it toward `limit`.
</ParamField>

<ParamField query="hasMediaOnly" type="boolean">
  In complete mode, only return replies containing media.
</ParamField>

### Tweet result filters

These filters apply to automatic and standard pagination. Remove every filter
before requesting complete mode.

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

## 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 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, when available.</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. Omitted if unavailable.</ResponseField>
    <ResponseField name="isReply" type="boolean">Whether the tweet is a reply.</ResponseField>
    <ResponseField name="inReplyToId" type="string">Parent tweet ID.</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, when available.</ResponseField>
    <ResponseField name="retweetCount" type="number">Repost count, when available.</ResponseField>
    <ResponseField name="replyCount" type="number">Reply count, when available.</ResponseField>
    <ResponseField name="quoteCount" type="number">Quote tweet count, when available.</ResponseField>
    <ResponseField name="viewCount" type="number">View count, when available.</ResponseField>
    <ResponseField name="bookmarkCount" type="number">Bookmark count, when available.</ResponseField>
    <ResponseField name="url" type="string">Permalink URL on X. Omitted if unavailable.</ResponseField>
    <ResponseField name="lang" type="string">The tweet's language code, when X returns it.</ResponseField>
    <ResponseField name="source" type="string">Client used to post the tweet. Omitted if unavailable.</ResponseField>
    <ResponseField name="displayTextRange" type="number[]">Offsets of the 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. Omitted if unavailable.</ResponseField>
    <ResponseField name="entities" type="object">Parsed entities. Omitted if unavailable.</ResponseField>
    <ResponseField name="contentDisclosure" type="object">Paid partnership and AI media labels: `advertising.isPaidPromotion` and `aiGenerated.hasAiGeneratedMedia`. X may omit this object.</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">This value records 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">Author profile image URL. Omitted if unavailable.</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="media" type="object[]">
      Media attachments, when available.

      <Expandable title="Media object fields">
        <ResponseField name="mediaUrl" type="string">Direct media URL.</ResponseField>
        <ResponseField name="videoVariants" type="object[]">Video renditions with bitrate, content type, and URL. Omitted for images.</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>
<ResponseField name="nested_replies" type="object[]">Complete mode's nested replies. Exclude them from direct coverage.</ResponseField>
<ResponseField name="orderPartial" type="boolean">Present with `latest` or `oldest` sort when some rows came from X views without date order. Rows stay sorted by date, but replies may be missing between them. Retry later for a gap-free order.</ResponseField>

<ResponseField name="diagnostic" type="object">
  Complete-mode coverage evidence. Omitted from standard responses.

  <Expandable title="Coverage diagnostic fields">
    <ResponseField name="complete" type="boolean">Whether direct coverage met the target without truncation.</ResponseField>

    <ResponseField name="replyTreeComplete" type="boolean">
      Known child counts match the source post & every collected reply.
      Omitted when confirmation is unavailable. Counts reflect collection time.
      Continue pagination while `has_next_page` is `true`.
    </ResponseField>

    <ResponseField name="replyScopeComplete" type="boolean">
      Known child counts confirm all replies within the requested scope & depth.
      Deeper replies may remain. Omitted when confirmation is unavailable.
      Check source errors & truncation separately.
    </ResponseField>

    <ResponseField name="reportedReplyCount" type="number">Reply count reported on the source tweet.</ResponseField>
    <ResponseField name="targetDirectReplies" type="number">Minimum direct replies required for the coverage target.</ResponseField>
    <ResponseField name="uniqueDirectReplies" type="number">Unique replies whose parent matches the requested tweet.</ResponseField>
    <ResponseField name="coveragePercentage" type="number">Unique direct replies divided by the reported count.</ResponseField>
    <ResponseField name="nestedReplyCount" type="number">Nested replies excluded from direct coverage.</ResponseField>
    <ResponseField name="pagesAttempted" type="number">Pages attempted across every collection strategy.</ResponseField>
    <ResponseField name="strategiesAttempted" type="object[]">Strategy names, page counts, contributions, and stop reasons.</ResponseField>
    <ResponseField name="duplicateCount" type="number">Duplicate tweet IDs removed across strategies.</ResponseField>
    <ResponseField name="cursorFailures" type="number">Cursor requests that failed.</ResponseField>
    <ResponseField name="repeatedCursorCount" type="number">Repeated cursors rejected to prevent loops.</ResponseField>
    <ResponseField name="emptyFalseProgressPages" type="number">Empty pages rejected for making no progress.</ResponseField>
    <ResponseField name="malformedCount" type="number">Malformed response items rejected.</ResponseField>
    <ResponseField name="unrelatedCount" type="number">Tweets rejected because they belong elsewhere.</ResponseField>
    <ResponseField name="missingResponseModulesOrFields" type="string[]">Expected X modules or fields that were unavailable.</ResponseField>
    <ResponseField name="recommendedFallback" type="string">Recommended action when coverage remains incomplete.</ResponseField>

    <ResponseField name="richness" type="object">
      Field-presence counts across collected direct replies. Includes
      `totalReplies`, `text`, `author`, `createdAt`, `language`, `url`,
      `entities`, `media`, `article`, `card`, `communityNote`,
      `quotedOrRepostedTweet`, and `engagementCounts`.
    </ResponseField>

    <ResponseField name="responseTruncated" type="boolean">Whether the requested limit truncated safe results.</ResponseField>
    <ResponseField name="sourcesEnded" type="boolean">Every source ended. A retry returns the same rows.</ResponseField>
  </Expandable>
</ResponseField>

### 400 Invalid tweet ID

The response uses `invalid_tweet_id`. Send a post ID or post URL instead.

### 401 Unauthenticated

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

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

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

### 429 Rate limit exceeded

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

### 424 Replies incomplete

Collected rows & diagnostics stay in the answer. Rows are billed as usual.
`recommendedFallback` says what to do next. A cut at your `limit` returns `200`
with `limit_reached: true`.

### 503 Complete reply extraction busy

Wait for the `Retry-After` duration before repeating complete mode.

<Note>
  **Related.** [Tweet Replies Export Workflow](/guides/tweet-replies-export) for 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>

<div className="related-api-links">
  <Accordion title="Related tweet, reply & media APIs" icon="link">
    * Tweets: [Get tweet](/api-reference/x/get-tweet) · [Batch tweets](/api-reference/x/batch-tweets) · [Tweet thread](/api-reference/x/tweet-thread) · [Hidden replies](/api-reference/x/tweet-hidden-replies) · [Translate tweet](/api-reference/x/tweet-translation) · [Embed tweet](/api-reference/x/tweet-embed) · [Resolve links](/api-reference/x/resolve-links) · [Tweet subtitles](/api-reference/x/tweet-subtitles) · [X Article](/api-reference/x/get-article)
    * Analysis: [Sentiment analysis](/api-reference/x/sentiment-analysis) · [Brand mentions](/api-reference/x/brand-monitoring) · [News classification](/api-reference/x/news-classification) · [Market signals](/api-reference/x/market-signals) · [Viral score](/api-reference/x/viral-score) · [Classify posts](/api-reference/x/classify-tweets)
    * Engagement: [Tweet replies](/api-reference/x/tweet-replies) · [Quote tweets](/api-reference/x/tweet-quotes) · [Likers](/api-reference/x/favoriters) · [Reposters](/api-reference/x/retweeters) · [Check repost](/api-reference/x/tweet-repost-check)
    * Profiles: [User tweets](/api-reference/x/user-tweets) · [Batch user tweets](/api-reference/x/batch-user-tweets) · [User replies](/api-reference/x/user-replies) · [User likes](/api-reference/x/user-likes) · [User media](/api-reference/x/user-media) · [User highlights](/api-reference/x/user-highlights) · [User articles](/api-reference/x/user-articles)
    * Feeds: [List tweets](/api-reference/x/list-tweets) · [Trends](/api-reference/x/trends) · [Trend locations](/api-reference/x/trend-locations) · [Search Spaces](/api-reference/x/search-spaces) · [Get Space](/api-reference/x/get-space) · [Space replay](/api-reference/x/space-replay) · [Get broadcast](/api-reference/x/get-broadcast) · [Hashflags](/api-reference/x/hashflags) · [Search places](/api-reference/x/search-places) · [Download media](/api-reference/x/download-media)
  </Accordion>
</div>


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