---
title: "Twitter API Error Codes and HTTP Status Reference"
description: "Troubleshoot Twitter/X API errors in TwexAPI: HTTP 401, 403, 429 and 5xx, invalid auth_token, duplicate tweets, DM limits, and safe retries."
lastModified: "2026-10-08"
sidebar:
  label: "Error Reference"
seo:
  title: "Twitter API Error Codes: 401, 403, 429 and Retries"
search:
  tags: ["Twitter API error codes", "X API errors", "invalid auth_token", "429 Too Many Requests", "twitter_error_code"]
---

TwexAPI reports Twitter/X API failures through HTTP status codes and, when available, upstream X error codes. A `401` needs a credential fix, a `403` needs an access or account fix, and a `429` needs a rate-limit wait. Check the response body before retrying.

Use this reference to troubleshoot Twitter API error codes, `invalid auth_token`, duplicate tweets, and DM limits. Endpoint paths follow the current [API reference](/api-reference/overview). For MCP errors, pagination recovery, and SDK examples, see [Error Handling](/guides/error-handling).

Messages and upstream codes below are troubleshooting examples; response shapes and HTTP mappings can vary by endpoint. Use the endpoint schema and the actual response together.

## Find the right Twitter API error fix

- **HTTP 401 / `Invalid auth_token`**: check both your TwexAPI API key and the X session credentials used by write endpoints. See [Authentication](/authentication#write-operations--byoc-bring-your-own-cookie).
- **HTTP 403**: inspect the message for insufficient credits, protected posts, account restrictions, or Premium requirements. Repeating an unchanged request does not restore access.
- **HTTP 429 / `Too Many Requests`**: honor `Retry-After` or `retry_after`, and distinguish request throttling from an X account's daily limit. See [Rate Limits](/guides/rate-limits).
- **HTTP 500 / 502 / 503**: retry transient read failures with capped backoff. Check whether a write already succeeded before repeating it.
- **X codes 187, 344, or 502**: these are upstream X codes, separate from HTTP status codes. Check the [Twitter/X code table](#twitterx-api-error-codes) and the [retry questions](#twitter-api-error-and-retry-questions).

## Error response format

Preserve the HTTP status and full JSON body. TwexAPI responses can include `code` and `msg`; request validation errors use `detail`:

```json
{
  "code": 500,
  "msg": "Internal server error"
}
```

```json
{
  "detail": [
    {
      "loc": ["body", "cookie"],
      "msg": "Field required",
      "type": "missing"
    }
  ]
}
```

If the response includes additional upstream metadata, retain it:

- **`error`**: an error message, when supplied. Do not assume every endpoint uses this field.
- **`twitter_error_code`**: an X error code, when supplied. It is separate from the HTTP status; X code `502`, for example, refers to a DM limit.
- **`retry_after`**: seconds to wait, when supplied. Also honor the HTTP `Retry-After` header.

Do not require optional fields to exist or branch only on exact message text. A non-`2xx` HTTP status is a failure even if the body contains a different `code`.

## Common errors (all endpoints)

Check these conditions on any request. Exact messages can vary.

| Status | Message | What it means | What to do |
| --- | --- | --- | --- |
| **401** | `Invalid or missing API key` | Your API key is missing or wrong | Check your `Authorization: Bearer <key>` header |
| **400** | `Missing required … param: <x>` | A required field/parameter is missing or invalid | Fix the request |
| **429** | `Please try again shortly.` (our capacity) · `Rate limit exceeded…` · or an X-side limit message | Too many requests, our capacity, or an **X account limit** (e.g. daily DM/tweet limit, these may include a `twitter_error_code`) | Honor `retry_after` / `Retry-After`; account daily limits need a longer wait |
| **403** | Credits exhausted or access denied | Insufficient credits or account permissions | Check balance and account access |
| **422** | Validation error (`detail`) | Request fields failed schema validation | Fix the fields listed in `detail`; do not retry unchanged |
| **500** | `Internal server error` | A temporary error occurred | Retry shortly |

:::warning
**Two kinds of 401.** A `401` at the API level means your **API key** is wrong. On write endpoints (posting, liking, profile updates), a `401` can also mean the **X session credentials you supplied in `cookie`** are invalid or expired; the message may say `Invalid auth_token` or `Could not authenticate you`. Refresh the X session credentials in that case. See [Authentication](/authentication#write-operations--byoc-bring-your-own-cookie).
:::

## Twitter API HTTP status codes

| Status | Meaning |
| --- | --- |
| **200** | Success |
| **202** | Accepted; if an endpoint returns this status, the action is pending |
| **400** | Bad request, missing/invalid parameters, invalid proxy URL, or media too large |
| **401** | Unauthorized, bad API key or invalid/expired `auth_token` |
| **403** | Forbidden — insufficient credits, a **protected/private or suspended target account** (its posts can't be read), a suspended/locked account you're using, a permission restriction, or a Premium-only action |
| **404** | Not found, the user, tweet, or resource doesn't exist |
| **409** | Conflict, duplicate tweet |
| **410** | Resource unavailable; inspect the body for account suspension details |
| **422** | Request validation failed; inspect `detail` and fix the input |
| **423** | If returned by X: the account is locked or needs verification |
| **429** | Too many requests, a rate limit was hit |
| **500 / 502 / 503** | Temporary server or upstream error, retry |

## Twitter/X API error codes

When an upstream X code is included in the response, use the following meanings. These are **X codes**, not HTTP statuses, and not every endpoint exposes `twitter_error_code`.

| Code | Meaning | What to do |
| --- | --- | --- |
| **32** | Could not authenticate you | Refresh the X session credentials supplied in `cookie` |
| **63** | The target account is suspended | Use an accessible account or wait for access to be restored |
| **64** | Your account is suspended | Use a different account |
| **131** | Temporary X internal error | Retry |
| **139** | Already liked | Confirm the current state; do not repeat the action |
| **144** | No tweet found with that ID | The tweet was deleted or the ID is wrong |
| **187** | Duplicate tweet | Confirm the previous post, then change the text if a new post is intended |
| **226** | Request looked automated | Retry |
| **326** | Account temporarily locked | Unlock at `x.com/account/access`, then retry |
| **327** | Already retweeted | Confirm the current state; do not repeat the action |
| **344** | Posting temporarily limited (network/IP throttle, not the account) | Back off and check the proxy if supplied; confirm the write outcome before retrying |
| **349** | Cannot message this user | The recipient doesn't accept your DMs |
| **399** | X session login failed | Check the X session credentials |
| **433** | Reply restricted / Premium required | The tweet is reply-gated, or the action needs X Premium |
| **465** | Cannot retweet an outdated tweet | The tweet is too old to retweet |
| **476** | Not allowed to send message requests | The account can't send DM requests |
| **502** | Daily DM (message request) limit reached | Wait 24 hours, or use an X Premium account for higher limits |

## Reading tweets & search

Applies to **POST** `/twitter/{screen_name}/timeline/page`, `/twitter/tweets-replies/page`, and `/twitter/advanced_search/page`.

| Status | Message | What to do |
| --- | --- | --- |
| **403** | `This account's posts are not available. The account is protected (private), suspended, or no longer active.` | **Don't retry unchanged** — access must change before the request can succeed. The target's posts aren't readable by anyone who isn't an approved follower. Point the request at a public account. |
| **403** | `This account is suspended, so its posts are not available.` | The target account is suspended. Use an accessible account or wait for access to be restored. |
| **502** | `Upstream returned an unexpected response — please retry.` | An upstream failure. **Retry with capped backoff**; preserve the same cursor. |

:::info
A `403` caused by a **protected/suspended target** needs an access or account change. A `502` can be transient. Inspect the status and body before choosing a retry policy.
:::

## Posting & engagement

### Create Tweet

**POST** `/twitter/tweets/create`

Use `tweet_content`, optional `reply_tweet_id`, and your X credentials in `cookie`. See [Create a Tweet or Reply](/api-reference/tweet-actions-endpoints/create-tweet-twitter-tweets-create-post).

| Status | Code | Message | What to do |
| --- | --- | --- | --- |
| **409** | 187 | `Status is a duplicate.` | Check whether the post already exists; change the text for a new post |
| **403** | 433 | `The original Tweet author restricted who can reply…` | The tweet doesn't allow your reply |
| **403** | 433 | Long-form / long-video needs Premium | Use a Premium account or shorten the content |
| **403** | n/a | Not a member of the community | Join the community first |
| **429** | 344 | Posting temporarily limited (network/IP throttle) | Back off; check the supplied proxy and confirm whether the post was created |
| **502** | n/a | `X returned an empty result` (outcome unconfirmed) | Read the account timeline before retrying; the write outcome is unconfirmed |
| **400** | n/a | `File size exceeds…` | Reduce the media file size |
| **503** | 226 | `This request looks automated` | Back off and check the write outcome before retrying |
| **502 / 503** | n/a | Temporary connection error | Retry (if you supplied a `proxy`, confirm it's working) |

### Favorite / Retweet / Bookmark

**POST** `/twitter/tweets/{tweet_id}/like` · `/twitter/tweets/{tweet_id}/retweet` · `/twitter/tweets/{tweet_id}/bookmark`

**DELETE** `/twitter/tweets/{tweet_id}/like` · `/twitter/tweets/{tweet_id}/retweet` · `/twitter/tweets/{tweet_id}/bookmark`

| Status | Code | Message | What to do |
| --- | --- | --- | --- |
| **403** | n/a | `User is suspended, deactivated or offboarded` | The account is unavailable; switch accounts |
| **401** | 32 | `Could not authenticate you` | Refresh the X session credentials supplied in `cookie` |
| **403** | 465 | `not permitted to retweet an outdated Tweet` | The tweet is too old to retweet |
| Varies | 139 / 327 | already liked / already retweeted | Confirm the current state; do not repeat the action |
| **429** | n/a | Rate limit | Slow down, then retry |
| **502 / 503** | n/a | Temporary connection error | Retry |

### Delete Tweet

**POST** `/twitter/tweets/delete-batch`

Supply `target_id` to delete one tweet. Omitting it selects bulk deletion; preserve the original request fields when recovering from errors.

| Status | Message | What to do |
| --- | --- | --- |
| **404** | `No status found with that ID` | Already deleted or wrong ID |
| **403** | Not the author | You can only delete your own tweets |
| **401** | Invalid `auth_token` | Refresh the X session credentials |

### Follow / Unfollow

**POST** `/twitter/user/follow` · **DELETE** `/twitter/user/follow`

| Status | Message | What to do |
| --- | --- | --- |
| **404** | `User not found` | Check the handle/ID |
| **403** | Restricted | The account or target doesn't allow it |
| **401** | Invalid `auth_token` | Refresh the X session credentials |
| **429** | Follow limit | Wait, then retry |

### Update Profile / Avatar / Banner

**POST** `/twitter/profile`

Use `profile_image` and `profile_banner` for image URLs, and `cookie` for X credentials.

| Status | Message | What to do |
| --- | --- | --- |
| **401** | `Invalid auth_token - could not fetch credentials` | Refresh the X session credentials |
| **400** | Image too large / bad format | Fix the image |

## Media attachments

Attach media when creating tweets or sending DMs; there is no separate media-upload route in the current reference. For tweet creation, `media_urls` supports up to four images, one GIF, or one video. Do not mix a GIF/video with other media. Fix inaccessible URLs, unsupported formats, or rejected file sizes before retrying. Follow the endpoint schema for field names and constraints.

## Direct Messages

**POST** `/v3/twitter/send-dm` · `/v3/twitter/dm-history` · `/v3/twitter/conversations`

For permission checks, use **POST** `/v2/dm/status`. See [Send DM](/api-reference/dm-endpoints/send-dm-api-v3-v3-twitter-send-dm-post).

| Status | Code | Message | What to do |
| --- | --- | --- | --- |
| **429** | 502 | `You've hit your daily message request limit. Subscribe to Premium for higher limits.` | Wait 24h, or use a Premium account |
| **403** | 476 | `Sender is not verified to send message requests` | The account can't send DM requests |
| **403** | 349 | `Cannot send messages to this user` | The recipient doesn't accept your DMs |
| **401** | 32 | `Could not authenticate you` | Refresh the X session credentials |
| **404** | n/a | Conversation / user not found | Check the recipient |

## Reading data

**POST** `/v2/tweet/detail` · `/twitter/tweets/lookup` · `/twitter/users/by_ids` · `/v3/twitter/users/followers` · `/v3/twitter/users/following` · `/twitter/tweets/thread_by_id` · `/twitter/tweets/{tweet_id}/replies/page`

**GET** `/twitter/{screen_name}/about` · `/twitter/search-user/{keyword}/{target_count}`

| Status | Message | What to do |
| --- | --- | --- |
| **404** | `Tweet not found: <id>` | The tweet was deleted, is protected, or the ID is wrong |
| **404** | `Could not resolve userId for @<handle>` | The handle doesn't exist, was renamed, or is suspended |
| **404** | `Could not find user with ID: <id>` | Check the user ID |
| **400** | `Missing required query param: <x>` | Provide the required parameter |
| **429** | Rate limit | Wait `retry_after`, then retry |

:::info
**Region-restricted content.** X access restrictions can depend on location, including the exit location of a supplied proxy. Inspect the response and the target’s availability; do not assume that API access bypasses regional restrictions.
:::

## Articles

**POST** `/x/article` · **GET** `/x/article/{tweet_id}/markdown`

For writes: **POST** `/x/articles/draft` · **PUT** `/x/articles/{article_id}/cover` · `/x/articles/{article_id}/title` · `/x/articles/{article_id}/content` · **POST** `/x/articles/{article_id}/publish` or `/x/articles/publish`.

The Premium requirement below applies to publishing articles. Prefer the [step-by-step article flow](/api-reference/article-endpoints/article-create-draft-x-articles-draft-post) so you can preserve `article_id` and retry only the failed step.

| Status | Message | What to do |
| --- | --- | --- |
| **403** | Premium required | Article publishing requires an X Premium account |
| **404** | Article not found | Check the article ID |
| **401** | Invalid `auth_token` | Refresh the X session credentials |
| **400** | Invalid content | Fix the article body |

## Retry guide

| You see… | Retry? | Notes |
| --- | --- | --- |
| **429** | ✅ after the indicated wait | Honor account daily limits as well as request rate limits |
| **422** | ❌ | Fix the fields listed in the validation response |
| **500 / 502 / 503** | ✅ | Temporary, retry shortly |
| **X code 226** | After checking the write outcome | Back off; inspect account restrictions before retrying |
| **401** | ❌ | Fix your API key or refresh the X session credentials |
| **403** (suspended/locked) | ❌ | Use a different account, or unlock it first |
| **404** | ❌ | Check the ID/handle |
| **400 / 409** | ❌ | Fix the request (params, media size, duplicate text) |

**Tip:** Use capped backoff with jitter for `429` and transient `5xx`. For `400`/`401`/`403`/`404`/`409`/`422`, fix the input, credentials, or account access first.

:::warning Write retries
After a timeout, empty response, or `5xx` on a write, check the timeline, DM history, or engagement state before sending the action again. Do not assume a failed response means the action never happened.
:::

## Twitter API error and retry questions

### Why does the Twitter API return 401 or invalid auth_token?

HTTP `401` can mean your TwexAPI API key is missing or invalid. On write endpoints, `Invalid auth_token` or X code `32` can also mean the X session has expired. Fix the Bearer header or refresh the X credentials supplied in `cookie` before retrying.

### What is the difference between Twitter API errors 403 and 429?

HTTP `403` indicates an access problem, such as insufficient credits, private content, a restricted account, or a Premium-only action. HTTP `429` indicates a request or account limit. Fix the cause of a `403`; wait for the indicated limit to reset after a `429`.

### How do I fix Twitter API 429 Too Many Requests?

Wait for `Retry-After` or `retry_after` when provided, then resume with lower concurrency and capped backoff. A daily tweet or DM limit needs its reset period, not just a short delay. Preserve the failed page's cursor when retrying a read.

### What does Twitter error code 187 mean?

X error code `187` means duplicate tweet content. Check whether the previous write already created the post. If you intend to publish a different post, change `tweet_content` instead of repeating the same request.

### What does Twitter error code 344 mean?

X error code `344` indicates a temporary posting restriction associated with the network or IP. Back off, check any proxy you supplied, and inspect the account timeline before retrying the write. It is an X error code, not an HTTP status code.

### Should I retry Twitter API errors 500, 502, or 503?

Retry transient read failures with capped backoff and jitter. After a write times out or returns `5xx`, first inspect the timeline, DM history, or engagement state. A failed response does not prove that the write was never applied.

### Should I retry a TwexAPI 422 validation error?

Do not retry the same input. TwexAPI uses HTTP `422` for request validation errors. Inspect `detail` for the failing field, location, and type, then correct the request according to the endpoint schema.

### Is Twitter error code 502 the same as HTTP 502?

No. X error code `502` refers to a daily DM request limit and can accompany HTTP `429`. HTTP `502` indicates an upstream response failure. Read both the HTTP status and `twitter_error_code`, when provided, before choosing a retry policy.

## Related pages

- [Error Handling](/guides/error-handling) — MCP, SDKs, and pagination recovery
- [Authentication](/authentication) — API keys and X session credentials
- [Rate Limits](/guides/rate-limits) — backoff and throughput
- [API Overview](/api-reference/overview) — current endpoint reference
