HTTP Status Codes: Complete Guide with Examples

THEJORD Team1 min read
httpapiwebdevelopment

All HTTP status codes explained: 2xx, 3xx, 4xx, 5xx. When to use them in your APIs.

HTTP Status Codes: Complete Guide with Examples

Introduction to HTTP Status Codes

HTTP status codes are three-digit numbers returned by servers to indicate the result of a client's request. Understanding these codes is essential for debugging APIs, building robust applications, and creating better user experiences. This guide covers all major status codes with practical examples.

Status Code Categories

Overview

RangeCategoryDescription
1xxInformationalRequest received, continuing process
2xxSuccessRequest successfully received and processed
3xxRedirectionFurther action needed to complete request
4xxClient ErrorRequest contains error or cannot be fulfilled
5xxServer ErrorServer failed to fulfill valid request

1xx Informational

100 Continue

Server acknowledges the request headers. Client should continue with the request body.

// Used with large uploads
// Client sends: Expect: 100-continue header
// Server responds: 100 Continue
// Client then sends body

101 Switching Protocols

Server is switching to a different protocol as requested by client.

// WebSocket upgrade
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade

2xx Success

200 OK

The request succeeded. Response body contains the requested data.

GET /api/users/123
HTTP/1.1 200 OK
{
  "id": 123,
  "name": "John Doe"
}

201 Created

A new resource was successfully created.

POST /api/users
HTTP/1.1 201 Created
Location: /api/users/124
{
  "id": 124,
  "name": "Jane Doe"
}

204 No Content

Request succeeded but no content to return.

DELETE /api/users/123
HTTP/1.1 204 No Content
// Empty body

206 Partial Content

Server is delivering only part of the resource (range request).

// Useful for video streaming, resumable downloads
GET /video.mp4
Range: bytes=0-999

HTTP/1.1 206 Partial Content
Content-Range: bytes 0-999/10000

3xx Redirection

301 Moved Permanently

Resource permanently moved to a new URL. Search engines update their index.

GET /old-page
HTTP/1.1 301 Moved Permanently
Location: /new-page

// Use for: domain changes, URL restructuring

302 Found (Temporary Redirect)

Resource temporarily at different URL. Original URL remains valid.

GET /login
HTTP/1.1 302 Found
Location: /dashboard

// Use for: login redirects, A/B testing

304 Not Modified

Resource hasn't changed since last request. Use cached version.

GET /api/data
If-None-Match: "abc123"

HTTP/1.1 304 Not Modified
// No body - use cached response

307 Temporary Redirect

Like 302, but method and body must not change.

POST /api/old-endpoint
HTTP/1.1 307 Temporary Redirect
Location: /api/new-endpoint
// Client must POST to new location

308 Permanent Redirect

Like 301, but method and body must not change.

4xx Client Errors

400 Bad Request

Server cannot process the request due to client error.

POST /api/users
{ "name": } // Invalid JSON

HTTP/1.1 400 Bad Request
{
  "error": "Invalid JSON syntax"
}

401 Unauthorized

Authentication required. Client must provide credentials.

GET /api/protected
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

// Solution: Add Authorization header

403 Forbidden

Server understood request but refuses to authorize it.

DELETE /api/users/1
// Logged in but not admin

HTTP/1.1 403 Forbidden
{
  "error": "Admin access required"
}

404 Not Found

Requested resource doesn't exist.

GET /api/users/99999
HTTP/1.1 404 Not Found
{
  "error": "User not found"
}

405 Method Not Allowed

HTTP method not supported for this resource.

POST /api/users/123 // Should be PUT
HTTP/1.1 405 Method Not Allowed
Allow: GET, PUT, DELETE

409 Conflict

Request conflicts with current state of the server.

POST /api/users
{ "email": "existing@email.com" }

HTTP/1.1 409 Conflict
{
  "error": "Email already exists"
}

422 Unprocessable Entity

Request is well-formed but semantically incorrect.

POST /api/users
{ "email": "not-an-email", "age": -5 }

HTTP/1.1 422 Unprocessable Entity
{
  "errors": {
    "email": "Invalid email format",
    "age": "Must be positive"
  }
}

429 Too Many Requests

Rate limit exceeded. Client should slow down.

HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
  "error": "Rate limit exceeded",
  "retryAfter": 60
}

5xx Server Errors

500 Internal Server Error

Generic server error. Something went wrong.

GET /api/data
HTTP/1.1 500 Internal Server Error
{
  "error": "An unexpected error occurred"
}

502 Bad Gateway

Server acting as gateway received invalid response from upstream.

// Nginx couldn't reach your app server
HTTP/1.1 502 Bad Gateway

503 Service Unavailable

Server temporarily unable to handle requests.

HTTP/1.1 503 Service Unavailable
Retry-After: 300
// Maintenance, overload, etc.

504 Gateway Timeout

Server didn't receive timely response from upstream server.

// Request took too long
HTTP/1.1 504 Gateway Timeout

Handling Status Codes in Code

JavaScript/Fetch

async function fetchData(url) {
  const response = await fetch(url);

  if (response.ok) { // 200-299
    return response.json();
  }

  switch (response.status) {
    case 401:
      throw new Error('Please log in');
    case 403:
      throw new Error('Access denied');
    case 404:
      throw new Error('Not found');
    case 429:
      const retryAfter = response.headers.get('Retry-After');
      throw new Error(`Rate limited. Retry in ${retryAfter}s`);
    default:
      throw new Error(`HTTP ${response.status}`);
  }
}

Express.js

app.get('/api/users/:id', async (req, res) => {
  try {
    const user = await User.findById(req.params.id);

    if (!user) {
      return res.status(404).json({ error: 'User not found' });
    }

    res.status(200).json(user);
  } catch (error) {
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.post('/api/users', async (req, res) => {
  const user = await User.create(req.body);
  res.status(201)
    .location(`/api/users/${user.id}`)
    .json(user);
});

Best Practices

API Design

  • Use 200 for successful GET/PUT/PATCH
  • Use 201 for successful POST that creates
  • Use 204 for successful DELETE
  • Use 400 for validation errors
  • Use 401 for missing authentication
  • Use 403 for insufficient permissions
  • Include helpful error messages in body

Error Handling

  • Always check status codes in clients
  • Log 5xx errors for investigation
  • Implement retry logic for 503/504
  • Respect Retry-After headers

Tools and Resources

For debugging HTTP requests:

Conclusion

HTTP status codes are the foundation of web communication. Key takeaways:

  • 2xx means success, 4xx means client error, 5xx means server error
  • Use specific codes to communicate exact outcomes
  • Include helpful error messages in response bodies
  • Handle errors gracefully in your applications

For more developer resources, explore our free online tools. For the complete specification, see MDN HTTP Status Codes and HTTP Status Codes Reference.