← Blog

Claude API Rate Limit Error 429: Causes and Fixes

2026-10-25 · 5 min read · SubToAPI Team

A 429 error from the Claude API means you've hit a rate limit: either too many requests per minute, too many tokens per minute, or (for the Anthropic Console) a spend limit on your organization. The fix depends on which limit you tripped, but in almost every case the solution is a combination of exponential backoff with jitter, respecting the retry-after header, and reducing concurrent request volume until you can request a higher tier or move to a provider that manages limits for you.

This article walks through what triggers the error, how to read the response headers that tell you exactly what's throttling you, and concrete code for handling retries correctly instead of hammering the API and making things worse.

Why Claude API returns 429

Anthropic enforces rate limits per organization and per API key, measured across a few dimensions:

A 429 doesn't mean something is broken in your code. It means the account-level limits were reached at that moment, usually because of a traffic spike, a loop with no backoff, or several workers hitting the API in parallel without coordination.

Step 1: read the response headers

Before writing retry logic, inspect what the API is telling you. Anthropic returns rate limit metadata in headers on both successful and 429 responses:

curl -i https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-3-5-sonnet-20241022","max_tokens":100,"messages":[{"role":"user","content":"hi"}]}'

Look for:

If retry-after is present, use it directly instead of guessing a backoff delay. It's the fastest, most accurate signal you have.

Step 2: implement exponential backoff with jitter

Don't retry immediately in a tight loop — that's the single most common cause of repeated 429s. Use exponential backoff, add jitter to avoid synchronized retries across workers, and cap the number of attempts.

async function callWithBackoff(fn, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err) {
      if (err.status !== 429 || attempt === maxRetries - 1) throw err;

      const retryAfter = err.headers?.get("retry-after");
      const base = retryAfter ? Number(retryAfter) * 1000 : 2 ** attempt * 500;
      const jitter = Math.random() * 300;

      await new Promise((resolve) => setTimeout(resolve, base + jitter));
    }
  }
}

This pattern works whether you're calling Anthropic directly or any downstream API that returns standard rate-limit semantics.

Step 3: reduce concurrency, not just retry harder

If you're firing requests from multiple workers, queues, or serverless functions simultaneously, backoff alone won't save you — you'll just all retry around the same time and collide again. Add a concurrency limit (a semaphore, a queue with a fixed worker count, or a library like p-limit) so you never exceed your known RPM/TPM ceiling in the first place.

import pLimit from "p-limit";

const limit = pLimit(5); // max 5 concurrent Claude calls
const results = await Promise.all(
  prompts.map((p) => limit(() => callWithBackoff(() => sendPrompt(p))))
);

Batching requests this way is almost always more effective than reactive retry logic alone.

Step 4: reduce token usage per call

If you're hitting ITPM/OTPM limits rather than RPM, backoff won't help much — you need to send fewer tokens per minute. Practical options:

Step 5: separate traffic across keys or request a limit increase

If your application has distinct workloads (e.g., a chatbot and a background summarization job), isolating them under separate API keys prevents one bursty job from starving the other. If you're consistently hitting limits at steady, legitimate traffic volume, request a rate limit increase through the Anthropic Console rather than architecting increasingly complex workarounds.

Where SubToAPI fits in

If you're building on top of a Claude subscription rather than a pay-as-you-go Anthropic API account, SubToAPI turns that access into a standard HTTPS API with per-application keys (sub_live_...), so each app, team member, or environment gets isolated usage instead of sharing one global limit. You get streaming, tool use, and usage metadata per key through the same /v1/messages interface, which makes it easier to see exactly which key or workload is responsible for a 429 instead of guessing. See the quickstart and messages docs for the request format, and streaming docs if you're sending long-running responses that benefit from partial delivery instead of large blocking calls. Plans start at €9/month on the Solo tier, with Team and Scale tiers for multi-seat usage — see pricing.

questions

Does retrying immediately after a 429 ever work? No. Immediate retries usually hit the same limit window and return another 429. Always wait at least the duration in the retry-after header, or use exponential backoff if that header isn't present.

Is a 429 the same as a billing or quota error? Not always. A 429 can mean RPM/TPM throttling (temporary, resolves within the minute) or a spend/budget cap (resolves only when the cap resets or is raised). Check the response body and headers to tell which one you hit.

Can I avoid 429 errors by using a different model? Sometimes. Smaller models often have separate, higher throughput tiers and lower token costs per request, which reduces how fast you burn through ITPM/OTPM limits — but it won't help with RPM caps if the issue is call frequency, not size.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →