Click any status code to expand the explanation and examples.
ℹ️ 1xx — Informational
100 Continue informational
Client: POST /upload HTTP/1.1
Expect: 100-continue
Server: HTTP/1.1 100 Continue
(client now sends the body)
Used with large uploads — the client checks if the server will accept the request before sending the full body.
101 Switching Protocols informational
Client: GET /chat HTTP/1.1
Upgrade: websocket
Server: HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Most commonly seen when upgrading an HTTP connection to WebSocket.
✅ 2xx — Success
200 OK success
GET /api/users/1 → 200
{ "id": 1, "name": "Alice" }
Use for: successful GET requests, successful PUT/PATCH updates that return the updated resource.
201 Created success
POST /api/users → 201
Location: /api/users/42
{ "id": 42, "name": "Bob" }
Use for: successful POST requests that create a new resource. Include a Location header pointing to the new resource.
204 No Content success
DELETE /api/users/42 → 204 (empty body)Use for: successful DELETE requests, or PUT/PATCH when you don't need to return the updated resource.
206 Partial Content success
Client: GET /video.mp4
Range: bytes=0-1023
Server: HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Used for video streaming, resumable downloads, and large file transfers.
↪️ 3xx — Redirection
301 Moved Permanently redirect
GET /old-page → 301 Location: /new-pageBrowsers and search engines will update their links. Use for permanent URL changes, domain migrations, or HTTP→HTTPS redirects.
302 Found (Temporary Redirect) redirect
GET /promo → 302 Location: /seasonal-saleThe client should continue using the original URL for future requests. Use for temporary redirects like maintenance pages.
304 Not Modified redirect
Client: GET /api/data
If-None-Match: "abc123"
Server: 304 Not Modified
(no body — client uses cached version)
Saves bandwidth. Works with ETag and If-None-Match or Last-Modified and If-Modified-Since headers.
307 Temporary Redirect redirect
POST /api/submit → 307 Location: /api/v2/submit (client re-sends POST to new URL)Use when you need to redirect a POST and want the client to POST again (not convert to GET).
308 Permanent Redirect redirect
POST /api/old → 308 Location: /api/new (client re-sends POST to new URL)Use for permanent API endpoint changes where you need to preserve the HTTP method.
❌ 4xx — Client Errors
400 Bad Request client error
POST /api/users
{ "email": "not-an-email" }
→ 400
{ “error”: “Invalid email format” }
Use for: invalid JSON, missing required fields, wrong data types, validation errors that aren’t covered by a more specific code.
401 Unauthorized client error
GET /api/profile (no Authorization header)The name is misleading — it means “unauthenticated”, not “unauthorized”. The client needs to log in.→ 401 { “error”: “Authentication required” }
403 Forbidden client error
DELETE /api/admin/users/1 Authorization: Bearer user-tokenUse when the user is logged in but lacks the required role or permissions. Re-authenticating won’t help.→ 403 { “error”: “Admin access required” }
404 Not Found client error
GET /api/users/99999 → 404
{ "error": "User not found" }
Use for: missing resources, invalid URLs. Sometimes used instead of 403 to hide the existence of a resource from unauthorized users.
405 Method Not Allowed client error
DELETE /api/users → 405 Allow: GET, POSTInclude an
Allow header listing the supported methods.
409 Conflict client error
POST /api/users
{ "email": "alice@example.com" }
→ 409
{ “error”: “A user with this email already exists” }
Use for: duplicate entries, version conflicts, trying to delete a resource that has dependencies.
422 Unprocessable Entity client error
POST /api/orders
{ "quantity": -5 }
→ 422
{ “errors”: [{ “field”: “quantity”, “message”: “Must be positive” }] }
Use for: business logic validation errors. The JSON is valid (not 400), but the values don’t make sense.
429 Too Many Requests client error
→ 429
Retry-After: 60
{ "error": "Rate limit exceeded. Try again in 60 seconds." }
Include a Retry-After header telling the client when to try again.
💥 5xx — Server Errors
500 Internal Server Error server error
GET /api/users → 500
{ "error": "Internal server error" }
The catch-all server error. Never expose stack traces or internal details to the client in production. Log the details server-side.
502 Bad Gateway server error
Client → Nginx → App Server (crashed) → 502 Bad GatewayCommon when: your app server crashed, a reverse proxy can't reach the backend, or a Lambda function timed out behind API Gateway.
503 Service Unavailable server error
→ 503
Retry-After: 300
{ "error": "Service under maintenance" }
Use for: planned maintenance, server overload, or temporary outages. Include Retry-After if you know when it'll be back.
504 Gateway Timeout server error
Client → Load Balancer → App Server (too slow) → 504 Gateway TimeoutCommon when: a database query takes too long, an external API call times out, or the backend is overloaded.
🎯 API Design Tips
Choosing the right status code best practice
POST (create): Success → 201 Created Duplicate → 409 Conflict Invalid data → 422 Unprocessable EntityGET (read): Found → 200 OK Not found → 404 Not Found Cached → 304 Not Modified
PUT/PATCH (update): Updated (with body) → 200 OK Updated (no body) → 204 No Content Not found → 404 Not Found
DELETE: Deleted → 204 No Content Not found → 404 Not Found
Error response format best practice
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"details": [
{ "field": "email", "message": "Must be a valid email" },
{ "field": "age", "message": "Must be at least 18" }
]
}
}
Always include a human-readable message and a machine-readable error code.
Quick Reference Table
| Code | Name | When to use |
|---|---|---|
200 | OK | Successful GET, PUT, PATCH |
201 | Created | Successful POST (new resource) |
204 | No Content | Successful DELETE |
301 | Moved Permanently | Permanent URL change |
302 | Found | Temporary redirect |
304 | Not Modified | Cached response is still valid |
400 | Bad Request | Malformed request |
401 | Unauthorized | Not authenticated |
403 | Forbidden | Not authorized (no permission) |
404 | Not Found | Resource doesn’t exist |
409 | Conflict | Duplicate / state conflict |
422 | Unprocessable Entity | Validation error |
429 | Too Many Requests | Rate limited |
500 | Internal Server Error | Unexpected server error |
502 | Bad Gateway | Upstream server error |
503 | Service Unavailable | Temporary outage |
504 | Gateway Timeout | Upstream timeout |