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

# Remove Twitter likes API: unlike a tweet by ID

> Unlike one tweet by ID from a connected X account. Store the acting account, write action, terminal result, and billed credits. Each call costs 10 credits.

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

    <Tab title="403" id="response-x-write-unlike-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-unlike-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-unlike-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-unlike-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-unlike-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-unlike-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-unlike-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 unlikes 1 tweet by ID.
It changes 1 connected account's like state.
It never deletes the tweet, replies, reposts, or another account's likes.

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

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

## Remove one Twitter like by ID

Put the exact Tweet ID in the path.
Put its connected X account in the body.
This endpoint accepts 1 Tweet ID per request.
Store Tweet IDs as strings to preserve large identifiers.

## Authenticate the Twitter account

Send an Xquik API key or OAuth 2.1 bearer token.
The request never accepts an X password or session cookie.
Keep credentials in server-side code.
Reconnect the account after `account_needs_reauth`.

## Approve the exact like removal

Show the tweet, author, Tweet ID, and acting account.
Store the approver, approval time, and removal reason.
Handle missing, private, or deleted tweets separately.
Never replace an approved ID with another tweet.

## Save an unlike receipt

Save the action before changing your local like record.

| Unlike action column | Source | Removal rule |
| - | - | - |
| `acting_account` | Request `account` | Match the account that owns the original like. |
| Tweet ID | Path `id` | Keep the exact liked Tweet ID. |
| `removal_reason` | Workflow value | Record why the user removed the like. |
| `idempotency_key` | Request header | Create a fresh removal key. |
| `write_action_id` | Response `id` | Store the removal action. |
| `terminal` | Response `terminal` | Change the local state only when `true`. |

## Confirm like removal

A `200` response is terminal.
A `202` response still needs polling through `statusUrl`.
Never resend an active action.
After success, match the returned and requested Tweet IDs.
If X reports no existing like, mark the account as unliked.

Keep the prior state while `terminal` is `false`.
Store the settled `billing` object after completion.
Close already-unliked actions without another request.

## Remove Twitter likes in a controlled queue

This route has no mass-delete request.
Process approved Tweet IDs separately.
Give each account and Tweet ID a unique key.
Use [User Likes](/api-reference/x/user-likes) to collect candidate IDs. X shows likes only to their owner. That read can return `424 likes_unavailable`.
Follow every cursor before approving the list.
After `429`, wait for `Retry-After`.
Never rotate accounts to bypass limits.
Review X's separate [Unlike rate limits](https://docs.x.com/x-api/fundamentals/rate-limits).

## Prevent duplicate unlike requests

Create one idempotency key per account and Tweet ID.
Reuse it only after an interrupted response.
A `409` means that key already belongs to another payload.
Create a new key only for a new removal intent.

## Handle remove Twitter likes errors

Never infer failure from a client timeout.
Poll the returned action before another request.

* `400`: Correct the Tweet ID or account.
* `401`: Replace invalid Xquik authentication.
* `402`: Add credits before another unlike.
* `403`: Reconnect the selected X account.
* `409`: Keep the original action and payload.
* `422`: Review X's rejection.
* `429`: Honor `Retry-After` before retrying.
* `500` or `503`: Follow `safeToRetry` and `terminal`.

## Choose unlike, delete, or unretweet

Use this route only to remove one account's like.

Use [Like Tweet](/api-reference/x-write/like) to restore a like.
Use [Delete Tweet](/api-reference/x-write/delete-tweet) for an owned tweet.
Use [Unretweet](/api-reference/x-write/unretweet) for a repost.
Unlike never removes replies, follows, bookmarks, or accounts.

## Remove Twitter likes questions

### How to remove a like on Twitter with an API?

Send the Tweet ID and connected account.
Poll the write action until it becomes terminal.

### Can I remove all Twitter likes at once?

No. Process each approved Tweet ID separately.
Store one key and action per removal.

### Can I remove likes for multiple Twitter accounts?

Yes. Name one connected account per request.
Keep its approval, key, and receipt together.

### What are the risks of third-party like removal tools?

Never share your X password or session cookie.
Review every account and Tweet ID.

### Can I schedule Twitter like removal?

Use your scheduler for approved Tweet IDs.
This endpoint stores no future schedule.

### Does unliking delete the original tweet?

No. It changes only the connected account's like state.

### Can I restore a removed like?

Yes. Call [Like Tweet](/api-reference/x-write/like) after new approval.
Use a new key.

### Does removing a like erase every historical record?

No. Earlier logs, exports, screenshots, or audits may remain.
Do not treat a Twitter archive as proof of the current like state.

## Headers

<ParamField header="x-api-key" type="string">
  Send your Xquik API key in this header. Alternatively, send an OAuth 2.1 bearer token.
</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 for the connected account. Xquik removes an included `@` prefix.
</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.