APIs3 min read
HTTP Status Codes Cheatsheet: What to Return & When
Developer HTTP status code reference: 2xx, 3xx, 4xx, 5xx meanings, when to return each code, and REST API error-handling best practices.
By IvyIvy TeamPublished Updated
#http#rest#api#status-codes#backend
2xx — Success
| Code | Meaning | Return when |
|---|---|---|
200 OK | Standard success | GET / PUT / PATCH succeeded |
201 Created | Resource created | POST created something; include Location header |
202 Accepted | Queued | Async job started (webhook, export) |
204 No Content | Success, empty body | DELETE succeeded, or toggle with nothing to return |
HTTP/1.1 201 Created
Location: /api/users/42
Content-Type: application/json
{ "id": 42, "email": "ada@example.com" }
3xx — Redirection
| Code | Meaning | Note |
|---|---|---|
301 | Permanent redirect | Use for canonical moves (/blog → /cheatsheets) |
302 / 307 | Temporary redirect | 307 preserves method; 302 may switch POST→GET |
304 | Not Modified | With ETag / If-None-Match caching |
4xx — Client Errors
| Code | Meaning | Return when |
|---|---|---|
400 | Bad Request | Malformed JSON, validation failed |
401 | Unauthorized | Missing/invalid credentials — client must auth |
403 | Forbidden | Authenticated but not allowed (admin-only) |
404 | Not Found | Unknown route or hidden existence |
405 | Method Not Allowed | POST on a read-only route |
409 | Conflict | Duplicate email, version mismatch |
422 | Unprocessable Entity | Well-formed but semantically wrong (Laravel/Rails style) |
429 | Too Many Requests | Rate limit hit — include Retry-After |
// Consistent error shape clients can rely on
return Response.json(
{
error: {
code: 'VALIDATION_ERROR',
message: 'Email is already registered.',
fields: { email: ['taken'] },
},
},
{ status: 409 }
);
5xx — Server Errors
| Code | Meaning |
|---|---|
500 | Unexpected failure — log with request ID, never leak stack traces |
502 | Upstream dependency failed (proxy/gateway) |
503 | Temporarily unavailable — include Retry-After during deploys |
504 | Upstream timed out |
Best Practices
- 401 vs 403: unauthenticated →
401; authenticated but unauthorized →403. - 404 vs 403 on private resources: return
404if the caller should not learn the resource exists. - Always include a machine-readable
code(RATE_LIMITED,PLAN_LIMIT) alongside the HTTP status. - Cache correctly:
GETresponses may be cached;POST/PATCHmust not be cached by default. - Document every code you return — an undocumented
418is a bug report waiting to happen.
Quick Debug Reference (cURL)
curl -i https://ivyivy.com/cheatsheets/git-commands/
curl -s -o /dev/null -w "%{http_code}\n" https://tools.ivyivy.com/health