</>StackKit
</>StackKit

Developer tutorials & guides

HTTP request and response visualization
Tools

HTTP Status Codes Explained: The Complete Developer Guide

Understand every important HTTP status code, when to use each one, common mistakes, and how they affect caching, security, and SEO.

S
Sam Rivera
March 6, 20257 min read
#http#web#api#backend#fundamentals

Why Status Codes Matter

HTTP status codes communicate intent. A 200 and a 201 both mean success, but they mean different things. A 401 and 403 are both "you can't do this," but for different reasons. Using the right status code makes your API self-documenting and allows clients to handle responses correctly.


1xx — Informational

Rarely used directly in application code.

100 Continue — Server received the request headers, client should proceed. 101 Switching Protocols — Used when upgrading to WebSockets.


2xx — Success

200 OK The standard success response. Use for GET, PATCH, PUT.

201 Created Resource was created. Always include a Location header pointing to the new resource:

HTTP/1.1 201 Created
Location: /api/users/42

202 Accepted Request received and will be processed asynchronously. Useful for long-running jobs:

HTTP/1.1 202 Accepted
Location: /api/jobs/99   <- poll here for status

204 No Content Success but nothing to return. Use for DELETE and some PUT/PATCH responses.


3xx — Redirection

301 Moved Permanently Resource has permanently moved. Browsers and search engines update their cache. Use for permanent URL changes.

302 Found (Temporary Redirect) Use for temporary redirects. Search engines don't update their index.

304 Not Modified Client's cached version is still valid. Used with ETags and Cache-Control.

307 Temporary Redirect Like 302 but guarantees the HTTP method is preserved (POST stays POST).

308 Permanent Redirect Like 301 but preserves HTTP method.


4xx — Client Errors

400 Bad Request The request is malformed or has invalid parameters. Include error details:

{
  "error": "VALIDATION_ERROR",
  "details": [{ "field": "email", "message": "Invalid format" }]
}

401 Unauthorized (poorly named) Actually means "not authenticated." No valid credentials provided.

403 Forbidden Authenticated but not authorized. You know who they are, they just can't do this.

404 Not Found Resource doesn't exist. Also used to avoid revealing existence of private resources.

405 Method Not Allowed HTTP method not supported for this endpoint. Include an Allow header:

HTTP/1.1 405 Method Not Allowed
Allow: GET, POST

409 Conflict Request conflicts with current state. Use for duplicate resource creation (email already registered) or version conflicts.

410 Gone Resource existed but has been permanently deleted. Unlike 404, signals intentional removal.

422 Unprocessable Entity Request is well-formed but semantically invalid. Common for business logic validation errors.

429 Too Many Requests Rate limit exceeded. Include retry information:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1714953600

5xx — Server Errors

500 Internal Server Error Generic server error. Use when something unexpected breaks. Never include stack traces in production responses.

501 Not Implemented Server doesn't support the requested functionality.

502 Bad Gateway Upstream server (database, microservice) returned an invalid response.

503 Service Unavailable Server temporarily overloaded or down for maintenance.

HTTP/1.1 503 Service Unavailable
Retry-After: 120

504 Gateway Timeout Upstream server didn't respond in time.


Common Mistakes

Using 200 for errors:

// Don't do this
HTTP/1.1 200 OK
{ "success": false, "error": "User not found" }

// Do this
HTTP/1.1 404 Not Found
{ "error": "USER_NOT_FOUND", "message": "User does not exist" }

Confusing 401 and 403:

  • No token provided → 401
  • Token provided but permission denied → 403

Using 400 for everything: Use the most specific code: 401, 403, 404, 409, 422. Reserve 400 for malformed request syntax.


Status Codes and Caching

  • 200 — cacheable with explicit Cache-Control
  • 301 — cached permanently by browsers
  • 302 — not cached
  • 304 — tells browser to use cached version
  • 404 — sometimes cached; consider Cache-Control: no-store

Conclusion

HTTP status codes are a shared vocabulary between your API and its clients. Use them precisely and your API becomes self-documenting. The most impactful habits: always return 201 for POST creation, distinguish 401 from 403, and include error details in 4xx responses.

#http#web#api#backend#fundamentals