HTTP Status Codes for API Developers
Which HTTP status code to return and when in a REST API: 2xx, 3xx, 4xx and 5xx, common mistakes like 200 for errors, and error response design.
Editorial disclosure: Pyalm publishes and maintains the products and free tools discussed on this site. Regulatory statements are linked to primary sources where applicable. No independent professional review is claimed unless a reviewer is explicitly named.
HTTP status codes tell a client what happened before it reads a single byte of the body. Choosing them well makes your API predictable; choosing them badly makes every client guess.
The five classes
| Class | Meaning | Client reaction |
|---|---|---|
| 1xx | Informational | Usually invisible |
| 2xx | Success | Use the response |
| 3xx | Redirection | Follow or use the cache |
| 4xx | Client error | Fix the request; retrying unchanged won't help |
| 5xx | Server error | May retry later |
Clients can act on the class even when they don't recognise the exact code — so getting the class right matters most.
Codes to use in a REST API
Success
- 200 OK — request succeeded and there's a body.
- 201 Created — a resource was created; include a
Locationheader. - 202 Accepted — queued for asynchronous processing.
- 204 No Content — success with nothing to return (typical for DELETE).
Redirection
- 301 / 308 — permanent move; 308 preserves the method.
- 302 / 307 — temporary; 307 preserves the method.
- 304 Not Modified — the client's cached copy is valid (conditional requests).
Client errors
- 400 Bad Request — malformed syntax, invalid JSON.
- 401 Unauthorized — authentication missing or invalid (really "unauthenticated").
- 403 Forbidden — authenticated but not allowed.
- 404 Not Found — resource doesn't exist (or you hide that it does).
- 405 Method Not Allowed — include an
Allowheader. - 409 Conflict — conflicts with current state: duplicate unique value, edit conflict.
- 410 Gone — deliberately removed.
- 415 Unsupported Media Type — wrong Content-Type.
- 422 Unprocessable Content — well-formed but fails validation.
- 429 Too Many Requests — rate limited; include
Retry-After.
Server errors
- 500 Internal Server Error — unexpected failure.
- 502 Bad Gateway / 504 Gateway Timeout — upstream problems.
- 503 Service Unavailable — temporarily down;
Retry-Afterhelps.
Mistakes to avoid
- 200 with an error in the body. Monitoring, caches and clients all treat it as success.
- 500 for validation errors. A bad input is the client's problem — return 4xx.
- 401 vs 403 confusion. 401 = who are you? 403 = I know who you are, and no.
- 404 for everything. Be specific when it's safe to be.
- Leaking details in 500 bodies. Log stack traces; return a generic message and a correlation ID.
- Not using 201/204 where they apply.
- Inconsistent validation code — pick 400 or 422 and document it.
A good error body
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid.",
"details": [
{ "field": "email", "issue": "must be a valid email address" }
],
"request_id": "9f3c1a2e"
}
}
A machine-readable code, a human message, field-level details and a request ID for support. The standard Problem Details format (RFC 9457) is a ready-made option.
Retry guidance
- Retry 5xx, 429 (respecting
Retry-After) and network failures — with exponential backoff and jitter. - Don't retry 4xx unchanged.
- Make non-idempotent operations (POST) safe to retry using an idempotency key.
Look codes up fast
The free HTTP Status Codes reference is searchable by number or phrase, filterable by class, with practical notes for each. Test endpoints in the API Tester, format responses with the JSON Formatter and read how to test a REST API. Redirect and status behaviour also affects SEO — see the robots.txt guide.
Need an API built or integrated?
Pyalm builds and integrates APIs for businesses in India and the UAE — see custom software development and business automation, or get in touch.