HTTP Status Codes Complete Reference Guide
Comprehensive guide to HTTP status codes from 1xx to 5xx. Learn what each status code means, when to use them, and common examples for web developers.
Understanding HTTP Status Codes
HTTP status codes are three-digit responses from servers that indicate the result of a client's request. They're essential for debugging, API design, and understanding web communication.
Status Code Categories
- 1xx - Informational: Request received, continuing process
- 2xx - Success: Request successfully received, understood, and accepted
- 3xx - Redirection: Further action needed to complete the request
- 4xx - Client Error: Request contains bad syntax or cannot be fulfilled
- 5xx - Server Error: Server failed to fulfill a valid request
1xx Informational Responses
100 Continue
The server has received the request headers, and the client should proceed to send the request body.
// Client sends headers first
POST /upload HTTP/1.1
Expect: 100-continue
Content-Length: 1000000
// Server responds
HTTP/1.1 100 Continue
// Client proceeds with large body
[... large file data ...]101 Switching Protocols
The server is switching protocols as requested by the client (e.g., upgrading to WebSocket).
2xx Success Responses
200 OK
The request succeeded. The meaning depends on the HTTP method:
// GET - Resource fetched and included in body
GET /api/users/123
Response: 200 OK
Body: { "id": 123, "name": "John Doe" }
// POST - Resource created and included in body
POST /api/users
Body: { "name": "Jane Doe" }
Response: 200 OK
Body: { "id": 124, "name": "Jane Doe" }
// PUT - Resource updated
PUT /api/users/123
Response: 200 OK201 Created
The request succeeded and a new resource was created. Should include Location header.
POST /api/users
Body: { "name": "John Doe", "email": "john@example.com" }
Response: 201 Created
Location: /api/users/123
Body: { "id": 123, "name": "John Doe", "email": "john@example.com" }202 Accepted
Request accepted for processing, but processing not complete. Used for async operations.
POST /api/batch-process
Response: 202 Accepted
Body: {
"message": "Processing started",
"jobId": "abc123",
"statusUrl": "/api/jobs/abc123"
}204 No Content
Request succeeded but no content to return. Common for DELETE requests.
DELETE /api/users/123
Response: 204 No Content
(empty body)3xx Redirection Responses
301 Moved Permanently
The resource has permanently moved to a new URL. Future requests should use the new URL.
GET /old-page
Response: 301 Moved Permanently
Location: /new-page302 Found (Temporary Redirect)
The resource temporarily resides at a different URL. The client should continue using the original URL for future requests.
304 Not Modified
Used for caching. The resource hasn't changed since the last request.
GET /api/data
If-None-Match: "abc123"
// If data unchanged
Response: 304 Not Modified
(Client uses cached version)307 Temporary Redirect & 308 Permanent Redirect
Similar to 302/301 but guarantee the request method won't change.
4xx Client Error Responses
400 Bad Request
The server cannot process the request due to client error (malformed syntax, invalid request).
POST /api/users
Body: { "name": "", "email": "invalid-email" }
Response: 400 Bad Request
Body: {
"error": "Validation failed",
"details": [
{ "field": "name", "message": "Name is required" },
{ "field": "email", "message": "Invalid email format" }
]
}401 Unauthorized
Authentication is required and has failed or not been provided.
GET /api/protected-resource
Response: 401 Unauthorized
WWW-Authenticate: Bearer realm="example"
Body: {
"error": "Authentication required",
"message": "Please provide valid credentials"
}403 Forbidden
The client is authenticated but doesn't have permission to access the resource.
DELETE /api/users/admin
Authorization: Bearer user_token
Response: 403 Forbidden
Body: {
"error": "Insufficient permissions",
"message": "You don't have permission to delete admin users"
}404 Not Found
The requested resource doesn't exist on the server.
GET /api/users/99999
Response: 404 Not Found
Body: {
"error": "Resource not found",
"message": "User with ID 99999 does not exist"
}405 Method Not Allowed
The request method is not supported for the requested resource.
DELETE /api/health
Response: 405 Method Not Allowed
Allow: GET, HEAD
Body: {
"error": "Method not allowed",
"message": "This endpoint only supports GET requests"
}409 Conflict
The request conflicts with the current state of the server.
POST /api/users
Body: { "email": "existing@example.com" }
Response: 409 Conflict
Body: {
"error": "Resource conflict",
"message": "User with this email already exists"
}422 Unprocessable Entity
The request is well-formed but contains semantic errors.
POST /api/transfers
Body: { "amount": 1000, "fromAccount": "A", "toAccount": "A" }
Response: 422 Unprocessable Entity
Body: {
"error": "Validation error",
"message": "Cannot transfer to the same account"
}429 Too Many Requests
The user has sent too many requests in a given time (rate limiting).
GET /api/data
Response: 429 Too Many Requests
Retry-After: 3600
Body: {
"error": "Rate limit exceeded",
"message": "Too many requests. Try again in 1 hour",
"retryAfter": 3600
}5xx Server Error Responses
500 Internal Server Error
The server encountered an unexpected condition that prevented it from fulfilling the request.
GET /api/users
Response: 500 Internal Server Error
Body: {
"error": "Internal server error",
"message": "An unexpected error occurred",
"requestId": "abc123" // For debugging
}501 Not Implemented
The server doesn't support the functionality required to fulfill the request.
502 Bad Gateway
The server, while acting as a gateway or proxy, received an invalid response from the upstream server.
503 Service Unavailable
The server is temporarily unable to handle the request (maintenance, overload).
GET /api/users
Response: 503 Service Unavailable
Retry-After: 120
Body: {
"error": "Service unavailable",
"message": "Server is undergoing maintenance",
"retryAfter": 120
}504 Gateway Timeout
The server, acting as a gateway, didn't receive a timely response from the upstream server.
Best Practices for API Design
Choose the Right Status Code
- Success (2xx): Always use appropriate success codes
- Created resources: Use 201, not 200
- No content: Use 204 for DELETE, not 200 with empty body
- Validation errors: Use 422, not 400
- Authentication: 401 for missing/invalid auth, 403 for insufficient permissions
Include Helpful Error Messages
// Good error response
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format",
"value": "invalid-email"
}
],
"timestamp": "2024-02-09T10:30:00Z",
"path": "/api/users",
"requestId": "abc123"
}
}Handle Errors Consistently
// Express.js error handling
app.use((err, req, res, next) => {
const status = err.status || 500;
const response = {
error: {
code: err.code || 'INTERNAL_ERROR',
message: err.message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
timestamp: new Date().toISOString(),
path: req.path,
requestId: req.id
}
};
res.status(status).json(response);
});Testing Status Codes
// Jest + Supertest
describe('User API', () => {
it('should return 200 for valid GET', async () => {
await request(app)
.get('/api/users/1')
.expect(200);
});
it('should return 404 for non-existent user', async () => {
await request(app)
.get('/api/users/99999')
.expect(404)
.expect(res => {
expect(res.body.error).toBeDefined();
});
});
it('should return 422 for invalid data', async () => {
await request(app)
.post('/api/users')
.send({ name: '' })
.expect(422);
});
});Quick Reference Chart
Common Status Codes Quick Reference: 200 - OK (GET, PUT, PATCH) 201 - Created (POST) 204 - No Content (DELETE) 400 - Bad Request (malformed) 401 - Unauthorized (auth required) 403 - Forbidden (insufficient permissions) 404 - Not Found 422 - Unprocessable Entity (validation errors) 429 - Too Many Requests 500 - Internal Server Error 503 - Service UnavailableTry Our API Tools
Test and debug your APIs with our developer tools: