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

> Retrieve quote tweets for one source tweet with author fields, engagement metrics, filters, and cursor checkpoints

<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 quote tweets returns tweet rows that quote one source tweet. It is also
  useful as a quote tweets API, tweet quotes API, X quote tweets API, Twitter
  quote tweets API, or quoted posts endpoint. The canonical endpoint remains
  `GET /api/v1/x/tweets/{id}/quotes`.
</Info>

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

  ```bash Next page with filters theme={null}
  curl -G https://xquik.com/api/v1/x/tweets/1893456789012345678/quotes \
    --data-urlencode "cursor=abc123" \
    --data-urlencode "sinceTime=1774500000" \
    --data-urlencode "includeReplies=false" \
    --data-urlencode "verifiedOnly=true" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const tweetId = "1893456789012345678";
  const params = new URLSearchParams({
    sinceTime: "1774500000",
    includeReplies: "false",
  });
  const response = await fetch(`https://xquik.com/api/v1/x/tweets/${tweetId}/quotes?${params}`, {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  const data = await response.json();
  const nextCursor = data.has_next_page ? data.next_cursor : null;
  const quoteRows = data.tweets.map((tweet) => ({
    quoted_tweet_id: tweetId,
    quote_id: tweet.id,
    text: tweet.text,
    author_id: tweet.author?.id ?? null,
    author_username: tweet.author?.username ?? null,
    author_name: tweet.author?.name ?? null,
    author_followers: tweet.author?.followers ?? null,
    author_verified: tweet.author?.verified ?? null,
    author_profile_picture: tweet.author?.profilePicture ?? null,
    created_at: tweet.createdAt ?? 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) ?? [],
  }));
  const checkpoint = { quoted_tweet_id: tweetId, next_cursor: nextCursor };

  for (const row of quoteRows) {
    process.stdout.write(`${JSON.stringify(row)}\n`);
  }
  process.stdout.write(`${JSON.stringify({ checkpoint })}\n`);
  ```

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

  tweet_id = "1893456789012345678"
  response = requests.get(
      f"https://xquik.com/api/v1/x/tweets/{tweet_id}/quotes",
      params={"sinceTime": "1774500000", "includeReplies": "false"},
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
  )
  data = response.json()
  next_cursor = data["next_cursor"] if data["has_next_page"] else None
  quote_rows = [
      {
          "quoted_tweet_id": tweet_id,
          "quote_id": tweet["id"],
          "text": tweet["text"],
          "author_id": (tweet.get("author") or {}).get("id"),
          "author_username": (tweet.get("author") or {}).get("username"),
          "author_name": (tweet.get("author") or {}).get("name"),
          "author_followers": (tweet.get("author") or {}).get("followers"),
          "author_verified": (tweet.get("author") or {}).get("verified"),
          "author_profile_picture": (tweet.get("author") or {}).get("profilePicture"),
          "created_at": tweet.get("createdAt"),
          "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")
          ],
      }
      for tweet in data["tweets"]
  ]
  checkpoint = {"quoted_tweet_id": tweet_id, "next_cursor": next_cursor}

  for row in quote_rows:
      print(json.dumps(row))
  print(json.dumps({"checkpoint": checkpoint}))
  ```
</CodeGroup>

The Node.js and Python snippets write JSON Lines quote rows plus a separate
checkpoint instead of raw response pages. Persist each mapped row and the latest
`next_cursor` so a moderation queue, campaign report, research job, or agent
handoff can resume from the last completed page without duplicate rows.

## Direct quote tweet handoff

Use `GET /api/v1/x/tweets/{id}/quotes` when a support, campaign, moderation,
research, or agent workflow needs quote tweets as JSON rows. It returns one row
per quote tweet for a single source tweet. Store `quoted_tweet_id`, `quote_id`,
`text`, `author_id`, `author_username`, `author_name`, `author_followers`,
`author_verified`, `author_profile_picture`, `created_at`, engagement counts,
media URLs, and a separate `next_cursor` checkpoint. Use `sinceTime`,
`untilTime`, `includeReplies`, and tweet result filters to bound the quote set
before exporting rows downstream.

<CardGroup cols={2}>
  <Card title="Quote rows" icon="quote">
    Store `tweets[]` as quote tweet rows for one source tweet.
  </Card>

  <Card title="Stable upserts" icon="key-round">
    Store `tweets[].id` as `quote_id` with `quoted_tweet_id` for idempotent
    imports and moderation queues.
  </Card>

  <Card title="Author joins" icon="user-round">
    Store `tweets[].author.id`, `username`, `name`, `followers`, `verified`, and
    `profilePicture` for CRM, research, and review tools.
  </Card>

  <Card title="Engagement metrics" icon="chart-no-axes-combined">
    Store `likeCount`, `replyCount`, `retweetCount`, `quoteCount`, `viewCount`,
    and `bookmarkCount` when returned.
  </Card>

  <Card title="Media context" icon="image">
    Store `media[].mediaUrl`, `entities`, `quoted_tweet`, and `retweeted_tweet`
    when returned to preserve attached context.
  </Card>

  <Card title="Window filters" icon="calendar-range">
    Use `sinceTime`, `untilTime`, `includeReplies`, and tweet result filters to
    narrow campaign, support, or audit windows.
  </Card>

  <Card title="Next page" icon="arrow-right">
    Store `has_next_page` and `next_cursor`; pass `next_cursor` back as `cursor`
    only when `has_next_page` is true.
  </Card>

  <Card title="Credit-limited pages" icon="coins">
    Use `tweets.length`, not a requested page size, for row counts. Low balances
    can return fewer rows.
  </Card>
</CardGroup>

Direct quote tweet reads cost 1 credit per tweet returned. Low credit balances
can return fewer tweets than a full page; zero affordable results return
`402 insufficient_credits`. For MPP callers, this endpoint is billed as a
session at USD 0.00015 per tweet returned.

## Historical pages vs live quote alerts

Use this endpoint when you need existing quote tweets for one source tweet. Use
monitors when future quote activity should arrive as stored events or signed
webhook deliveries.

<CardGroup cols={2}>
  <Card title="Historical quote pull" icon="clock-arrow-down">
    Call `GET /x/tweets/{id}/quotes`, store `quote_id`, and resume with
    `next_cursor` for one known source tweet.
  </Card>

  <Card title="Account quote monitor" icon="radio">
    Use [`POST /monitors`](/api-reference/monitors/create) with
    `eventTypes: ["tweet.quote"]` when one tracked account's future quote
    tweets should produce events.
  </Card>

  <Card title="Keyword quote monitor" icon="search-check">
    Use [`POST /monitors/keywords`](/api-reference/monitors/create-keyword)
    with `eventTypes: ["tweet.quote"]` when matching future quote tweets should
    produce events.
  </Card>

  <Card title="Signed webhook delivery" icon="webhook">
    Use [`POST /webhooks`](/api-reference/webhooks/create) with `tweet.quote`,
    verify signatures, and replay stored rows with
    [`GET /events`](/api-reference/events/list).
  </Card>
</CardGroup>

## Path parameters

<ParamField path="id" type="string" required>
  Tweet ID (numeric string).
</ParamField>

## Query parameters

<ParamField query="cursor" type="string">
  Pagination cursor from `next_cursor` in a previous response. Omit for the
  first page. Pass a cursor only when `has_next_page` is true.
</ParamField>

<ParamField query="sinceTime" type="string">
  Unix timestamp in seconds. Only return quotes after this time.
</ParamField>

<ParamField query="untilTime" type="string">
  Unix timestamp in seconds. Only return quotes before this time.
</ParamField>

<ParamField query="includeReplies" type="boolean">
  Include reply tweets. Default: `false`.
</ParamField>

### Tweet result filters

These optional filters apply to `tweets[]` returned by this route. They keep the
same quoted 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>

## Which tweet engagement endpoint?

<CardGroup cols={2}>
  <Card title="Quote tweets" icon="quote">
    Use `GET /x/tweets/{id}/quotes` for tweet rows that quote one source tweet.
  </Card>

  <Card title="Tweet replies" icon="message-square-reply">
    Use [`GET /x/tweets/{id}/replies`](/api-reference/x/tweet-replies) when you
    need reply tweet rows under the source tweet.
  </Card>

  <Card title="Retweeters" icon="repeat-2">
    Use [`GET /x/tweets/{id}/retweeters`](/api-reference/x/retweeters) for user
    profiles that reposted one source tweet.
  </Card>

  <Card title="Tweet likers" icon="heart">
    Use [`GET /x/tweets/{id}/favoriters`](/api-reference/x/favoriters) for user
    profiles that liked one source tweet.
  </Card>

  <Card title="Saved exports" icon="file-spreadsheet">
    Use [`Create extraction`](/api-reference/extractions/create) with
    `toolType=quote_extractor` when you need a saved job or CSV, JSON, or XLSX
    export.
  </Card>

  <Card title="Search handoff" icon="search">
    Use [`Search tweets`](/api-reference/x/search-tweets) when you need keyword,
    operator, or structured-filter discovery across many source tweets.
  </Card>
</CardGroup>

## 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 quote 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. 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="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": "Great point! RT @user: ...",
          "createdAt": "2026-03-27T11:00:00.000Z",
          "likeCount": 10,
          "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](/api-reference/x/tweet-replies) · [Tweet thread](/api-reference/x/tweet-thread) · [Retweeters](/api-reference/x/retweeters) · [Tweet favoriters](/api-reference/x/favoriters)
</Note>
