DevAtlas

Learn

  • Dashboard
  • Learning Paths
  • All Categories
  • Topics

Practice

  • Interview Questions
  • Flashcards
  • Quizzes
  • Study Plans

Personal

  • Bookmarks
  • Notes
  • Progress
  • PDF Library
  • Settings
  • About
  1. Topics
  2. HTTP Status Codes
0%
HTTP and Web Fundamentals

HTTP Status Codes

Every HTTP response carries a three-digit status code that says how the request went. Learn the five classes and the codes you will actually meet.

Beginner22 min study10 min read
Export PDF

Prerequisites: HTTP Request and Response

Learning objectives

  • Name the five status code classes (1xx–5xx) and what each one signals.
  • Recognize the most common codes such as 200, 201, 204, 301, 302, 304, 400, 401, 403, 404, 409, 422, 429, 500, 502 and 503.
  • Distinguish 401 (authentication) from 403 (authorization) and 301 (permanent) from 302 (temporary).
  • Choose the right status code when designing an API response.

Simple explanation

When you ask a server for something, it does not only hand back the data — it also hands back a short verdict on how the request went. That verdict is a three-digit status code. Think of it like the light on a traffic signal: green means *"all good, here it is"*, yellow means *"go somewhere else for this"*, and red means *"something went wrong"* — and the red splits into *"your mistake"* and *"my mistake"*.

You have already seen 200 OK and the dreaded 404 Not Found. There are only a few dozen you meet in daily work, and they follow a very predictable pattern.

Technical explanation

Every HTTP response begins with a status line like HTTP/1.1 200 OK. The number is grouped into five classes by its first digit:

  • 1xx Informational — the request was received and the process is continuing (e.g. 100 Continue, 101 Switching Protocols). You rarely handle these by hand.
  • 2xx Success — the request was received, understood, and accepted.
  • 3xx Redirection — further action (usually going to another URL) is needed to complete the request.
  • 4xx Client Error — the request was faulty: bad syntax, missing auth, or a resource that isn't there. The client should change something and retry.
  • 5xx Server Error — the request looked fine but the server failed to fulfill it. The client did nothing wrong.

That 4xx-vs-5xx split — *whose fault is it?* — is the single most useful thing to internalize.

The codes you actually meet

2xx Success

  • 200 OK — the standard "it worked" for GET, PUT, PATCH, and DELETE that return a body.
  • 201 Created — a new resource was created (typically after POST). A Location header points to the new resource.
  • 204 No Content — success, but there is deliberately no body to return (common for DELETE or a PUT that returns nothing).

3xx Redirection

  • 301 Moved Permanently — the resource now lives at a new URL forever. Browsers and search engines update their bookmarks/index. Use it for permanent domain or path changes.
  • 302 Found — a temporary redirect; the resource is elsewhere *for now* but the original URL still owns it. Don't let clients cache it as permanent.
  • 304 Not Modified — used with caching. The client sent a conditional request (If-None-Match / If-Modified-Since); the resource hasn't changed, so the server returns no body and the client reuses its cached copy.

4xx Client Error

  • 400 Bad Request — the request is malformed and the server can't parse it (invalid JSON, missing required field).
  • 401 Unauthorized — you are not authenticated. Despite the name, this means "I don't know who you are — log in." It usually comes with a WWW-Authenticate header.
  • 403 Forbidden — you are authenticated but not allowed. The server knows who you are and is refusing anyway. Re-logging-in will not help.
  • 404 Not Found — the resource does not exist (or the server won't admit it does).
  • 409 Conflict — the request conflicts with the current state, e.g. creating a user with an email that already exists, or a version/edit conflict.
  • 422 Unprocessable Entity — the syntax is fine but the *semantics* are invalid: the JSON parsed, but "age" was -5. Widely used by APIs for validation errors.
  • 429 Too Many Requests — rate limiting. You sent too many requests in a window; a Retry-After header often tells you how long to wait.

5xx Server Error

  • 500 Internal Server Error — a generic, unhandled failure on the server (an uncaught exception). It says nothing more specific.
  • 502 Bad Gateway — a server acting as a proxy/gateway got an invalid response from an upstream server.
  • 503 Service Unavailable — the server is temporarily overloaded or down for maintenance. Often paired with Retry-After.

Why it matters

Status codes are the contract between client and server. A frontend that treats every non-200 the same way cannot tell "please log in" (401) from "you can't touch this" (403) from "our server crashed" (500). Getting them right means correct retry logic, correct caching, correct error messages to users, and search engines that index your site properly.

How it works

The server picks a code as it builds the response and writes it into the status line. The client reads that number first and branches on it:

  1. Read the status code from the response (res.status in fetch, response.status_code in requests, etc.).
  2. Branch by class: 2xx → use the body; 3xx → follow Location (browsers do this automatically); 4xx → fix the request; 5xx → back off and maybe retry.
  3. For 4xx/5xx, read the body for a machine-readable error detail if the API provides one.

Real-world analogy

Imagine mailing a package request to a warehouse.

  • 200/201 — it arrives and they ship your item (created a new one for 201).
  • 301/302 — "we moved; send future mail to this new address" (301 forever, 302 just for now).
  • 304 — "nothing changed since last time, keep the copy you already have."
  • 401 — "we can't process this — you didn't sign the form" (prove who you are).
  • 403 — "we know it's you, but you're not on the approved list."
  • 404 — "no such item in our catalog."
  • 429 — "you're flooding us with requests; slow down."
  • 500/503 — "our warehouse caught fire / is closed for maintenance" — nothing you did.

Important terminology

  • Status class — the first digit of the code (1–5) that groups all codes by broad meaning.
  • Reason phrase — the human-readable text after the number (OK, Not Found). It is informational only; clients branch on the number, not the text.
  • Authentication vs authorization — 401 is about *who you are* (identity/login); 403 is about *what you're allowed to do* (permissions).
  • Conditional request — a request with If-None-Match/If-Modified-Since that lets the server answer 304 Not Modified and save bandwidth.

Key definitions

Status class (1xx–5xx)
The first digit groups every code: 1xx info, 2xx success, 3xx redirect, 4xx client error, 5xx server error.
401 vs 403
401 means not authenticated (who are you?); 403 means authenticated but not permitted (you may not do this).
301 vs 302
301 is a permanent redirect (clients/search engines update the URL); 302 is a temporary one (the original URL still owns the resource).
304 Not Modified
A cache response to a conditional request: the resource is unchanged, so no body is sent and the client reuses its cached copy.

Must memorize

Must memorize

  • 1xx info, 2xx success, 3xx redirect, 4xx client error, 5xx server error.
  • 4xx = you (the client) messed up; 5xx = the server messed up.
  • 401 = not authenticated (log in); 403 = authenticated but forbidden (no permission).
  • 301 = permanent move; 302 = temporary move; 304 = use your cache.

Real-world example

Creating a resource in a REST API

A POST /api/orders that succeeds returns 201 Created with a Location header pointing to /api/orders/1001. If the same order id already exists, the server returns 409 Conflict; if the payload parsed but "quantity" was 0, it returns 422 Unprocessable Entity with the field-level errors in the body.

A 429 during a traffic spike

A public API allows 100 requests per minute per key. A client that exceeds it gets 429 Too Many Requests with Retry-After: 30. A well-behaved client waits 30 seconds before retrying instead of hammering the endpoint.

Code example

response-401.http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api", error="invalid_token"
Content-Type: application/json
Content-Length: 52

{
  "error": "invalid_token",
  "message": "Token expired"
}

A raw 401 response asking the client to authenticate.

handle-status.js
const res = await fetch('https://api.example.com/orders', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer ' + token,
  },
  body: JSON.stringify({ item: 'coffee', quantity: 2 }),
});

if (res.status === 201) {
  const order = await res.json();          // created
  console.log('Created at', res.headers.get('Location'));
} else if (res.status === 401) {
  redirectToLogin();                        // not authenticated
} else if (res.status === 403) {
  showMessage('You do not have permission.'); // authenticated, no access
} else if (res.status === 422) {
  const { errors } = await res.json();      // validation failed
  showFieldErrors(errors);
} else if (res.status >= 500) {
  showMessage('Server error, please try again later.'); // not your fault
}

Branching on res.status to handle each class correctly.

Common mistakes

Mistake

Returning 200 OK for everything and putting an "error" flag in the JSON body.

Do this instead

Use the status code as the primary signal. Reserve 2xx for success and return 4xx/5xx for failures so clients, proxies, and monitoring behave correctly.

Mistake

Using 401 when the user is logged in but simply lacks permission.

Do this instead

That case is 403 Forbidden. Use 401 only when authentication is missing or invalid — i.e. the server does not yet know who the caller is.

Interview questions

Quiz

Question 1 of 30 ✓
A user is logged in but tries to open an admin-only page they are not allowed to see. Which status code fits best?
Select an answer to continue.

Flashcards

Card 1 of 3

Show answer · Space

Summary

HTTP status codes are three-digit results grouped into five classes: 1xx informational, 2xx success, 3xx redirection, 4xx client error, and 5xx server error. The key distinctions to master are 4xx (client fault) vs 5xx (server fault), 401 (not authenticated) vs 403 (not authorized), and 301 (permanent redirect) vs 302 (temporary). Picking the right code makes clients, caches, and monitoring behave correctly.

References

  • MDN — HTTP response status codes
  • RFC 9110 — HTTP Semantics (Status Codes)

Related topics

HTTP Request and ResponseHTTP MethodsREST API Fundamentals
Previous
HTTP Methods

On this page

  • Learning objectives
  • Simple explanation
  • Technical explanation
  • Why it matters
  • How it works
  • Real-world analogy
  • Important terminology
  • Key definitions
  • Must memorize
  • Real-world example
  • Code example
  • Common mistakes
  • Interview questions
  • Quiz
  • Flashcards
  • Summary