Skip to content
ExplainerBackend

HTTP status codes, the eight you need

You don't need dozens of status codes. Watch one request get 200, 301, 401, 404 and 500, learn the first digit rule, and keep the eight that cover real traffic.

3 min read
HTTP status codes, the eight you need, the opening step of the interactive scene

One request, five kinds of answer

Every response starts with a three digit number. The first digit alone tells you how it went, before you read anything else.

Step 1 of 6

You have seen 404 on a page that was not there, and probably a 500 on a page that fell over. Both are status codes: the three digit number a server sends back with every response, the first line of its answer. There are dozens of them, and you need about eight. Step through the scene above to watch one request earn five different numbers.

The first digit tells you the category

Before you know a single code by name, you can read any response by its first digit.

  • 2xx, success. It worked. 200 OK for most things, 201 Created when a POST made something new.
  • 3xx, redirect. It lives somewhere else now. 301 Moved Permanently sends the client to the address in the Location header.
  • 4xx, your request. Fix what you sent and try again. 400 is malformed, 401 is "who are you?", 403 is "I know you, and no", 404 is "no such thing".
  • 5xx, the server. Nothing you change in the request will help. 500 is the handler crashing.

That split is half of debugging. A 4xx means stop blaming the server and look at your request. A 5xx means stop editing your request and look at the server logs.

The eight, and why the number has to be honest

Here is the whole set worth knowing on sight.

  • 200 OK: here you go.
  • 201 Created: done, and something new now exists.
  • 301 Moved Permanently: use this other address from now on.
  • 400 Bad Request: I could not make sense of what you sent.
  • 401 Unauthorized: I do not know who you are. Sign in.
  • 403 Forbidden: I know who you are, and no.
  • 404 Not Found: nothing lives at that address.
  • 500 Internal Server Error: I broke. Not your fault.

The number matters because clients trust it before they read anything else. This is what a front end does with your response:

const res = await fetch("/users/42");
if (res.status === 401) return goToLogin();
if (res.status === 404) return showNotFound();
if (!res.ok) return showRetry();          // any other 4xx or 5xx
render(await res.json());                 // 2xx: the body is a user

Return 200 with { "error": "user not found" } in the body and that code renders a blank profile, because it believed you. The status line is a contract: the number and the body must agree. The MDN status code reference lists every code when you need one beyond the eight; the lesson puts you in the server's seat and lets you watch a client react to the number you choose.

Common questions

What is the difference between 401 and 403?
401 means the server does not know who you are, so sign in. 403 means it knows exactly who you are and the answer is still no. Signing in again does not fix a 403.
Should I return 200 with an error in the body?
No. Clients branch on the number before they read the body, so a 200 that carries an error is a lie every client believes. Return the 4xx or 5xx that matches the failure.
When is it 400 and when is it 404?
400 is a request the server could not make sense of, such as invalid JSON or a missing field. 404 is a well formed request for something that does not exist. Malformed is 400; missing is 404.
Why 201 instead of 200 for a POST?
Both mean success, but 201 says something new now exists. Front end code often checks for 201 specifically after a create, so answering 200 can leave a success screen that never shows.