PureTools

HTTP Status Codes: The Complete Reference

PureTools Team· 9 min read
HTTP Status Codes: The Complete Reference

HTTP Status Codes: What Your Server Is Really Telling the Client

Every HTTP response includes a three-digit status code. Get them right and your API is intuitive. Get them wrong and developers spend hours debugging why the client retries on a 200 that should've been a 400.

The Five Classes

RangeCategoryMeaning
1xxInformationalRequest received, continuing
2xxSuccessRequest accepted and processed
3xxRedirectionClient must take additional action
4xxClient ErrorRequest has a problem
5xxServer ErrorServer failed to fulfill valid request

Success Codes (2xx)

CodeNameWhen to Use
200OKGET succeeded, PUT/PATCH updated successfully
201CreatedPOST created a new resource. Include Location header with the new resource URL.
202AcceptedRequest accepted for async processing (e.g., queued job). Not done yet.
204No ContentDELETE succeeded, nothing to return. Also good for PUT with no response body.
// Express.js examples
app.post('/users', (req, res) => {
  const user = createUser(req.body);
  res.status(201).json(user);
});

app.delete('/users/:id', (req, res) => {
  deleteUser(req.params.id);
  res.status(204).send();
});

app.post('/reports', (req, res) => {
  queueReportGeneration(req.body);
  res.status(202).json({ message: 'Report is being generated' });
});

Redirection Codes (3xx)

CodeNameWhen to Use
301Moved PermanentlyResource URL changed forever. Browsers cache this. Use for domain migrations.
302FoundTemporary redirect. Browser uses GET for the redirect (even if original was POST).
304Not ModifiedConditional GET — resource hasn't changed since the cached version.
307Temporary RedirectLike 302, but preserves the HTTP method. POST stays POST.
308Permanent RedirectLike 301, but preserves the HTTP method.

Common mistake: Using 302 when you mean 301. If the URL change is permanent (moved to a new domain, changed URL structure), use 301 so search engines update their index.

Client Error Codes (4xx)

CodeNameWhen to Use
400Bad RequestMalformed JSON, missing required fields, invalid data types
401UnauthorizedNo authentication provided or token is invalid. Misleading name — it means "unauthenticated".
403ForbiddenAuthenticated but doesn't have permission. The user is known, but can't access this resource.
404Not FoundResource doesn't exist at this URL.
405Method Not AllowedEndpoint exists, but not for this HTTP method (e.g., POST to a GET-only endpoint).
409ConflictConflicts with current state — duplicate email, version mismatch, concurrent edit.
422Unprocessable EntityJSON is valid, but the data doesn't pass validation (e.g., email format wrong).
429Too Many RequestsRate limited. Include Retry-After header.
// 400 vs 422 — both are valid, pick one convention
// 400: request is structurally wrong (malformed JSON)
// 422: request is structurally fine, but data is invalid

app.post('/users', (req, res) => {
  if (!req.body.email) {
    return res.status(422).json({
      error: 'Validation failed',
      details: [{ field: 'email', message: 'Email is required' }]
    });
  }
});

Server Error Codes (5xx)

CodeNameWhen to Use
500Internal Server ErrorGeneric "something broke." Don't leak stack traces to clients.
502Bad GatewayReverse proxy (Nginx) couldn't connect to the upstream server (your app crashed).
503Service UnavailableServer is temporarily down — maintenance, overloaded. Include Retry-After.
504Gateway TimeoutReverse proxy timed out waiting for your app to respond.

Key principle: 4xx means the client needs to fix something. 5xx means the server needs to fix something. If the client can never succeed by changing their request, it's a 5xx.

Decision Tree

Is the request valid?
├── No → Is it a structural problem?
│   ├── Yes → 400 Bad Request
│   └── No → 422 Unprocessable Entity
├── Yes → Is the user authenticated?
│   ├── No → 401 Unauthorized
│   └── Yes → Is the user authorized?
│       ├── No → 403 Forbidden
│       └── Yes → Does the resource exist?
│           ├── No → 404 Not Found
│           └── Yes → Was it processed successfully?
│               ├── Yes → 200/201/204
│               └── No → 500 Internal Server Error

Quick reference: HTTP Status Codes — searchable table with descriptions, categories, and examples for every code.