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

# See who retweeted my tweet with Twitter API

> See who retweeted a tweet with user profiles, follower counts, verification fields, cursor checkpoints & exact Twitter API examples for giveaway checks.

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

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

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

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

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

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

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

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

    <Tab title="503" id="response-x-retweeters-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>

<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 result returned** · [All plans](https://xquik.com/#pricing) from \$0.00012/credit · Supports [guest paid reads](/guides/guest-wallets)
</Callout>

This route shows who retweeted one public tweet. The response
returns one user profile per visible reposting account. The route
is `GET /api/v1/x/tweets/{id}/retweeters`.

A post X does not have returns `404 tweet_not_found`, as
[Get tweet](/api-reference/x/get-tweet) does. Deleted, suspended-account &
protected posts count as missing. A post without reposts returns an empty page.
A 404 costs no credits.

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

  ```bash Next page theme={null}
  curl -G https://xquik.com/api/v1/x/tweets/1893456789012345678/retweeters \
    --data-urlencode "cursor=abc123" \
    -H "x-api-key: xq_your_api_key_here" | jq
  ```

  ```javascript Node.js theme={null}
  const tweetId = "1893456789012345678";
  const response = await fetch(`https://xquik.com/api/v1/x/tweets/${tweetId}/retweeters`, {
    headers: { "x-api-key": "xq_your_api_key_here" },
  });
  const data = await response.json();
  const retweeterRows = data.users.map((user) => ({
    source_tweet_id: tweetId,
    retweeter_id: user.id,
    username: user.username,
    display_name: user.name,
    follower_count: user.followers ?? null,
    following_count: user.following ?? null,
    verified: user.verified ?? false,
    verified_type: user.verifiedType ?? null,
    profile_image_url: user.profilePicture ?? null,
  }));
  const nextCursor = data.has_next_page ? data.next_cursor : null;
  const checkpoint = { source_tweet_id: tweetId, next_cursor: nextCursor };

  for (const row of retweeterRows) {
    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}/retweeters",
      headers={"x-api-key": "xq_your_api_key_here"},
  )
  data = response.json()
  next_cursor = data["next_cursor"] if data["has_next_page"] else None
  retweeter_rows = [
      {
          "source_tweet_id": tweet_id,
          "retweeter_id": user["id"],
          "username": user["username"],
          "display_name": user["name"],
          "follower_count": user.get("followers"),
          "following_count": user.get("following"),
          "verified": user.get("verified", False),
          "verified_type": user.get("verifiedType"),
          "profile_image_url": user.get("profilePicture"),
      }
      for user in data["users"]
  ]
  checkpoint = {"source_tweet_id": tweet_id, "next_cursor": next_cursor}
  for row in retweeter_rows:
      print(json.dumps(row))
  print(json.dumps({"checkpoint": checkpoint}))
  ```
</CodeGroup>

The Node.js and Python snippets write JSON Lines retweeter rows plus a separate
checkpoint. They do not write raw response pages. Store each mapped row and the latest
`next_cursor`. An import, giveaway verifier, CRM sync, or agent job can then resume
from the last completed page without duplicate rows.

## Retweet timestamps

Set `includeRetweetTimestamp=true` to request each account's matching repost timestamp.
The additional lookup checks the newest available profile page and adds latency.
It does not search the account's complete history.

```bash Retweet timestamps theme={null}
curl -G https://xquik.com/api/v1/x/tweets/1893456789012345678/retweeters \
  --data-urlencode "includeRetweetTimestamp=true" \
  -H "x-api-key: xq_your_api_key_here"
```

Read `users[].retweetedAt` as a UTC ISO 8601 timestamp or `null`.
`null` means the lookup could not establish the matching repost time.
The profile remains in the response when that lookup fails or expires.
Neither the account creation date nor the original post date replaces it.
`createdAt` continues to describe the account's creation date.

The option defaults to `false`. Ordinary retweeter responses omit `retweetedAt`.
Keep it enabled on later pages when exporting timestamps.
The Engagement Scraper accepts the same option for `retweeters` results.
Its dataset rows use `retweetedAt`.

## Direct retweeter handoff

Use `GET /api/v1/x/tweets/{id}/retweeters` when a workflow needs one row per
account that retweeted or reposted a tweet. Use these rows for giveaway checks,
CRM imports, audience reviews, or follow-up jobs. Store `source_tweet_id`,
`retweeter_id`, `username`, `display_name`, `follower_count`,
`following_count`, `verified`, `verified_type`, and `profile_image_url`. Store
`next_cursor` as a separate checkpoint.

<CardGroup cols={2}>
  <Card title="Retweeter rows" icon="rows-3">
    Store `users[]` as the profile rows for accounts that reposted the source
    tweet.
  </Card>

  <Card title="Stable upserts" icon="key-round">
    Store `users[].id` as `retweeter_id` with `source_tweet_id` for idempotent
    imports and giveaway checks.
  </Card>

  <Card title="Readable labels" icon="badge">
    Store `users[].username` and `users[].name` for handles, labels, and review
    queues.
  </Card>

  <Card title="Profile enrichment" icon="file-text">
    Store `description`, `location`, `url`, and `profilePicture` when returned
    for CRM and warehouse enrichment.
  </Card>

  <Card title="Audience signals" icon="chart-no-axes-combined">
    Store `followers`, `following`, `verified`, and `verifiedType` for reach
    scoring, filters, and outreach priority.
  </Card>

  <Card title="Approved contact" icon="message-square">
    Use DM endpoints only after a user-approved message flow. The write
    response tells you whether X delivered the DM.
  </Card>

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

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

Direct retweeter reads cost 1 credit per user returned. Low credit balances can
return fewer users than a full page. Zero affordable results return
`402 insufficient_credits`.

## Retweeter questions

### Can I see who retweeted my tweet?

Yes, for profiles visible to this endpoint. Pass the tweet's numeric ID. The
response lists handles, names, follower counts, and verification fields.
Continue pagination only when the response confirms another page.
[X documents this read intent as Get Reposted by.](https://docs.x.com/x-api/posts/get-reposted-by)

### Why can't I see every retweeter?

X controls which profiles each request exposes. Deleted, protected, blocked,
or withheld accounts may not appear. X may also omit accounts it cannot
return. Pagination and credit limits can shorten one page. A missing profile
cannot confirm zero repost activity.

### Do retweeters include quote tweets?

No. A standard repost shares the source tweet without added commentary.
[The quote-tweets endpoint returns added commentary.](/api-reference/x/tweet-quotes)
[Use the tweet-replies endpoint to read the conversation.](/api-reference/x/tweet-replies)

### How do I export retweeters?

The Node.js and Python examples write one JSON Lines row per user. Store the
source tweet ID beside each profile. Use `next_cursor` to resume an interrupted
export. Use `toolType=repost_extractor` for a saved CSV, JSON, or XLSX job.

### How can I analyze retweeters?

Compare complete snapshots with numeric user IDs. Record the collection time
beside follower and verification fields. A repost does not prove endorsement
or a business relationship. Report only returned profile attributes.

## 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).
</ParamField>

## Query parameters

<ParamField query="cursor" type="string">
  Pagination cursor from `next_cursor` in a previous response. Omit it on the
  initial request. Pass it only when `has_next_page` is true. A cursor X refuses
  or that expired returns a free `400 invalid_cursor`. Start again without it.
</ParamField>

<ParamField query="pageSize" type="integer">
  Profiles per page. Range: `20-200`. Defaults to `200`.
</ParamField>

<ParamField query="includeRetweetTimestamp" type="boolean" default="false">
  Look for each account's matching repost on its newest available profile page. Adds latency and
  returns `retweetedAt` as a UTC timestamp or `null`. Unavailable timestamps do not remove profile
  rows.
</ParamField>

<ParamField query="enrichProfiles" type="boolean" default="false">
  Set `true` to add each row's full profile, as `GET /x/users/{id}` returns it.
  Pages take several seconds longer. The price per row stays the same.
</ParamField>

## Which tweet engagement endpoint?

<CardGroup cols={2}>
  <Card title="Retweeters" icon="repeat-2">
    Use `GET /x/tweets/{id}/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="Quote tweets" icon="quote">
    Use [`GET /x/tweets/{id}/quotes`](/api-reference/x/tweet-quotes) when you
    need tweet rows that quote the 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="Saved exports" icon="file-spreadsheet">
    Use [`Create extraction`](/api-reference/extractions/create) with
    `toolType=repost_extractor` when you need a saved job or CSV, JSON, or XLSX
    export.
  </Card>

  <Card title="DM handoff" icon="send">
    Use [`Send DM`](/api-reference/x-write/send-dm) only after your workflow has
    a user-approved outreach step.
  </Card>
</CardGroup>

### User result filters

These filters apply before billing. Selective filters can return fewer rows.

<ParamField query="minFollowers" type="integer">
  Require this minimum follower count. Filtering happens before billing.
</ParamField>

<ParamField query="maxFollowers" type="integer">
  Allow this maximum follower count. Missing counts pass this filter.
</ParamField>

<ParamField query="minFollowing" type="integer">
  Require this minimum following count.
</ParamField>

<ParamField query="maxFollowing" type="integer">
  Allow this maximum following count. Missing counts pass this filter.
</ParamField>

<ParamField query="minStatuses" type="integer">
  Require this minimum post count.
</ParamField>

<ParamField query="maxStatuses" type="integer">
  Allow this maximum post count. Missing counts pass this filter.
</ParamField>

<ParamField query="minAccountAgeDays" type="integer">
  Require this minimum account age in days.
</ParamField>

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

<ParamField query="verifiedType" type="string">
  Match the exact verification type.
</ParamField>

<ParamField query="hasWebsite" type="boolean">
  When `true`, require a profile website.
</ParamField>

<ParamField query="hasLocation" type="boolean">
  When `true`, require a profile location.
</ParamField>

<ParamField query="bioContains" type="string">
  Require every comma-separated or line-separated bio term.
</ParamField>

<ParamField query="locationContains" type="string">
  Require this text in the profile location.
</ParamField>

<ParamField query="usernameContains" type="string">
  Require this text in the username.
</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

With `enrichProfiles=true`, each row carries the full profile. The
`x-xquik-profile-enrichment` header then counts the rows that have it, as in
`enriched=180; requested=200`. A row without it keeps its list fields.

<ResponseField name="users" type="object[]">
  Array of users who retweeted.
  **User object fields.**

  <ResponseField name="id" type="string">
    X user ID.
  </ResponseField>

  <ResponseField name="username" type="string">
    X username.
  </ResponseField>

  <ResponseField name="name" type="string">
    Display name.
  </ResponseField>

  <ResponseField name="description" type="string">
    Profile bio.
  </ResponseField>

  <ResponseField name="followers" type="number">
    This value records the follower count.
  </ResponseField>

  <ResponseField name="following" type="number">
    Following count.
  </ResponseField>

  <ResponseField name="verified" type="boolean">
    Verified status.
  </ResponseField>

  <ResponseField name="profilePicture" type="string">
    Profile image URL.
  </ResponseField>

  <ResponseField name="location" type="string">
    Profile location.
  </ResponseField>

  <ResponseField name="accountBasedIn" type="object | null">
    Country or region X shows for the account, with `value`, `level` & `observedAt`. X infers it from
    account access. It states no nationality or exact location. `null` when X shows none. Present with
    `enrichProfiles=true`, unless X withholds it.
  </ResponseField>

  <ResponseField name="accountBasedInUnavailable" type="boolean">
    `true` when X withheld `accountBasedIn` from this row. Retry later to get it. Omitted otherwise.
  </ResponseField>

  <ResponseField name="createdAt" type="string">
    Account creation date (ISO 8601).
  </ResponseField>

  <ResponseField name="statusesCount" type="number">
    This value records the total tweet count. X may omit it.
  </ResponseField>

  <ResponseField name="coverPicture" type="string">
    This value contains the cover image URL. X may omit it.
  </ResponseField>

  <ResponseField name="mediaCount" type="number">
    This value records the media tweet count. X may omit it.
  </ResponseField>

  <ResponseField name="url" type="string">
    Website URL from profile. Omitted if empty.
  </ResponseField>

  <ResponseField name="favouritesCount" type="number">
    This value records the liked tweet count. X may omit it.
  </ResponseField>

  <ResponseField name="hasCustomTimelines" type="boolean">
    X sets this flag for accounts with custom timelines. X may omit it.
  </ResponseField>

  <ResponseField name="isTranslator" type="boolean">
    X sets this flag for translator accounts. X may omit it.
  </ResponseField>

  <ResponseField name="withheldInCountries" type="string[]">
    Country codes where the account is withheld. Omitted if empty.
  </ResponseField>

  <ResponseField name="possiblySensitive" type="boolean">
    X sets this flag for sensitive accounts. X may omit it.
  </ResponseField>

  <ResponseField name="pinnedTweetIds" type="string[]">
    This array contains pinned tweet IDs. Omitted if none.
  </ResponseField>

  <ResponseField name="isAutomated" type="boolean">
    X sets this flag for automated accounts. X may omit it.
  </ResponseField>

  <ResponseField name="automatedBy" type="string">
    Username of the account operator if automated. Omitted if not automated.
  </ResponseField>

  <ResponseField name="unavailable" type="boolean">
    X sets this flag when it cannot return the account.
  </ResponseField>

  <ResponseField name="unavailableReason" type="string">
    X may give a reason for a missing account.
  </ResponseField>

  <ResponseField name="verifiedType" type="string">
    Verification type (for example `Business`, `Government`). Omitted if not verified or standard blue
    check.
  </ResponseField>

  <ResponseField name="profile_bio" type="object">
    Use this object for bio text and linked profile entities. X may omit it.
  </ResponseField>

  <ResponseField name="isBlueVerified" type="boolean">
    X sets this flag for X Premium verification. X may omit it.
  </ResponseField>

  <ResponseField name="isVerified" type="boolean">
    Use this field for normalized verification status. X may omit it.
  </ResponseField>

  <ResponseField name="profileBannerUrl" type="string">
    This value contains the profile banner URL. X may omit it.
  </ResponseField>

  <ResponseField name="protected" type="boolean">
    X sets this flag for protected accounts. X may omit it.
  </ResponseField>

  <ResponseField name="communityRole" type="string">
    Role within the requested community context. Omitted outside community results.
  </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.</ResponseField>

### 400 Invalid input or cursor

```json theme={null}
{
  "error": "invalid_cursor",
  "message": "Cursor invalid or expired. Start again without cursor, then use next_cursor."
}
```

A cursor X can't read returns `invalid_cursor`. Start again without `cursor`, then use
`next_cursor`. Other invalid input returns `invalid_input`. Both answers are free.

### 401 Unauthenticated

Anonymous requests receive `WWW-Authenticate: Bearer`. This is not a Payment challenge.

### 402 Payment required

Account keys receive account options. A guest wallet receives a checkout option.
Confirm any payment action.

<Note>
  **Related.** [Tweet favoriters](/api-reference/x/favoriters) · [Quote tweets](/api-reference/x/tweet-quotes) · [Tweet replies](/api-reference/x/tweet-replies)
</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.