The HTTP status codes, and when each one is the right answer
A status code is a contract with every client that will ever talk to your API, and choosing the wrong one causes the bug to be blamed on the client. This reference covers the full set with the practical consequence of each code.
- Codes
- Full registry
- Categories
- 1xx to 5xx
- Search
- Filterable
| Code | Name | Meaning and when to use it |
|---|
Questions people ask
Should I use 400 or 422 for a validation error?
Use 422 when the body parsed correctly and the content is invalid, and 400 when the body could not be parsed at all. RFC 4918 introduced 422 for exactly this distinction. The important part is that you pick one and document it, because clients branch on the code.
What is the difference between 401 and 403?
401 means the client failed to prove who it is, so a WWW-Authenticate header is required. 403 means the client proved who it is and is still not allowed. Returning 403 where the client expects 401 breaks standard HTTP auth flows.
Which status code is right for rate limiting?
429, with a Retry-After header telling the client when to come back. It is the clearest signal you can send, and it lets well-behaved clients back off instead of hammering you.
Should errors ever return 200?
No. A 200 with an error field in the body breaks every HTTP client library, every monitoring system and every cache. The status code is the part of the response that tooling actually reads.
What is the difference between 404 and 410?
404 says the resource is not there right now. 410 says it was there and is deliberately gone, so clients and search engines can drop it. Use 410 when you are certain a URL will never come back.
Are the 4xx codes safe to cache?
Some of them are explicitly cacheable, such as 404 and 410, which is why a 404 page can be served from a CDN edge. Others such as 429 should carry a Cache-Control header that prevents it.
Reference
The distinctions that cause the most bugs
| Code | Means | Not this |
|---|---|---|
| `400` | The request is malformed and cannot be parsed | Not a validation failure — use 422 |
| `401` | No valid credentials were presented | Not "you lack permission" |
| `403` | Authenticated, but not allowed to do this | Not a substitute for 401 |
| `409` | The request conflicts with the current state | Not a generic failure |
| `422` | Parsed fine, but the content failed validation | Not a malformed body |
| `429` | Rate limit exceeded | Always send Retry-After |
Details that catch people out
A 4xx means the client should change something before retrying. A 5xx means the server failed and the same request may succeed later. That distinction is what tells a client whether to retry, and it is why a bug in a server that returns 400 for everything causes infinite client retry loops.
Where this earns its keep
Debugging an API that returns the wrong code
A 400 where the client expected a 422 sends developers hunting for a syntax error that is not there. The distinction table settles it.
Designing an error contract
A consistent mapping from your domain errors to status codes is what lets clients handle failures programmatically instead of parsing message strings.
Configuring a CDN or a load balancer
Several edge behaviours, including caching and retry, are triggered by specific status codes, and picking the wrong one has a measurable cost.
Guides that go deeper
- Cache-Control and ETag, Explained 9 min read · How HTTP caching works: what Cache-Control directives mean, what an ETag is, what Vary…
- Designing API Error Responses 8 min read · What an API error body should contain, which status code to use, and how to keep errors…
Last reviewed 2026-09-27. Every tool on DevSnap runs entirely in your browser, so whatever you paste here never reaches a server.