# X API Rate Limits: Per-Endpoint Limits and 429 Fixes

X API v2 rate limits by endpoint: 100 posts per user per 15 minutes, 10,000 per app per day, the x-rate-limit headers, and how to handle a 429.

Canonical page: https://www.tryadeli.com/blog/x-api-rate-limit
Last updated: 2026-10-26

By Mika Reyes, Co-founder, Adeli. Published 2026-10-26.

## The short answer

X API v2 rate limits are set per endpoint, usually per 15-minute window. POST /2/tweets allows 100 posts per user every 15 minutes and 10,000 per app every 24 hours. Every response carries x-rate-limit-limit, x-rate-limit-remaining, and x-rate-limit-reset headers. Going over returns 429 with error code 88: wait for the reset time, then retry with jitter. Adeli runs the X app and refreshes tokens for you.

X API rate limits cap how many requests you can make to each endpoint in a time window, usually **15 minutes**. For posting, `POST /2/tweets` allows **100 requests per user per 15 minutes** and **10,000 per app per 24 hours**. Every response tells you where you stand through three `x-rate-limit-*` headers, and going over returns **`429 Too Many Requests`** until the window resets.

This post lists the limits by endpoint, shows how to read the headers, and gives retry code for a 429. Every number comes from [X's rate limits page](https://docs.x.com/x-api/fundamentals/rate-limits), checked on 2026-10-26. For the wider picture of the API, start with our [X API guide](https://www.tryadeli.com/blog/x-api-guide).

## How do X API rate limits work?

**X API rate limits are counted per endpoint, per time window, and per app or per user depending on how you authenticate.** The four rules from X's docs:

| Concept | How it works |
|---|---|
| **Time window** | Usually 15 minutes; some limits are per 24 hours or per second |
| **Per-user limits** | Apply when you call with an OAuth 1.0a or OAuth 2.0 user token |
| **Per-app limits** | Apply when you call with the app-only Bearer Token |
| **Per endpoint** | Each endpoint has its own counter |

**The two pools don't drain each other.** X's [app-only auth guide](https://docs.x.com/resources/fundamentals/authentication/oauth-2-0/application-only) says requests made with user tokens come from a different rate-limit pool than requests made with the Bearer Token.

## What is the X API post rate limit?

**`POST /2/tweets` allows 100 posts per user per 15 minutes and 10,000 posts per app per 24 hours.** Deleting is limited separately.

| Method | Endpoint | Per app | Per user |
|---|---|---|---|
| `POST` | `/2/tweets` | 10,000 / 24 hours | 100 / 15 min |
| `DELETE` | `/2/tweets/:id` | Not listed | 50 / 15 min |
| `POST` | `/2/users/:id/retweets` | Not listed | 50 / 15 min |
| `POST` | `/2/users/:id/likes` | Not listed | 50 / 15 min, 1,000 / 24 hours |
| `POST` | `/2/media/upload` | 50,000 / 24 hours | 500 / 15 min |
| `POST` | `/2/media/upload/initialize`, `/append`, `/finalize` | 180,000 / 24 hours | 1,875 / 15 min |

**X's own pages give two different per-user numbers.** The rate limits page says 100 per 15 minutes. The [Manage Posts guide](https://docs.x.com/x-api/posts/manage-tweets/integrate) says 200 per 15 minutes, plus a limit of **300 posts per 3 hours** that counts posts and reposts together. Build to the lower numbers and read the headers rather than hard-coding either one.

**The per-user limit follows the user across apps.** The Manage Posts guide says the user can only call the endpoint a set number of times "across any developer App." If a customer also posts through another tool, both draw from the same budget.

## What are the X API v2 rate limits for reading?

**Read limits are higher than write limits and nearly all reset every 15 minutes.** The endpoints social products call most:

| Method | Endpoint | Per app | Per user |
|---|---|---|---|
| `GET` | `/2/tweets` | 3,500 / 15 min | 5,000 / 15 min |
| `GET` | `/2/tweets/:id` | 450 / 15 min | 900 / 15 min |
| `GET` | `/2/users/:id/tweets` | 10,000 / 15 min | 900 / 15 min |
| `GET` | `/2/users/:id/mentions` | 450 / 15 min | 300 / 15 min |
| `GET` | `/2/tweets/search/recent` | 450 / 15 min | 300 / 15 min |
| `GET` | `/2/tweets/search/all` | 1 / sec, 300 / 15 min | 1 / sec |
| `GET` | `/2/tweets/analytics` | 300 / 15 min | 300 / 15 min |
| `GET` | `/2/users/me` | Not listed | 75 / 15 min |
| `GET` | `/2/users/by/username/:username` | 300 / 15 min | 900 / 15 min |

**Direct Messages are the tightest.** Looking up DM events allows **15 requests per user per 15 minutes**, and sending a message allows 15 per 15 minutes and **1,440 per 24 hours**, per user and per app. A support inbox that polls DMs will hit this first.

## How do I check my X API rate limit?

**Read the three `x-rate-limit-*` headers that come back on every response.** X's [error reference](https://docs.x.com/x-api/fundamentals/response-codes-and-errors) says every response includes them:

| Header | Meaning |
|---|---|
| `x-rate-limit-limit` | The maximum requests allowed in the window |
| `x-rate-limit-remaining` | Requests left in the current window |
| `x-rate-limit-reset` | Unix timestamp (seconds) when the window resets |

```bash
curl -s -D - -o /dev/null "https://api.x.com/2/users/me" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN" | grep -i x-rate-limit
```

The [Developer Console](https://console.x.com) also shows each endpoint's limits. Store the headers per endpoint and per user, so your scheduler knows which accounts can post before it tries.

## Why do I get "Rate limit exceeded" from the X API?

**You get "Rate limit exceeded" when a window's budget is spent: X returns HTTP 429 with error code 88.** The body looks like this:

```json
{
  "errors": [{ "code": 88, "message": "Rate limit exceeded" }]
}
```

A 429 isn't always a rate limit. X's error reference lists **429 for "Rate limit or usage cap exceeded"**, with separate problem types for each:

| Problem type | What happened | Fix |
|---|---|---|
| `rate-limit-exceeded` | The window's request budget is spent | Wait for `x-rate-limit-reset` |
| `usage-capped` | A usage cap is reached | Waiting for the window won't help; check usage and limits in the console |

Two other errors tend to show up next to 429s. **`503 Service Unavailable`** means X is overloaded: wait and retry. And if your credit balance runs out, X blocks requests until you top up, which no retry logic can fix. Billing is covered in [X API pricing](https://www.tryadeli.com/blog/x-api-pricing).

## How do I handle a 429 from the X API?

**Wait until `x-rate-limit-reset`, add a random delay, and retry.** X's own recovery steps are to check the reset header, wait until then, and use exponential backoff if needed. Here it is in Node.js:

```javascript
async function xRequest(url, options, attempt = 0) {
  const res = await fetch(url, options);
  if (res.status !== 429 && res.status < 500) return res;
  if (attempt >= 5) throw new Error(`X API gave up after ${attempt} retries: ${res.status}`);

  const reset = Number(res.headers.get("x-rate-limit-reset"));
  const untilReset = reset ? reset * 1000 - Date.now() : 0;
  const backoff = Math.min(60_000, 1000 * 2 ** attempt);
  const jitter = Math.random() * 1000;
  await new Promise((r) => setTimeout(r, Math.max(untilReset, backoff) + jitter));

  return xRequest(url, options, attempt + 1);
}
```

Don't skip the jitter. When many workers hit a limit together, they all wake at the reset time and collide again. Marc Brooker, a Distinguished Engineer at AWS, measured this in [Exponential Backoff And Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) (March 4, 2015):

> "The return on implementation complexity of using jittered backoff is huge, and it should be considered a standard approach for remote clients."

**Don't retry a post blindly after a timeout.** If the post went through and the response got lost, a retry creates a duplicate, which X rejects. Check the account's recent posts before retrying a create.

## How do I stay under X API rate limits at SaaS scale?

**Queue posts per user, and plan around the per-app daily cap, because every customer shares it.** The 10,000-posts-a-day limit belongs to your app, not to each customer. A product with 3,000 connected accounts posting 5 times a day needs 15,000 and won't fit on self-serve.

Paul Tarjan, then an engineer at Stripe, described the two client patterns in [Scaling your API with rate limiters](https://stripe.com/blog/rate-limiters) (March 30, 2017):

> "Fork off X jobs and have them process the queue" compared to "Hammer the API and back off when I get a HTTP 429"

For posting to X, the queue model wins. In practice:

- **One queue per connected account.** Space each user's posts so they stay under 100 per 15 minutes without ever seeing a 429.
- **A global counter for the app.** Track creates against the 10,000-per-24-hours cap and slow the whole queue before you reach it.
- **Cache reads.** Post lookups are deduplicated for billing within a UTC day, but they still count against rate limits. Store what you've read.
- **Use streams or webhooks for real-time data.** X recommends the filtered stream over polling.
- **Ask about Enterprise early.** X gives Enterprise customers custom limits, and its terms describe self-serve plans as built for a limited number of end users.

## Is there a faster way to post to X at scale?

**Yes, if your customers are the ones posting.** Rate-limit handling is one of several jobs an X integration carries: the developer app, the OAuth flow, refreshing every account's tokens, and the per-request bill.

[Adeli's X API](https://www.tryadeli.com/product/x) maintains the X developer app, has passed X's review, and refreshes every connected account's tokens. Your product sends one request to [`POST /api/v1/posts`](https://www.tryadeli.com/docs/api/posts/publish-x), the same call it uses for Instagram, TikTok, YouTube, Facebook, and Bluesky ([posting API](https://www.tryadeli.com/social-media-posting-api)). When X is unavailable to Adeli for a while, the response is **`503 temporarily_unavailable`**, and Adeli's [error docs](https://www.tryadeli.com/docs/errors) say to retry `429` and `502` with backoff. X's API usage fees are passed through at X's published rates.

If you're building social features into a marketing platform, see how Adeli fits [AI marketing platforms](https://www.tryadeli.com/use-cases/ai-marketing-platforms).

## Frequently asked questions

### What does 'Rate limit exceeded' mean on the X API?

It means your app or the user you're acting for has used every request the endpoint allows in the current window. X returns HTTP 429 with error code 88. The x-rate-limit-reset header gives the Unix time when the window resets, and requests before then keep failing.

### Are X API rate limits different on Enterprise?

Yes. X's rate limits page says Enterprise customers have custom rate limits, set with their account manager. The published per-endpoint limits apply to pay-per-use (self-serve) apps.

### Do X API rate limits reset every 15 minutes?

Most do. X lists most limits per 15 minutes, but some are per 24 hours, such as creating posts (10,000 per app) and sending direct messages (1,440 per app and per user), and full-archive search also has a 1-request-per-second limit.

### Does hitting the X API rate limit cost money?

Not by itself. X says rate limits and billing are separate systems: you can hit a rate limit without additional cost, and you can stay within every limit and still run up a large bill. X bills writes per request and reads per resource returned.

## Related Adeli pages

- [X (Twitter) API for Developers](https://www.tryadeli.com/product/x.md): Publish, schedule, and read analytics for X (Twitter) through one API. Adeli owns the X developer app, token refresh, and review process. Free to start.
- [Social Media Posting & Scheduling API](https://www.tryadeli.com/social-media-posting-api.md): Adeli's social media posting and scheduling API publishes to Instagram, TikTok, YouTube, Facebook, X, and Bluesky in one request, now or at a set time. Free to start.
- [Social Media and Ads API for AI Marketing Platforms](https://www.tryadeli.com/use-cases/ai-marketing-platforms.md): Run posting, analytics, inbox, and Meta ads for your customers' accounts through one API, without months of platform reviews.
- [All posts on the Adeli blog](https://www.tryadeli.com/blog.md)

## About the author

Mika Reyes is the CEO behind Adeli and a tech and AI content creator. She was previously co-founder and CEO of Parallax, which was acquired by Phantom, and a product lead at LinkedIn. She is a Forbes 30 Under 30 honoree.
