> ## 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 retweet API: repost one tweet by ID

> Repost one tweet by ID from a connected X account. Approve the account, send an idempotency key, poll the action, then store billed credits and the result.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-write-retweet-200">
      ```json theme={null}
      {
        "object": "x_write_action",
        "id": "12345",
        "writeActionId": "12345",
        "action": "retweet",
        "status": "success",
        "terminal": true,
        "retryable": false,
        "safeToRetry": false,
        "statusUrl": "/api/v1/x/write-actions/12345",
        "pollAfterMs": null
      }
      ```
    </Tab>

    <Tab title="202" id="response-x-write-retweet-202">
      ```json theme={null}
      {
        "object": "x_write_action",
        "id": "12346",
        "writeActionId": "12346",
        "action": "retweet",
        "status": "dispatching",
        "terminal": false,
        "retryable": false,
        "safeToRetry": false,
        "statusUrl": "/api/v1/x/write-actions/12346",
        "pollAfterMs": 2000
      }
      ```
    </Tab>

    <Tab title="400" id="response-x-write-retweet-400">
      ```json theme={null}
      {
        "error": "missing_idempotency_key",
        "message": "Idempotency-Key is required. Generate one unique key for this write.",
        "charged": false,
        "chargedCredits": "0",
        "retryable": false,
        "safeToRetry": true
      }
      ```
    </Tab>

    <Tab title="401" id="response-x-write-retweet-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required. Provide a valid API key or bearer token."
      }
      ```
    </Tab>

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

    <Tab title="403" id="response-x-write-retweet-403">
      ```json theme={null}
      {
        "error": "account_needs_reauth",
        "message": "X account needs re-authentication. Re-add the account."
      }
      ```
    </Tab>

    <Tab title="404" id="response-x-write-retweet-404">
      ```json theme={null}
      {
        "error": "account_not_found",
        "message": "X account not found. Connect it first at /dashboard/account?tab=x-accounts."
      }
      ```
    </Tab>

    <Tab title="409" id="response-x-write-retweet-409">
      ```json theme={null}
      {
        "error": "idempotency_conflict",
        "message": "Idempotency-Key was already used with a different request.",
        "charged": false,
        "chargedCredits": "0",
        "retryable": false,
        "safeToRetry": true
      }
      ```
    </Tab>

    <Tab title="422" id="response-x-write-retweet-422">
      ```json theme={null}
      {
        "error": "x_rejected",
        "message": "X rejected this request. Check what you sent & the account on x.com before you try again."
      }
      ```
    </Tab>

    <Tab title="429" id="response-x-write-retweet-429">
      ```json theme={null}
      {
        "error": "x_rate_limited",
        "message": "X rate limited this account. Try again in about 15 minutes. Send fewer requests from this account."
      }
      ```
    </Tab>

    <Tab title="500" id="response-x-write-retweet-500">
      ```json theme={null}
      {
        "error": "x_write_failed",
        "message": "Write action failed unexpectedly. Contact support if this persists."
      }
      ```
    </Tab>

    <Tab title="503" id="response-x-write-retweet-503">
      ```json theme={null}
      {
        "error": "write_tracking_unavailable",
        "message": "Write tracking unavailable. Try again.",
        "charged": false,
        "chargedCredits": "0",
        "retryable": true,
        "safeToRetry": true
      }
      ```
    </Tab>
  </Tabs>
</Panel>

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

<Callout icon="coins" color="#5c3327">
  **10 credits per call** · [All plans](https://xquik.com/#pricing) from \$0.00012/credit
</Callout>

Each request reposts 1 tweet by ID.
Each request names 1 connected X account.
Review the source tweet before sending the write.
Then store the action and poll `statusUrl` until `terminal` is `true`.

Compare X's separate [Repost Post endpoint](https://docs.x.com/x-api/users/repost-post).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://xquik.com/api/v1/x/tweets/1895432178065391234/retweet \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -H "Idempotency-Key: retweet-1895432178065391234" \
    -H "Content-Type: application/json" \
    -d '{
      "account": "elonmusk"
    }' | jq
  ```

  ```javascript Node.js theme={null}
  const tweetId = "1895432178065391234";
  const response = await fetch(`https://xquik.com/api/v1/x/tweets/${tweetId}/retweet`, {
    method: "POST",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
      "Idempotency-Key": "retweet-1895432178065391234",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      account: "elonmusk",
    }),
  });
  const repostReceipt = await response.json();
  if (!response.ok) {
    throw new Error(JSON.stringify(repostReceipt));
  }
  ```

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

  tweet_id = "1895432178065391234"
  response = requests.post(
      f"https://xquik.com/api/v1/x/tweets/{tweet_id}/retweet",
      headers={
          "x-api-key": "xq_YOUR_KEY_HERE",
          "Idempotency-Key": "retweet-1895432178065391234",
      },
      json={
          "account": "elonmusk",
      },
  )
  repost_receipt = response.json()
  response.raise_for_status()
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
  )

  func main() {
      tweetID := "1895432178065391234"
      body, _ := json.Marshal(map[string]interface{}{
          "account": "elonmusk",
      })

      req, err := http.NewRequest("POST", "https://xquik.com/api/v1/x/tweets/"+tweetID+"/retweet", bytes.NewReader(body))
      if err != nil {
          panic(err)
      }
      req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")
      req.Header.Set("Idempotency-Key", "retweet-1895432178065391234")
      req.Header.Set("Content-Type", "application/json")

      resp, err := http.DefaultClient.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      var repostReceipt map[string]interface{}
      if err := json.NewDecoder(resp.Body).Decode(&repostReceipt); err != nil {
          panic(err)
      }
      fmt.Println(repostReceipt)
  }
  ```
</CodeGroup>

## Authenticate and approve the reposting account

Send an Xquik API key or OAuth 2.1 bearer token.
Name 1 connected X account in the request body.
Connect that account before scheduling or approving a repost.
Never send an X password or session cookie.

Review the source tweet just before approval.
Show its author, text, media, Tweet ID, and current availability.
Also show the X account that will publish the repost.
Use this review to avoid sharing from the wrong account.

Store these approval fields with the request:

| Approval field | Source | Purpose |
| - | - | - |
| Acting account | Request `account` | Identify the account publishing the repost. |
| Source Tweet ID | Path `id` | Keep the approved Tweet ID. |
| Source author | Tweet lookup | Keep original attribution in the review. |
| Approval time | Workflow clock | Record when the user approved distribution. |
| Approval owner | Workflow identity | Record who approved the repost. |
| Idempotency key | Request header | Bind retries to this exact decision. |

## Publish one repost by tweet ID

Resolve the Tweet ID before approval.
Show the source tweet, author, media, and acting account.
A repost keeps the original tweet and its author.

Assign a unique idempotency key to that repost decision.
Reuse it only after an interrupted response.
Store the action ID with the Tweet ID and acting account.

Repost workflows often include:

* Amplifying an approved announcement from a partner account.
* Reposting a customer reply selected by a support team.
* Sharing a monitored tweet after a moderation checkpoint.
* Preventing 2 workers from reposting the same tweet.

An accepted action may not appear on the account timeline yet.
Poll the lifecycle state while the action remains active.

| Repost action column | Source | Distribution rule |
| - | - | - |
| `acting_account` | Request `account` | Keep the connected account with the repost decision. |
| `tweet_id` | Path `id` | Use the exact source Tweet ID approved for distribution. |
| `source_author_id` | Review context | Store the original tweet author when available. |
| `approval_reference` | Workflow value | Link the repost to its campaign or moderation decision. |
| `idempotency_key` | Request header | Generate one key for this account and Tweet ID. |
| `write_action_id` | Response `id` | Store the repost action before polling. |
| `status` | Response `status` | Keep queued, completed, and failed reposts distinct. |
| `terminal` | Response `terminal` | Mark distribution complete only when `true`. |
| Request time | Integration timestamp | Save when the repost request starts. |

| Repost outcome | Evidence | Campaign action |
| - | - | - |
| Queued | `terminal: false` | Poll `statusUrl`. Do not count the repost yet. |
| Completed | Terminal success | Record the account, source Tweet ID, and completion time. |
| Already reposted | Terminal result that reports an existing repost | Complete without another repost request. |
| Retry allowed | `safeToRetry: true` | Keep the receipt. Follow `nextAction`. |
| Final failure | Terminal failure | Store the error and exclude the repost from completed totals. |

## Choose a repost or new tweet

Use a repost to share an existing tweet unchanged.
The request adds no comment, caption, or reply text.

Use [Create Tweet](/api-reference/x-write/create-tweet) for original posts and replies.
A reply needs `reply_to_tweet_id`.

| Publishing intent | API route | Required content |
| - | - | - |
| Share an existing tweet unchanged | `POST /x/tweets/{id}/retweet` | Source tweet ID and connected account |
| Publish original text | `POST /x/tweets` | New tweet text and connected account |
| Reply to a tweet | `POST /x/tweets` | Reply text and `reply_to_tweet_id` |
| Remove a repost | `DELETE /x/tweets/{id}/retweet` | Source tweet ID and connected account |

Show the source tweet during approval.
Store its author, text, media, and Tweet ID.
Never replace that ID with a search-result position.

## Reconcile retweet automation

Store one receipt per connected account and source tweet. This key prevents
2 workers from counting the same repost as separate campaign results.

Keep queued, completed, already-reposted, and failed outcomes distinct.
Mark an already-reposted outcome complete.
It does not create a second repost.

Use [Unretweet](/api-reference/x-write/unretweet) for an approved rollback.
The rollback needs a new idempotency key. Store both action IDs. The
campaign record then shows the repost and its later removal.

## Schedule retweets without duplicate posts

This endpoint starts the repost action when it receives the approved request.
Use your scheduler when a repost must run later.
Store the Tweet ID, account, time zone, and approval together.
Recheck the source tweet before dispatch.

Create the idempotency key once the schedule is final.
Reuse that key after a network interruption.
Never reuse it for another account, Tweet ID, or scheduled time.

The endpoint accepts 1 Tweet ID per request.
It has no bulk repost body.
Queue several approved tweets as separate jobs.
Store each action before starting the next job.

After `429`, honor `Retry-After`.
Do not rotate connected accounts to bypass a limit.
Delay the existing job instead of creating a duplicate.

## Verify repost completion and attribution

Store `id` as the write action ID.
Store `request.hash` with the submitted account and Tweet ID.
Keep `status`, `terminal`, `statusUrl`, and `safeToRetry` together.
Store `billing.chargedCredits` after billing settles.

Treat `202` as active work, not a completed repost.
Poll the same `statusUrl` until `terminal` becomes `true`.
Never send another repost while the action remains active.

After success, compare the returned target with the approved Tweet ID.
Mark an already-reposted outcome complete.
It does not create another timeline entry.

The repost keeps the source tweet's original attribution.
Use [Retweeters](/api-reference/x/retweeters) for available account-level evidence.
Timeline visibility can lag behind a completed write receipt.
Keep read time separate from repost completion time.

## Handle Twitter retweet API errors

Keep every error beside the request hash and action ID.
Never swap in another Tweet ID as a fallback.

* `400`: Correct the Tweet ID or account value.
* `401`: Replace invalid Xquik authentication.
* `402`: Add credits before another repost request.
* `403`: Reconnect the selected X account.
* `409`: Keep the action protected by that idempotency key.
* `422`: Review X's rejection before another attempt.
* `429`: Honor `Retry-After` before polling or retrying.
* `500`: Store the failure. Contact support if it persists.
* `503`: Check `safeToRetry` before retrying.

A client timeout does not prove the repost failed.
Check any returned action before sending another write.
Use `nextAction` to choose the next step.

## Apply repost bot and campaign controls

Require approval for the exact account and source tweet.
Use campaign allowlists for authors, topics, or Tweet IDs.
Set a per-campaign repost limit before dispatch begins.
Keep separate limits for each connected account.

Lock the approved tweet list before processing.
Record skipped, active, completed, and failed jobs separately.
Never count an accepted action as completed.

Inspect unavailable tweets instead of substituting new content.
Keep deleted or restricted source tweets as distinct outcomes.
Do not turn a failed repost into an original tweet in code.

Store the approval, request, action, billing, and final result.
These records support audits without exposing account credentials.

## Twitter retweet API questions

### How do I automate a retweet through an API?

Approve the Tweet ID and connected account.
Send this request, then poll the write action until terminal.

### How do I authenticate a Twitter API retweet?

Send an Xquik API key or OAuth 2.1 bearer token.
Never send an X password or session cookie.

### Can I schedule a retweet?

Call this endpoint from your scheduler after approval.
The endpoint stores no future schedule.

### What is the retweet API rate limit?

After `429`, honor `Retry-After` before another request.
X publishes separate [Repost rate limits](https://docs.x.com/x-api/fundamentals/rate-limits).

### Is a retweet the same as a quote tweet?

No. This route reposts the existing tweet unchanged.
It cannot add a quote comment or new media.

### Can I bulk retweet several tweet IDs?

No bulk request exists here.
Approve and submit each Tweet ID separately.

### How do I track retweet activity?

Poll this write action for completion.
Use [Retweeters](/api-reference/x/retweeters) to read available reposting accounts.

### Why can a Twitter retweet API request fail?

The account may need reconnection, credits, or a later retry.
The source tweet may also be unavailable or rejected by X.

### Does a repost keep the original author?

Yes. A repost references the source tweet and its author.
This endpoint adds no replacement caption or attribution.

### Can I undo an API retweet?

Yes. Call [Unretweet](/api-reference/x-write/unretweet) after new approval.
Use a new idempotency key for that removal.

### Can a bot use this retweet API?

Yes. Keep credentials server-side and require clear account authorization.
Apply approvals, limits, idempotency, and terminal polling to every job.

### Do I need a Twitter retweet SDK?

No. Call this REST endpoint with any HTTP client.
Use the cURL, Node.js, Python, or Go examples above.

## Headers

<ParamField header="x-api-key" type="string">
  Send your Xquik API key. Generate one from the [dashboard](https://xquik.com/dashboard).
</ParamField>

<ParamField header="Authorization" type="string">
  Send `Bearer <token>` instead of `x-api-key` when using OAuth 2.1.
</ParamField>

<ParamField header="Idempotency-Key" type="string" required>
  Unique key for this intended write. Reuse it only for an exact network replay.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`.
</ParamField>

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

## Body

<ParamField body="account" type="string" required>
  X username or account ID identifying which connected X account will retweet. Xquik strips the `@` prefix if included.
</ParamField>

## Response

## Durable write recovery

<Warning>
  Send one unique `Idempotency-Key` per intended write.
  Replay the same account, target, payload, and media after a lost response.
  Keep the original key for that replay.
</Warning>

1. Store `id`, the nested `hash` in `request`, `billing`, and `statusUrl`.
2. Poll after `Retry-After` or `pollAfterMs` when `terminal` is `false`.
3. Retry only when `safeToRetry` is `true`.
4. Use a new key when `nextAction.requiresNewIdempotencyKey` is `true`.

### 200 terminal or 202 active

* After HTTP `200`, store the result and settled billing.
* After HTTP `202`, poll the same action. Never submit another write.
* After HTTP `400`, fix the named field. Use a new idempotency key.
* After HTTP `401`, fix authentication. Do not retry unchanged.
* After HTTP `402`, fund the account before another write.
* After HTTP `403`, reconnect the account.
* After HTTP `409`, keep the original action. Use a new key for new input.
* After HTTP `422`, fix the rejected request before retrying.
* After HTTP `429`, wait for `Retry-After`. Follow `nextAction`.

See [Get Write Action Status](/api-reference/x-write/get-write-action-status)
for every lifecycle field, terminal state, billing field, and retry rule.


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