BRYME TECH
SEPTEMBER 2026 · THE TOOL DESKPractical technology. No theatre.
THE BRYME

Practical guide · verified against the real thing

Why is my API returning an error? A status-code diagnostic tree

In one line: 401, 403, 404, 429, 5xx and the CORS illusion: what each code is actually telling you, in the order to check them.

The symptom: your request fails, and the error is an alphabet soup — 401, 403, 429, 500, or a CORS wall of text. Every status code is a sentence from the server; most debugging pain is refusing to read the sentence. Here is the tree, in the order the codes deserve.

401 Unauthorized — the key problem

The server does not know who you are: missing header, malformed key, wrong scheme ("Bearer" missing), or a rotated/revoked token still living in an env file (the single most common cause). Diagnosis: print the exact request your code sends — not the one you think it sends — and compare against one made with curl from the provider's docs. We have lost count of the deploys where the code was fine and the env var was stale; this desk keeps its own provider tokens in server-side env vars precisely because tokens die (token hygiene applies to every key you own).

403 Forbidden — the permission problem

Authenticated, but not allowed: the key is valid but scoped to different endpoints, the account lacks the feature, or a region/IP rule blocks it. Do not "fix" a 403 by upgrading blindly — read the provider's response body first; good APIs say which permission failed.

404 Not Found — the address problem

Version mismatch (/v3/ where the API is now /v4/), a trailing slash the route does not declare, a base path duplicated (/api/api/thing), or an ID that simply does not exist. The URL in the failing request, read character by character, resolves most 404s without documentation.

429 Too Many Requests — the pace problem

You are too fast. The honest fix is respecting the limits the provider publishes — many send Retry-After or rate-limit headers; honour them, back off exponentially, and cache responses you already have. Retrying immediately converts a rate limit into a ban. (This desk's own data agent throttles on purpose and caches by design — the pattern scales down to hobby projects.)

5xx — their problem, handled your way

A server error is the provider's failure, but your handling is still yours: retry with backoff, make retries idempotent (never double-charge, never double-post), and show a human-appropriate message. Check the provider's status page before debugging your own code — a perfect codebase can do nothing about someone else's incident.

The CORS illusion

A wall of CORS errors in the browser console usually means "the request failed, and also CORS blocked reading the details" — the underlying 401/404/500 hides behind it. Test the identical request with curl: if curl succeeds and the browser fails, it is genuinely a CORS configuration problem; if both fail, fix the real status first. And keys that must stay secret never belong in browser code at all — proxy through a server (what an API is, error bodies, decoded, and making the call from Python in call an API with Python).

Official documentation (checked 11 September 2026): MDN's HTTP status and CORS references (developer.mozilla.org), RFC 9110 (HTTP semantics, rfc-editor.org), and your provider's own rate-limit and auth docs — the sentences that matter are always theirs.

Next

Related on this desk.