HTTP Status Codes & API Error Mapping Markdown Table Template
An error mapping table is the page of your API docs that client developers keep open while they write error handling. It answers three questions for every failure: which HTTP status will I get, which machine-readable code tells me exactly what went wrong, and what should my code do next. When that information only lives in prose, every SDK and mobile team ends up reverse-engineering it from logs.
Edit This Template
Edit cells, add rows, or sort — the Markdown updates livePaste cells from Excel or Google Sheets into the first header to replace the table · Tab / Enter / arrows move · Shift+F10 opens row & column actions
When to Use This Table
The HTTP status is the coarse category that proxies, caches, and generic HTTP clients understand; the error code is the precise, stable identifier your own clients branch on. Keep both. Two different problems often share one status (a 400 can be a malformed body or a failed business rule), so clients should never have to parse the human-readable message to tell them apart.
The Retryable and Client Action columns are what make this table more than a glossary. They turn it into a decision table: a client can safely retry 429 and 503 with backoff, but retrying a 400 will fail forever. If your API returns RFC 9457 Problem Details bodies, add a column for the type URI so each row links to its own documentation.
What Goes in Each Column
| Column | Alignment | What to put here |
|---|---|---|
| HTTP Status | right ---: | The numeric code plus its standard reason phrase, in backticks (429 Too Many Requests). Right-aligned so the three-digit numbers line up. Use the standard reason phrases from RFC 9110 rather than inventing your own. |
| Error Code | left :--- | Your stable, machine-readable identifier in UPPER_SNAKE_CASE. Treat these as part of the API contract: clients branch on them, so never rename one without a deprecation period. One HTTP status can map to several error codes. |
| Retryable | center :---: | A plain Yes / No, centered. Mark Yes only when repeating the identical request can succeed later without the client changing anything — typically 429, 502, 503, and 504. |
| Cause / Meaning | left :--- | One sentence describing what actually went wrong from the client’s point of view. Include concrete limits where they exist (“more than 1,000 requests per minute”) instead of vague wording like “too many requests”. |
| Client Action | left :--- | The concrete next step the client should take: refresh the token, fix a field, back off and retry, or contact support. This column is what developers scan when they are writing a switch statement. |
How to Fill It In
- 1List every error your API can actually return. The fastest source is your error middleware or exception classes, not memory — undocumented codes are the ones that page someone at 3 a.m.
- 2Group them by HTTP status and give each one a stable error code. Reuse a status for several codes when the client needs to react differently to each.
- 3Decide retryability per row. If a retry needs a changed request (new token, fixed payload), it is not retryable in this sense — say what to change in Client Action instead.
- 4Fill in Cause / Meaning with the real limits and conditions, then check every row against your implementation or integration tests.
- 5Keep
2xxrows to a minimum. One success row is useful as a reference point; the value of this table is in the failure rows.
Ready-to-Paste Variations
With RFC 9457 Problem Details type URIs
Use this if your API returns application/problem+json error bodies. The type column links each row to its own documentation page.
| HTTP Status | Problem `type` | Title | Retryable |
| ---: | :--- | :--- | :---: |
| `400` | `https://api.example.com/problems/invalid-payload` | Invalid request body | No |
| `401` | `https://api.example.com/problems/token-expired` | Access token expired | No |
| `409` | `https://api.example.com/problems/version-conflict` | Resource was modified | No |
| `429` | `https://api.example.com/problems/rate-limited` | Rate limit exceeded | Yes |
| `503` | `https://api.example.com/problems/maintenance` | Service temporarily unavailable | Yes |Compact README version
For a README or changelog where a full mapping is overkill: status, code, and what to do, nothing else.
| Status | Code | What to do |
| ---: | :--- | :--- |
| `401` | `AUTH_EXPIRED` | Refresh the token and retry once |
| `404` | `ENTITY_NOT_FOUND` | Check the resource ID |
| `429` | `RATE_LIMITED` | Wait for `Retry-After`, then retry |
| `503` | `SERVICE_UNAVAILABLE` | Retry with exponential backoff |Common Mistakes
Returning
200 OKwith an error object in the body.Use a real
4xx/5xxstatus. Monitoring, caches, and generic HTTP clients all decide success by the status code, so a200error is invisible to them.Mixing up
401and403.401 Unauthorizedmeans “we don’t know who you are” (missing or invalid credentials);403 Forbiddenmeans “we know who you are, and you can’t do this”. Re-authenticating fixes a401but never a403.Using
503for a gateway timeout.503 Service Unavailableis for overload or maintenance;504 Gateway Timeoutis for an upstream that didn’t answer in time. Both are retryable, but they point operators at different problems.Telling clients to retry everything.
Retrying a
400or422just repeats the failure. Limit automatic retries to rows marked Yes, and always use exponential backoff with jitter so clients don’t retry in lockstep.
Related Markdown Table Templates
Browse all 50 templatesREST & GraphQL API Parameters
Document REST endpoints, GraphQL query fields, request payload types, requirements, and default fallback values.
Relational Database Table DDL Schema
Document database tables, column names, SQL types, nullability, keys (PK/FK), default values, and column semantics.
Project Architecture & Tech Stack
List technologies, libraries, packages, and cloud services powering your application by architectural tier.
HTTP Status Codes & API Error Mapping: Frequently Asked Questions
Should I document every HTTP status code?
No. Document the statuses your API actually returns, plus the error codes behind each one. A table of all 60-odd registered status codes tells your users nothing about your API.
What is the difference between 400 and 422?
400 Bad Request is the general “this request is malformed” response, such as invalid JSON. 422 Unprocessable Content means the syntax was fine but the content failed validation, such as an end date before the start date. Many APIs use only 400; if you use both, document which validation failures return which.
How should clients handle 429 Too Many Requests?
Read the Retry-After response header if you send one, wait that long, then retry. Without the header, use exponential backoff with random jitter. Document your actual rate limits in the Cause / Meaning column so clients can stay under them.
Is a 401 retryable?
Not as-is. The same request with the same expired token will fail again. The client should refresh or re-acquire the token first, which is why the template marks it No and puts “Refresh access token” in Client Action.