HTTP Status Codes Explained

beginner
10 min

HTTP Status Codes Explained

Every HTTP response begins with a three-digit status code, and it is the first thing any client checks. A well-chosen status code lets a caller know instantly whether to celebrate, retry, fix their request, or page the on-call engineer. In this lesson we tour the five status classes and the specific codes every API developer should know cold.

The Five Classes

Status codes are grouped by their first digit:

  • 1xx Informational: interim responses, rarely seen in REST work.
  • 2xx Success: the request was received and processed correctly.
  • 3xx Redirection: the resource lives somewhere else.
  • 4xx Client Error: the caller did something wrong.
  • 5xx Server Error: the server failed; the caller is blameless.

The 4xx versus 5xx distinction is the most important habit to build. If validation fails, that is the client's fault (4xx). If your database connection dies, that is your fault (5xx).

Success Codes You Will Actually Use

  • 200 OK: the generic success for GET, PUT, and PATCH, with a body.
  • 201 Created: a POST created a resource; include a Location header pointing to it.
  • 202 Accepted: the request was queued for asynchronous processing, useful for long jobs like video encoding.
  • 204 No Content: success with nothing to return, the natural response for DELETE.
http
HTTP/1.1 201 Created Location: /api/users/512 Content-Type: application/json {"id": 512, "email": "maya@example.com"}

Client Errors: Blame the Request

  • 400 Bad Request: malformed JSON or failed validation. Include details in the body so the caller can fix it.
  • 401 Unauthorized: the caller is not authenticated; credentials are missing or invalid. (The name is misleading; it really means unauthenticated.)
  • 403 Forbidden: the caller is authenticated but not allowed to do this. A regular user hitting an admin endpoint gets 403, not 401.
  • 404 Not Found: the resource does not exist. Also commonly used to hide resources a caller should not know exist.
  • 409 Conflict: the request clashes with current state, like registering an email that is already taken.
  • 422 Unprocessable Entity: syntactically valid JSON that fails business rules. Many APIs use 400 for this too; pick one convention and stick to it.
  • 429 Too Many Requests: the caller hit a rate limit. Send a Retry-After header.

Server Errors: Blame Yourself

  • 500 Internal Server Error: an unhandled exception. Log the details privately, return a generic message publicly.
  • 502 Bad Gateway and 504 Gateway Timeout: an upstream service or proxy failed, common in microservice chains.
  • 503 Service Unavailable: the server is overloaded or in maintenance; pair it with Retry-After.

A production example: an e-commerce checkout that calls a payment provider should map a provider timeout to 502 or 504, not 500, so operators can immediately see where the failure originated.

Choosing Codes in Practice

A simple decision path covers most cases: Did it work? Use 200, 201, 202, or 204 depending on the situation. Is the request itself wrong? Use the most specific 4xx. Did the server break? Use 5xx and log everything. Never return 200 with an error message inside the body; it breaks client error handling, HTTP caching, and monitoring dashboards all at once.

Key Takeaways

  • The first digit sorts every code: 2xx success, 4xx caller error, 5xx server error.
  • Use 201 for creation, 204 for deletion, 401 for missing auth, 403 for missing permission.
  • Return 429 with Retry-After when rate limiting.
  • Never wrap failures in a 200 response.

Next up: JSON in REST APIs, the data format that carries almost every modern API payload.