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

By Mika ReyesPublished 6 min read

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, checked on 2026-10-26. For the wider picture of the API, start with our 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 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 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 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
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 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:

{
  "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.

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:

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 (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 (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 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, the same call it uses for Instagram, TikTok, YouTube, Facebook, and Bluesky (posting API). When X is unavailable to Adeli for a while, the response is 503 temporarily_unavailable, and Adeli's error docs 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.

faq

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.

Power your next project
with one ads & social media API

Give your users publishing, scheduling, and analytics through one integration your team can actually maintain.

Try with agents

Start with free credits. No credit card required.