HTTP Status Codes Explained: The Complete Developer Reference

Every HTTP response comes with a status code. This complete reference explains what every status code means, when to use it, and how to handle it in your application.

HTTP Status Codes Explained: The Complete Developer Reference

What Are HTTP Status Codes?

Every HTTP response includes a three-digit status code that tells the client whether the request succeeded, failed, or requires further action. Status codes are grouped into five classes, each identified by the first digit:

  • 1xx — Informational: The request was received and processing is continuing.
  • 2xx — Success: The request was received, understood, and accepted.
  • 3xx — Redirection: Further action is needed to complete the request.
  • 4xx — Client Error: The request contains bad syntax or cannot be fulfilled.
  • 5xx — Server Error: The server failed to fulfil a valid request.

Understanding status codes is fundamental to building and consuming REST APIs. Using the wrong status code misleads API consumers, breaks client error handling, and causes subtle bugs that are hard to diagnose.

1xx — Informational

Informational responses are rarely seen in everyday API work but are important in certain scenarios.

100 Continue

The server has received the request headers and the client should proceed to send the request body. Used when a client sends a large payload and wants to confirm the server will accept it before transmitting all the data.

101 Switching Protocols

The server agrees to switch protocols as requested by the client. Most commonly seen when upgrading an HTTP connection to a WebSocket connection.

2xx — Success

The 2xx class indicates the request was successfully received, understood, and accepted.

200 OK

The most common success response. The request succeeded and the response body contains the requested data. Used for successful GET, PUT, PATCH, and DELETE requests.

GET /users/1
HTTP/1.1 200 OK
{ "id": 1, "name": "Alice Johnson" }

201 Created

A new resource was successfully created as a result of the request. Should be returned for successful POST requests. Best practice is to include a Location header pointing to the new resource.

POST /users
HTTP/1.1 201 Created
Location: /users/42
{ "id": 42, "name": "Bob Smith" }

202 Accepted

The request has been accepted for processing but processing has not been completed. Used for asynchronous operations — for example, when a job has been queued and the result will be available later.

204 No Content

The request succeeded but there is no content to return. Commonly used for successful DELETE operations and PATCH operations where no updated resource is returned.

DELETE /users/42
HTTP/1.1 204 No Content

206 Partial Content

The server is returning only part of the resource, as requested by the client using a Range header. Used in video streaming and large file downloads to support resumable transfers.

3xx — Redirection

Redirection responses tell the client to take additional action, usually by following a different URL.

301 Moved Permanently

The resource has been permanently moved to a new URL. Clients and search engines should update their bookmarks. All future requests should use the new URL provided in the Location header.

302 Found

The resource is temporarily available at a different URL. Clients should continue to use the original URL for future requests. Commonly used for temporary redirects in web applications.

304 Not Modified

The cached version of the resource is still valid. The client sent a conditional GET request (using If-Modified-Since or ETag) and the resource has not changed. No response body is returned — the client uses its cached copy.

307 Temporary Redirect

Similar to 302, but the client must use the same HTTP method for the redirected request. A POST to a 307-redirected URL must POST to the new URL, not GET.

308 Permanent Redirect

Like 301, but the HTTP method must not change. A POST to a 308-redirected URL must POST to the new URL.

4xx — Client Errors

Client errors indicate the request contains bad syntax, is missing required data, or cannot be fulfilled for a reason attributable to the client.

400 Bad Request

The server cannot process the request due to malformed syntax, invalid data, or missing required fields. Return a clear error message explaining what is wrong so the client can fix it.

POST /users
HTTP/1.1 400 Bad Request
{ "error": "email is required" }

401 Unauthorized

Despite the name, this code means unauthenticated — the client has not provided valid credentials. The client should authenticate and retry. Do not use this to indicate insufficient permissions (use 403 for that).

GET /account
HTTP/1.1 401 Unauthorized
{ "error": "Authentication required" }

403 Forbidden

The client is authenticated but does not have permission to access the resource. Unlike 401, re-authenticating will not help. This is the correct code for authorisation failures.

404 Not Found

The requested resource does not exist on the server. Also used to deliberately hide the existence of a resource that the client is not authorised to know about (instead of returning 403).

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

405 Method Not Allowed

The HTTP method used is not supported for this endpoint. For example, sending a DELETE request to an endpoint that only supports GET and POST. The response should include an Allow header listing permitted methods.

409 Conflict

The request conflicts with the current state of the resource. Commonly returned when trying to create a resource that already exists — for example, registering with an email address that is already in use.

POST /users
HTTP/1.1 409 Conflict
{ "error": "An account with this email already exists" }

410 Gone

The resource has been permanently deleted and will not be available again. Unlike 404, this explicitly tells the client the resource previously existed. Useful for deprecated API versions.

422 Unprocessable Entity

The request was well-formed but failed validation. Use this when the syntax is correct but the semantic content is invalid — for example, a valid JSON body that fails business logic validation.

POST /orders
HTTP/1.1 422 Unprocessable Entity
{
  "errors": {
    "quantity": "must be greater than 0",
    "shippingAddress": "is required"
  }
}

429 Too Many Requests

The client has sent too many requests in a given time period (rate limiting). The response should include a Retry-After header indicating when the client can try again.

HTTP/1.1 429 Too Many Requests
Retry-After: 60
{ "error": "Rate limit exceeded. Try again in 60 seconds." }

5xx — Server Errors

Server errors indicate the server failed to fulfil a valid request. These are never the client's fault.

500 Internal Server Error

A generic catch-all error for unexpected server failures. Use this when something goes wrong that does not fit a more specific 5xx code. Never expose stack traces or internal error details in the response body — log them server-side instead.

501 Not Implemented

The server does not support the functionality required to fulfil the request. Often returned when a client uses an HTTP method the server does not support at all (different from 405, which is per-endpoint).

502 Bad Gateway

The server, acting as a gateway or proxy, received an invalid response from an upstream server. Common in microservice architectures when a downstream service is unavailable or returns garbage.

503 Service Unavailable

The server is temporarily unable to handle the request due to overload or maintenance. Should include a Retry-After header when the outage duration is known.

504 Gateway Timeout

The server, acting as a gateway, did not receive a timely response from an upstream server. Common when a downstream service is too slow to respond within the timeout window.

Cheat Sheet: Most Common Status Codes

CodeNameWhen to Use
200OKSuccessful GET, PUT, PATCH
201CreatedSuccessful POST that creates a resource
204No ContentSuccessful DELETE or update with no body
400Bad RequestInvalid input or missing required fields
401UnauthorizedNot authenticated
403ForbiddenAuthenticated but not authorised
404Not FoundResource does not exist
409ConflictDuplicate resource
422Unprocessable EntityValidation errors
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server failure
503Service UnavailableServer down or overloaded

Common Mistakes to Avoid

  • Returning 200 for errors — Never put an error message inside a 200 response. Status codes exist precisely so clients do not have to parse the body to detect failures.
  • Confusing 401 and 403 — 401 means "you are not logged in." 403 means "you are logged in but not allowed." They require different client behaviour.
  • Using 400 for everything — Use 409 for conflicts, 422 for validation errors, and 404 for missing resources instead of defaulting to 400 for all failures.
  • Exposing internals in 500 responses — Log the full error server-side; return only a safe, generic message to the client.

Conclusion

HTTP status codes are the universal language of the web. Using them correctly makes your API self-documenting, enables automatic error handling in client code, and signals professionalism to every developer who consumes your service.

When building or testing an API, mock your error responses too — not just the happy path. Create a free mock API on Mockable to simulate any status code and test how your application handles each one.