FOUNDATIONS / SYSTEM CONCEPT BRIEF

HTTP status codes

An HTTP status code is the three-digit number a server returns with every response to say what happened.

BeginnerPhase 01 / Topic 14 of 17RequirementsTrade-offsFailure modes
01

Overview

An HTTP status code is the three-digit number a server returns with every response to say what happened. The first digit is the class - 1xx informational, 2xx success, 3xx redirection, 4xx client error (the request was wrong), and 5xx server error (the server failed on a valid request).

Correct status codes are part of an API's contract. Clients, browsers, caches, load balancers, retry libraries, and monitoring all make decisions from them. Returning 200 with an error message in the body, or 500 for invalid input, breaks retries, alerting, and caching in subtle ways.

A delivery receipt

A courier writes one code on the receipt: delivered (2xx), moved to a new address (3xx), wrong address from sender (4xx), or our truck broke down (5xx). The sender knows immediately whether to fix the address or simply try again later.

02

When to use it

  • Designing REST API responses and error handling.
  • Deciding which failures a client should retry.
  • Configuring health checks, alerts, and dashboards.
  • Debugging proxies, CDNs, and load balancers.
03

Where it shows up in interviews

API error contract

Recognize it when: design the responses of an API.

  • Design a REST API for orders
  • Design a payment API
Retry decisions

Recognize it when: which failures are safe to retry?

  • Design a resilient API client
  • Design webhook delivery
04

Where it is used in real software

Browsers and CDNs

Browsers follow 301/302 redirects automatically, and CDNs cache 200 and 404 responses by default rules while never caching most 5xx responses.

Load balancers

AWS ALB and Nginx mark targets unhealthy based on health-check status codes and return 502/503/504 when upstreams fail.

Public APIs

GitHub and Stripe return 401, 403, 404, 409, 422, and 429 with machine-readable error bodies so SDKs can react correctly.

05

Key terms

2xx success
200 OK, 201 Created, 202 Accepted, 204 No Content.
3xx redirection
301 permanent, 302/307 temporary, 304 Not Modified (use cache).
4xx client error
400 bad request, 401 unauthenticated, 403 forbidden, 404 not found, 409 conflict, 422 validation, 429 rate limited.
5xx server error
500 internal error, 502 bad gateway, 503 unavailable, 504 gateway timeout.
Retry-After
Header telling clients when to retry (with 429 or 503).
06

How it works, step by step

  1. 1
    Decide who is at fault

    Client mistake is 4xx; server or dependency failure is 5xx.

  2. 2
    Pick the most specific code

    404 for a missing resource, 409 for a state conflict, 422 for invalid fields.

  3. 3
    Return a structured body

    Error code, message, and details (for example RFC 9457 Problem Details).

  4. 4
    Add helpful headers

    Location for 201/3xx, Retry-After for 429/503, ETag for caching.

  5. 5
    Monitor by class

    Alert on 5xx rate; track 4xx trends for client or UX issues.

How a client reacts to each class
Step 1 / 4
Request
2xx
3xx
4xx
5xx

STEP 12xx means success. Use the response; 201 includes a Location header for the new resource.

07

Choosing codes for an orders API

POST /orders and GET /orders/{id}

Step 1 / 8
SituationStatusWhy
Order created201 CreatedNew resource with Location header
Missing required field422 Unprocessable ContentRequest is well-formed but invalid
No or expired token401 UnauthorizedAuthentication needed
User cannot view this order403 ForbiddenAuthenticated but not allowed
Order not found404 Not FoundResource does not exist
Duplicate idempotency key with different body409 ConflictState conflict
Too many requests429 Too Many RequestsRate limit with Retry-After
Database down503 Service UnavailableTemporary server-side failure

NOWSituation: Order created | Status: 201 Created | Why: New resource with Location header

Precise codes let clients decide automatically whether to fix, wait, or retry.

08

Implementation

class HttpError extends Error {  constructor(readonly status: number, readonly code: string, message: string, readonly headers: Record<string, string> = {}) {    super(message);  }} app.post("/orders", async (req, res, next) => {  try {    if (!req.user) throw new HttpError(401, "UNAUTHENTICATED", "Sign in required");    const errors = validateOrder(req.body);    if (errors.length) return res.status(422).json({ code: "VALIDATION_FAILED", errors });    const order = await orders.create(req.user.id, req.body);    res.status(201).location(`/orders/${order.id}`).json(order);  } catch (err) {    next(err);  }}); // One place maps errors to status codes and safe messagesapp.use((err: unknown, _req: Request, res: Response, _next: unknown) => {  if (err instanceof HttpError) {    res.set(err.headers).status(err.status).json({ code: err.code, message: err.message });  } else {    console.error(err);    res.status(500).json({ code: "INTERNAL", message: "Something went wrong" });  }}); // Client: retry only what is safe to retryconst retryable = (status: number) => status === 429 || status === 502 || status === 503 || status === 504;
09

Complexity and performance

Status classes5 (1xx-5xx)

The first digit carries most of the meaning.

Codes worth memorizing~15

200, 201, 204, 301, 302, 304, 400, 401, 403, 404, 409, 422, 429, 500, 502, 503, 504.

10

Trade-offs

Precision vs simplicity

Very specific codes help clients but can leak information (403 vs 404 reveals a resource exists); some APIs return 404 for both on purpose.

400 vs 422

Teams differ on using 400 for all bad input or 422 for semantic validation errors; pick one convention and document it.

11

Variants and related techniques

Problem Details (RFC 9457)

Standard JSON error body with type, title, status, detail, and instance.

gRPC status codes

gRPC uses its own set (OK, INVALID_ARGUMENT, NOT_FOUND, UNAVAILABLE) that map to HTTP codes at gateways.

12

Common mistakes

  • 200 OK with an error in the body.

    Fix: Monitoring, caches, and retries all misread it; return the real status.

  • 500 for invalid input.

    Fix: Client mistakes are 4xx; reserve 5xx for server failures so alerts stay meaningful.

  • Confusing 401 and 403.

    Fix: 401 means not authenticated (who are you?); 403 means authenticated but not allowed.

13

Interview questions

What is the difference between 401 and 403?

401 Unauthorized means the request lacks valid authentication, so the client should sign in or refresh its token. 403 Forbidden means the server knows who the caller is but they do not have permission; retrying with the same credentials will not help.

Which status codes should a client retry?

Usually 429 (after Retry-After), 502, 503, and 504, plus network errors, and only for idempotent requests or requests with idempotency keys. 4xx errors other than 429 indicate a problem with the request itself.

14

Practice problems

ProblemDifficultyWhat it trains
Assign status codes to 10 API scenariosEasyPicking specific codes.
Design an error contract for a public APIMediumCodes, bodies, and headers.