HTTP 429 error code 88 returns the same response body whether you have exhausted a 15-minute endpoint window, a per-user 24-hour cap, or the app-level monthly ceiling. The only way to determine which limit fired is to cross-reference the x-rate-limit-remaining header against a separately maintained monthly usage counter: the error body gives you nothing. This guide covers the X API basic tier read limits, the pay-per-use model that replaced them for new developers, and the operational patterns that prevent costly surprises.
Read requests allowed per 15-minute window
Requests per 15 minutes
X API basic tier read limits: what the numbers actually were
The short version
The X API legacy Basic tier capped post reads at 10,000 to 15,000 per month at the app level for $200/month. That tier closed to new signups in early 2026. New developers now use a pay-per-use model at $0.005 per third-party post read, with a hard 2,000,000-read monthly ceiling before an Enterprise upgrade is required.
The legacy Basic tier ran $200/month and capped post reads at 10,000 to 15,000 per month at the app level. That spread is not hedging on our part. Most sources put 10,000 reads at the $100/month price point and 15,000 at $200/month, and the tier changed shape often enough that no single figure held for long. Writes were far more generous: 50,000 posts per month at the app level, with a per-user cap of 3,000 posts per month.
Sit with that ratio for a second. The app could publish 50,000 posts for every 10,000 to 15,000 it was allowed to read. Most platform APIs are shaped the other way around, because reading is cheap and writing is the thing that gets abused. X priced it backwards on purpose. The tier was built for tools that push content out, not for tools that listen.
That tier is closed. As of early 2026, every new developer signup goes to pay-per-usage credit pricing. Free, Basic and Pro still appear in the documentation, but only as grandfathered subscriptions held by developers who were already paying. There is no path to buy into them now.
Pay-per-use removes the monthly read allowance entirely and replaces it with a meter. A third-party post read costs $0.005. The hard ceiling is 2,000,000 post reads per month, and crossing it means an Enterprise upgrade rather than an overage charge.
We build automation tooling on this API, so the change arrived on our side as a rewrite of the cost model rather than a pricing announcement. A fixed tier is a budget. Pay-per-use is a meter. With a budget you plan once and then ignore it until the month ends. With a meter, every polling interval, every retry, and every redundant lookup in your codebase becomes a line item somebody has to defend.
X API pay-per-use pricing: read costs, write costs, and the monthly ceiling
The per-operation prices are short enough to memorize. A third-party post read costs $0.005. Reading your own posts costs $0.001. A user profile read or a DM event read costs $0.010. Creating a text-only post costs $0.015. Creating a post that contains a URL costs $0.200, which is 13x the price of the same post without the link.
At the 2,000,000-read monthly ceiling, the effective cost is approximately $10,000/month. The next thing above that is Enterprise, reported to start somewhere between $42,000 and $50,000 per month. There is nothing in between. That gap is the real story of the pricing page: the model scales smoothly right up to the point where it stops, and then the only remaining option costs several times more than the ceiling you just hit.
One rule cuts against the meter. Requesting the same post ID more than once inside a single UTC calendar day counts as one billable event, not one charge per request. Fetch the same post fifty times before the day rolls over and you pay once.
The catch is the boundary. The deduplication window resets at UTC midnight, not 24 hours after your first call. A monitoring job that polls the same post IDs hourly and runs continuously will straddle that boundary every night and pay twice for the transition, once just before midnight and once just after. In production we treat this as a scheduling problem rather than a billing problem. A nightly batch that lands entirely inside one UTC day, at 01:00 UTC for instance, is meaningfully cheaper than a rolling hourly poller that does the same work.
The $0.200 URL post price is not a line item either. It is an architecture decision. The gap between a text post and a post with a link attachment is wide enough that we keep them in separate scheduling queues with separate credit budgets, because a single campaign with URLs embedded in every post will burn through a monthly allocation 13x faster than the same campaign written as plain text. Teams that discover this at the end of the month discover it as a number they cannot explain.
If you are still on legacy Basic, that is temporary. Existing Basic subscribers were being auto-migrated to pay-per-use as of June 2026, so the population of fixed-price accounts is shrinking toward zero. Cost models built on a flat monthly tier have an expiry date now.
Rather not do this by hand? SocialNexis drafts posts and comments in your own voice and schedules them across LinkedIn and X.
Start freeWhy the X API 429 error tells you almost nothing on its own
HTTP 429 with error code 88 comes back identical from three separate limit sources: a per-endpoint 15-minute window, a per-user monthly cap, and the app-level monthly ceiling. The body is the same in all three cases, a single errors array containing code 88 and the message Rate limit exceeded. No field distinguishes them. You get the same eight bytes of information whether you need to wait a few minutes or a few weeks.
The diagnosis has to come from somewhere else, and this is the part that generic documentation skips. Cross-reference x-rate-limit-remaining against a counter of monthly usage that you maintain yourself. The header snaps back to its full value at the window boundary. If remaining looks healthy and you are still collecting 429s, the window is not your problem and no amount of waiting will fix it. You are against a monthly cap.
The failure mode this creates is worth naming, because it is common and it is quiet. Call it the blind backoff loop: a client that throttles purely in reaction to the 429 will sleep, retry, get another 429, sleep longer, and keep going. Against a 15-minute window that behavior is correct. Against the monthly ceiling it is a client that has confidently scheduled itself to fail for the rest of the billing period while its logs show nothing more alarming than retries. The outage looks exactly like a throttle and lasts a thousand times longer.
There is a second trigger that produces 429s at activity levels low enough to look like a bug in X rather than a bug in your code. Auth misconfiguration. The X developer community forum has a long-running thread on exactly this, and the pattern that surfaces repeatedly is a client silently falling back to app-only bearer token on endpoints where the bearer-token limit is lower than the OAuth one. Nothing in the request fails. Nothing in the response says which credential was used. The account simply runs out of read headroom well before its own accounting expects to.
How many requests per 15 minutes does the X API read rate limit allow?
Tweet lookup, the GET /2/tweets endpoint, allows 3,500 requests per 15 minutes under app-level auth or 5,000 per 15 minutes under user-level auth. It is the highest-volume read endpoint in the API and the one most tools lean on hardest.
Recent search is a different animal. GET /2/tweets/search/recent caps at 450 per 15 minutes app-level, or 300 per 15 minutes user-level. Read that pairing again: the user-level limit is lower than the app-level limit, which inverts the assumption most people carry over from tweet lookup. Anyone who builds a token-selection layer on the rule that OAuth always buys more headroom will be wrong on this endpoint, and the way they find out is a 429 from a client that was nowhere near its expected budget.
Social-graph endpoints are tighter than anything else in the API by a wide margin. Follow and unfollow actions cap at 50 per 15 minutes, user-level only, with no app-level pool to fall back on. Blocks and mutes reads cap at 15 per 15 minutes at the user level.
Here is the part that costs teams the most time. User-level limits do not aggregate across accounts under the same app. Each OAuth token carries its own independent 15-minute ceiling, including the 100-posts-per-15-minute write ceiling. That sounds like good news until you watch a scheduler distribute work evenly across 20 accounts and produce a wall of simultaneous 429s anyway. The accounts were not sharing a limit. Their windows were aligned, because every token was initialized at the same clock time, so all of them opened and exhausted the same 15-minute slot together. The failure reads as an app-level problem. It is per-user exhaustion happening twenty times in parallel.
The fix costs nothing. Stagger token initialization by a few minutes so the windows do not line up. Total throughput is unchanged, because you were never sharing a pool in the first place. The thundering herd just stops.
Rather not do this by hand? SocialNexis drafts posts and comments in your own voice and schedules them across LinkedIn and X.
Start freeTwo limits, two windows: 15-minute endpoint caps and monthly read ceilings
Per-endpoint 15-minute windows and monthly usage caps run on independent clocks, and neither one knows about the other. A client can sit comfortably inside its 15-minute allowance while being completely exhausted against the monthly ceiling. Nothing reconciles the two. There is no combined view of remaining capacity anywhere in the API.
Since the same 429 with code 88 fires either way, the error cannot tell you which clock ran out. That diagnosis problem is covered above. The structural point here is simpler and easier to miss: you are not tracking one limit with two names. You are tracking two limits that happen to fail identically.
Write endpoints make this worse by mixing both window types on the same operation. A 15-minute per-window limit and a 24-hour sub-cap, running together. A client that honors only the 15-minute reset will behave perfectly for hours and then start throwing 429s in the middle of the afternoon against a 24-hour ceiling that appeared in no header it was reading. No source we have found documents this timing asymmetry, and it is the single most common reason a tool that passed its own rate-limit tests fails in production.
The numbers to track separately, per account and per app: post creation is 10,000 per 24 hours at the app level and 100 per 15 minutes at the user level. DM sends are 1,440 per 24 hours combined and 15 per 15 minutes at the user level.
DM tooling hits the 24-hour ceiling long before the per-window limit ever feels restrictive. At 15 DMs per window, the daily ceiling of 1,440 arrives after 96 windows, roughly a full day of continuous sending. What that produces in practice is a tool running near capacity that silently exhausts its daily budget around midnight UTC, then collects 429s for the first fifteen minutes or so of the new UTC day before the counter rolls over. Every engineer who sees it for the first time files it as a transient network issue. It is deterministic quota rollover, and the tell is that it recurs at the same clock time every single day.
Get the next breakdown in your inbox
Occasional, practical guides on LinkedIn and X growth. No spam, unsubscribe anytime.
Search, write caps, and the social-graph ceiling
Basic tier search was a 7-day rolling window and nothing more. Full-archive search, meaning everything back to 2006, requires the legacy Pro tier at $5,000/month or an Enterprise contract. Pro is closed to new developers along with the rest of the fixed-price tiers, so in 2026 there is no lower-cost path to historical data at all. If your product needs the archive, the price of entry is a negotiation with a sales team, not a checkout page. Plan the roadmap accordingly, because this is the constraint that kills more X-based product ideas than rate limits ever have.
Post creation caps at 10,000 per 24 hours at the app level. That ceiling governs your real publishing pace no matter how many 15-minute windows reset underneath it, which is the part people forget when they size capacity off the per-window number alone. The 15-minute limit describes burst behavior. The daily cap describes the business you can actually run.
DM sends reach the 24-hour ceiling well before the per-window limit tightens: 1,440 per 24 hours combined, against 15 per 15 minutes at the user level. The practical maximum works out to roughly one DM per minute, sustained. Any outreach plan that assumes otherwise is planning around the wrong number.
Follow and unfollow actions cap at 50 per 15 minutes, user-level only, with no app-level equivalent to draw down instead. Blocks and mutes reads cap at 15 per 15 minutes at the user level. These are the tightest windows in the API, and they are tight for an obvious reason: bulk follow and unfollow behavior is the oldest growth-hack pattern on the platform.
Anything automating social-graph management runs into these ceilings almost immediately. The instinct is to spread the work across more user contexts, which does not buy the headroom people expect, because each account ceiling is independent and nothing pools. More accounts means more separate small budgets, not one larger one. Coordination overhead grows. The ceiling per account does not move.
Read the rate-limit headers before the 429 hits
Every X API response carries three rate-limit headers. x-rate-limit-limit is the total number of requests allowed in the current window. x-rate-limit-remaining is how many you have left before the window closes. x-rate-limit-reset is a Unix epoch timestamp marking when the window clears. All three are on every response, including successful ones, which means the information you need to avoid a 429 arrives long before the 429 does.
Read x-rate-limit-remaining on every response and throttle against it. When remaining drops below your threshold, pause. Waiting for the 429 to arrive first means you have already spent a request you cannot recover, and you are now guessing at the wait instead of being told.
x-rate-limit-reset removes the guessing entirely. Subtract the current Unix timestamp from it and you have the exact number of seconds until the window clears. That is your sleep duration. Not a fixed backoff, not an exponential guess with jitter bolted on. The API is telling you the answer and most clients throw it away.
The limitation matters more than the feature. These headers describe the 15-minute window and nothing else. Monthly cap usage appears in no response header anywhere in the API. Tracking it means an application-level counter that you increment on every billable read and persist yourself, because X will not tell you where you stand against the monthly ceiling until the moment it starts refusing. On our side that counter is the thing we alert on, not the 429 rate, since by the time the 429 rate moves the decision has already been made for us.
One rule to implement today: when x-rate-limit-remaining reaches 0, sleep until x-rate-limit-reset. Do not retry. Retries against an exhausted window return another 429, count as attempts in your own logs, and do nothing whatsoever to accelerate the reset.
Frequently asked questions
What are the post read limits on the X API basic tier per month?
The legacy Basic tier allowed 10,000 to 15,000 post reads per month at the app level at $200/month. That tier closed to new signups in early 2026. New developers use pay-per-use pricing at $0.005 per third-party post read, with a hard monthly ceiling of 2,000,000 reads before a mandatory upgrade to Enterprise is required.
What happens when you exceed the X API rate limit, and why do some 429 errors appear at very low activity levels?
Exceeding any X API limit returns HTTP 429 with error code 88, but the same error body fires for three separate sources: a 15-minute endpoint window, a per-user monthly cap, or the app-level monthly ceiling. Low-activity 429s often occur because the monthly cap is exhausted while per-window request counts appear untouched, or because a client uses app-only bearer token on endpoints that have lower bearer-token limits than expected.
How many tweets can you read per 15 minutes on the X API, and does it differ by auth method?
The tweet lookup endpoint (GET /2/tweets) allows 3,500 requests per 15 minutes under app-level bearer token auth and 5,000 per 15 minutes under user-level OAuth. Recent search allows 450 per 15 minutes (app-level) or 300 per 15 minutes (user-level). App-only auth generally has higher read limits on lookup endpoints but cannot be used for write operations.
What is the difference between the X API pay-per-use model and the legacy basic tier read limits?
The legacy Basic tier offered a fixed monthly allowance of 10,000 to 15,000 post reads for a flat $200/month fee. The pay-per-use model charges $0.005 per third-party post read with no fixed monthly allowance, a 2,000,000-read hard cap, and a deduplication rule: the same post ID fetched multiple times within a UTC calendar day counts as a single charge.
How do I read the x-rate-limit-reset header to know when my X API rate limit resets?
The x-rate-limit-reset header is a Unix epoch timestamp. Subtract the current Unix timestamp from this value to get the seconds until the window resets, which is how long your client should sleep before retrying. This header reflects only the 15-minute endpoint window; monthly cap usage must be tracked separately in application state, since the API provides no monthly-remaining header.
What is the cheapest way to get full-archive X API search access in 2026?
There is no low-cost option. Full-archive search extending back to 2006 requires the legacy Pro tier at $5,000/month or an Enterprise contract. The legacy Basic tier limited search to a 7-day rolling window. Pro tier signups are also closed to new developers, so new accounts that need historical data must negotiate an Enterprise agreement directly with X.
How many posts per month can you create with the X API under pay-per-use pricing?
Under pay-per-use there is no separate monthly post creation cap, but per-window limits apply: 100 posts per 15 minutes at the user level and 10,000 per 24 hours at the app level. Cost is $0.015 per text-only post and $0.200 per post with an embedded URL. A campaign posting 10,000 URL-containing posts costs $2,000 in creation charges alone.
Why is creating a post with a URL so much more expensive than a text-only post on the X API?
Under pay-per-use pricing, a post with an embedded URL costs $0.200 to create while a text-only post costs $0.015, a 13x difference. For high-volume posting workflows this changes the architecture: campaigns with embedded links must be separated into distinct scheduling queues with separate credit budgets, or URL posts can exhaust a monthly credit allocation 13x faster than text-only posts would.
What is the difference between app-level and user-level X API rate limits, and which one matters for automation?
App-level limits apply across your entire application under a single bearer token or app credential. User-level limits apply independently per OAuth token, so each authenticated account has its own ceiling that does not pool with other accounts in the same app. For automation tools managing multiple accounts, user-level limits matter most: each account exhausts its own 15-minute window independently, and when windows align in time, all accounts can 429 simultaneously.
Sources and further reading
- X API rate limits official documentation, with per-endpoint 15-minute tables, rate-limit header definitions, and the HTTP 429 error format
- X API pay-per-use pricing page, covering per-operation credit costs, the deduplication rule, and the 2,000,000 monthly read cap
- X Developer Community thread where developers report 429 errors at low activity levels and identify auth misconfiguration as a common trigger
Put this guide into practice
SocialNexis writes posts and comments in your voice, then runs them across LinkedIn and X on a schedule you set.
Not ready? Score your next post free and see what's holding your reach back.