Introduction
HTTP status codes are three-digit numbers that indicate the result of an HTTP request. Understanding them is crucial for building and debugging REST APIs. This guide covers all status codes and when to use them.
Status Code Categories
1xx: Informational
Temporary responses indicating the request was received and being processed.
- 100 Continue: Server received headers, client should send body
- 101 Switching Protocols: Server agrees to protocol upgrade
- 102 Processing: Request is being processed (WebDAV)
- 103 Early Hints: Some headers available (H2/H3)
2xx: Success
Request was successfully received, understood, and accepted.
200 OK
Standard success response:
GET /api/users/1 HTTP/1.1
Host: api.example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"name": "Alice"
}
Use for:
- GET requests (retrieve resource)
- PUT requests (update successful)
- POST requests (when no specific code fits)
201 Created
Resource successfully created:
POST /api/users HTTP/1.1
Content-Type: application/json
{
"name": "Bob",
"email": "bob@example.com"
}
HTTP/1.1 201 Created
Location: /api/users/123
Content-Type: application/json
{
"id": 123,
"name": "Bob",
"email": "bob@example.com"
}
Use for:
- POST requests (resource created)
- Include
Locationheader with new resource URL
204 No Content
Success with no response body:
DELETE /api/users/123 HTTP/1.1
HTTP/1.1 204 No Content
Use for:
- DELETE requests (resource deleted)
- PUT requests (update, nothing to return)
- Headers-only responses
202 Accepted
Request accepted for processing (async):
POST /api/jobs HTTP/1.1
HTTP/1.1 202 Accepted
Location: /api/jobs/456/status
Use for:
- Asynchronous processing
- Background jobs
- Long-running operations
3xx: Redirection
Client must take additional action to complete request.
301 Moved Permanently
Resource permanently moved:
GET /old-page HTTP/1.1
HTTP/1.1 301 Moved Permanently
Location: /new-page
Use for:
- Permanent URL changes
- SEO redirects
- Domain migrations
302 Found (Temporary Redirect)
Resource temporarily moved:
HTTP/1.1 302 Found
Location: /temporary-location
Use for:
- Temporary redirects
- Maintenance pages
304 Not Modified
Resource not modified (caching):
GET /api/data HTTP/1.1
If-None-Match: "abc123"
HTTP/1.1 304 Not Modified
ETag: "abc123"
Use for:
- Conditional requests
- Cache validation
4xx: Client Errors
Client made an error (bad request, unauthorized, etc.).
400 Bad Request
Malformed request:
{
"error": "Invalid request body",
"details": {
"email": "Must be valid email address"
}
}
Use for:
- Validation errors
- Malformed JSON
- Missing required fields
401 Unauthorized
Authentication required:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
{
"error": "Authentication required"
}
Use for:
- Missing or invalid credentials
- Expired tokens
403 Forbidden
Authenticated but not authorized:
{
"error": "You don't have permission to access this resource"
}
Use for:
- Insufficient permissions
- Resource access denied
404 Not Found
Resource doesn’t exist:
GET /api/users/999 HTTP/1.1
HTTP/1.1 404 Not Found
{
"error": "User not found"
}
Use for:
- Resource doesn’t exist
- Invalid URL
- Deleted resource
409 Conflict
Request conflicts with current state:
{
"error": "Email already exists",
"conflict": {
"field": "email",
"value": "user@example.com"
}
}
Use for:
- Duplicate entries
- Version conflicts
- Resource state conflicts
422 Unprocessable Entity
Well-formed but semantically invalid:
{
"error": "Validation failed",
"errors": [
{
"field": "age",
"message": "Must be positive number"
}
]
}
Use for:
- Validation errors
- Business logic violations
5xx: Server Errors
Server failed to fulfill valid request.
500 Internal Server Error
Generic server error:
{
"error": "Internal server error",
"requestId": "abc-123-def"
}
Use for:
- Unexpected server errors
- Database failures
- Application crashes
502 Bad Gateway
Invalid response from upstream server:
HTTP/1.1 502 Bad Gateway
Use for:
- Proxy/gateway issues
- Upstream server errors
503 Service Unavailable
Service temporarily unavailable:
HTTP/1.1 503 Service Unavailable
Retry-After: 60
Use for:
- Maintenance mode
- Overloaded servers
- Temporary outages
REST API Status Code Usage
GET Requests
// Resource found
GET /api/users/1
→ 200 OK
// Resource not found
GET /api/users/999
→ 404 Not Found
// Not modified (caching)
GET /api/data (with If-None-Match)
→ 304 Not Modified
POST Requests
// Resource created
POST /api/users
→ 201 Created (with Location header)
// Validation error
POST /api/users (invalid data)
→ 400 Bad Request
// Conflict
POST /api/users (duplicate email)
→ 409 Conflict
PUT Requests
// Updated successfully
PUT /api/users/1
→ 200 OK (with updated resource)
→ 204 No Content (no body)
// Resource not found
PUT /api/users/999
→ 404 Not Found
// Validation error
PUT /api/users/1 (invalid data)
→ 400 Bad Request
DELETE Requests
// Deleted successfully
DELETE /api/users/1
→ 204 No Content
// Resource not found
DELETE /api/users/999
→ 404 Not Found
// Conflict (cannot delete)
DELETE /api/users/1 (has dependencies)
→ 409 Conflict
Best Practices
✅ Do This
1. Use appropriate status codes
if (!user) {
return res.status(404).json({ error: "User not found" });
}
if (user.email === newEmail) {
return res.status(409).json({ error: "Email already exists" });
}
return res.status(200).json(user);
2. Include error details
{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"details": [
{
"field": "email",
"message": "Must be valid email"
}
]
}
3. Use consistent error format
interface ApiError {
error: string;
code: string;
details?: any;
requestId: string;
}
❌ Don’t Do This
1. Don’t use 200 for errors
// ❌ Bad
return res.status(200).json({ error: "Not found" });
// ✅ Good
return res.status(404).json({ error: "Not found" });
2. Don’t expose internal errors
// ❌ Bad - exposes stack trace
return res.status(500).json({
error: error.message,
stack: error.stack,
});
// ✅ Good
return res.status(500).json({
error: "Internal server error",
requestId: req.id,
});
Status Code Reference
Use our tools:
- HTTP Status Code Lookup - Complete reference
Conclusion
HTTP status codes are essential for REST APIs:
Key principles:
- 2xx = Success
- 3xx = Redirection
- 4xx = Client error
- 5xx = Server error
Best practices:
- Use appropriate codes
- Include helpful error messages
- Be consistent
- Document your API
Next Steps
- Lookup codes with HTTP Status Lookup
- Learn REST API Best Practices
- Explore API Development