Skip to main content

Errors, Rate Limits & Reliability

Intermediate
What you'll learn
  • Read the HTTP error map and know which statuses to retry vs. fix
  • Retry transient errors with exponential backoff and jitter, capped
  • Handle rate limits with retry-after, smoothing, batching, and cheaper models
  • Insulate your code from model deprecations and migrations

Production code talks to a network service, so it must expect failure. A little structure here is the difference between a flaky integration and a dependable one.

The error map

Typical HTTP statuses you'll handle:

StatusMeaningWhat to do
400Invalid requestFix the payload; don't retry as-is
401Bad/missing API keyCheck credentials
403Not permittedCheck access/permissions
429Rate limitedBack off and retry (respect retry-after)
500/529Server error / overloadedRetry with backoff
Pro tip
  • The SDKs surface these as typed exceptions, so you can branch cleanly instead of parsing strings.

Retries with backoff

For transient errors (429, 5xx), retry with exponential backoff + jitter, capped:

import time, random
for attempt in range(5):
try:
return client.messages.create(...)
except (RateLimitError, APIStatusError) as e:
if attempt == 4 or not should_retry(e):
raise
time.sleep(min(2 ** attempt + random.random(), 30))
Watch out
  • Many SDKs retry transient errors automatically — know your client's default before adding your own, or you may double up on retries.

Rate limits

Limits apply per-account/tier (requests and tokens per minute). When you hit one you get 429 with timing hints. Strategies to stay under the ceiling:

Guided walkthrough1 of 4
  1. When you get a 429, read the timing hint in the response and wait that long before retrying.

See Choosing a Model for picking the right model for high-volume steps.

Model migration

Model IDs are dated/versioned and get deprecated. Insulate yourself:

Key takeaways
  • 400/401/403 are your fault — fix the request or credentials, don't blind-retry. 429 and 500/529 are retryable.
  • Retry transient errors with exponential backoff + jitter, capped (e.g. min(2 ** attempt + random(), 30)).
  • On 429: respect retry-after, smooth bursts, batch offline work, and route high-volume steps to a cheaper model.
  • Read model IDs from config, watch deprecations, and re-run evals when migrating models.

Check yourself

0/4
  1. You get a 400 Invalid request. What should you do?
  2. Which statuses are the ones you should retry with backoff?
  3. Why add jitter to exponential backoff?
  4. Which is NOT a suggested rate-limit strategy?

Next