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

# How to undo a retweet with the Twitter API

> Undo one retweet by Tweet ID from a connected X account. Poll the write action, verify completion, and handle errors. The source tweet stays. 10 credits.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-write-unretweet-200">
      ```json theme={null}
      {
        "object": "x_write_action",
        "id": "12345",
        "writeActionId": "12345",
        "action": "unretweet",
        "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-unretweet-202">
      ```json theme={null}
      {
        "object": "x_write_action",
        "id": "12346",
        "writeActionId": "12346",
        "action": "unretweet",
        "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-unretweet-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-unretweet-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-unretweet-402">
      ```json theme={null}
      {
        "error": "insufficient_credits",
        "message": "Insufficient credits. Top up or subscribe to continue."
      }
      ```
    </Tab>

    <Tab title="403" id="response-x-write-unretweet-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-unretweet-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-unretweet-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-unretweet-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-unretweet-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-unretweet-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-unretweet-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 removes 1 repost by Tweet ID.
Name the connected X account that owns the repost.
Then poll `statusUrl` until `terminal` becomes `true`.

The route keeps the source tweet and its original author.
It does not remove likes, follows, replies, bookmarks, or original tweets.

Compare X's separate [Unrepost Post endpoint](https://docs.x.com/x-api/users/unrepost-post).
X also publishes a [Retweet management guide](https://docs.x.com/x-api/posts/retweets/quickstart/manage-retweets).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://xquik.com/api/v1/x/tweets/1895432178065391234/retweet \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -H "Idempotency-Key: unretweet-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: "DELETE",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
      "Idempotency-Key": "unretweet-1895432178065391234",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      account: "elonmusk",
    }),
  });
  const unretweetReceipt = await response.json();
  if (!response.ok) {
    throw new Error(JSON.stringify(unretweetReceipt));
  }
  ```

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

  tweet_id = "1895432178065391234"
  response = requests.delete(
      f"https://xquik.com/api/v1/x/tweets/{tweet_id}/retweet",
      headers={
          "x-api-key": "xq_YOUR_KEY_HERE",
          "Idempotency-Key": "unretweet-1895432178065391234",
      },
      json={
          "account": "elonmusk",
      },
  )
  unretweet_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("DELETE", "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", "unretweet-1895432178065391234")
      req.Header.Set("Content-Type", "application/json")

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

      var unretweetReceipt map[string]interface{}
      if err := json.NewDecoder(resp.Body).Decode(&unretweetReceipt); err != nil {
          panic(err)
      }
      fmt.Println(unretweetReceipt)
  }
  ```
</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.
Never send an X password or session cookie.

Show the specific tweet and acting account before approval.
Include the author, text, media, Tweet ID, and removal reason.

## Remove one repost by tweet ID

Resolve the source Tweet ID before approval.
Do not use a timeline position or search-result index.
Send the ID as a string to keep every digit.

Generate a new idempotency key for the removal.
Do not reuse the key from the original repost.
Reuse the key only after an interrupted response.

Store the action ID before starting another removal.
Poll `statusUrl` while `terminal` is `false`.

## Choose unretweet, delete tweet, or unlike

Use Unretweet for an unchanged repost of someone else's tweet.
It removes only the acting account's repost relationship.
Use [Delete Tweet](/api-reference/x-write/delete-tweet) for original or quote tweets.
Use [Unlike Tweet](/api-reference/x-write/unlike) for likes.

X Premium's Undo Post feature is different.
It delays publication during a short preview window.
Unretweet removes a repost that already exists.

## Verify repost removal and timeline state

Store `id` as the write action ID.
Poll the same `statusUrl` until `terminal` becomes `true`.
Store the account, source Tweet ID, request hash, billing, and both action IDs.
Close already-removed actions without another request.
Keep the prior repost state after a final failure.

A cached timeline can lag behind the write result.
X documents that delay in its [repost help](https://help.x.com/en/using-x/how-to-repost).

## Schedule repost cleanup without bulk unretweet

Use your scheduler when a repost should end later.
The endpoint accepts 1 Tweet ID per request.
It has no bulk unretweet body.
To delete retweets in a queue, approve each Tweet ID separately.

## Handle Twitter undo retweet errors

Fix the ID or account after `400`.
Replace Xquik authentication after `401`. Reconnect the account after `403`.
Add credits after `402`. Review rejected input after `422`.
Honor `Retry-After` after `429`.
After `500` or `503`, check `safeToRetry` before retrying.
Use `nextAction` to choose the next step.

## Twitter undo retweet questions

### How do I undo a retweet on Twitter with an API?

Approve the account and source Tweet ID.
Send this DELETE request. Poll until terminal.

### Can I undo recent, old, or several retweets?

Submit recent or old removals individually.
The X Premium Undo Post window does not limit this endpoint.

### Why can't I undo a retweet on Twitter?

Check authentication, credits, account connection, and the source tweet.

### What happens to the tweet, engagement, and notifications?

Unretweet keeps the source tweet and author intact.
It does not change likes, replies, bookmarks, or source content.
The action does not track notification delivery.
Cached timelines can lag behind the terminal result.

### Do I use a Twitter archive, retweet icon, or delete button?

A Twitter archive can help identify an old source Tweet ID.
In X, use the green retweet icon for reposts.
Use a delete button to delete tweets you published.
Never delete the original source tweet during an unretweet.

## 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>
  Source 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 that owns the repost. The `@` prefix is optional.
</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.