developmentwebAPIs

HTTP Status Codes Explained: Every Code You'll Actually Encounter

200, 301, 404, 500 — most developers know these four. But what about 429, 307, 422, or 503? Here's a practical guide to every status code you'll encounter in the real world.

·7 min read

How Status Codes Are Structured

HTTP status codes are three-digit numbers grouped into five classes based on 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

The Codes You Need to Know

2xx Success

**200 OK** — The standard success response. For GET requests, the response body contains the requested resource. For POST, it contains the result.

**201 Created** — A resource was successfully created. Returned after a successful POST to a creation endpoint. Should include a Location header pointing to the new resource.

**204 No Content** — The request succeeded but there's nothing to return. Common for DELETE requests and PUT requests that update without returning the result.

**206 Partial Content** — Used for range requests (streaming video, resumable downloads). The Content-Range header specifies which chunk is being returned.

3xx Redirection

**301 Moved Permanently** — The resource has permanently moved. Browsers and search engines cache this and update bookmarks. Use for permanent URL changes.

**302 Found** — Temporary redirect. Browsers follow it but don't cache. The original URL is still "valid". Use sparingly — it's often misused where 301 is more appropriate.

**303 See Other** — After a POST request, redirect to a GET request. The standard way to implement the Post/Redirect/Get pattern to prevent form resubmission.

**304 Not Modified** — The client has a cached copy and the content hasn't changed. The server sends this instead of re-transmitting the full response.

**307 Temporary Redirect** — Like 302, but explicitly guarantees the redirect uses the same HTTP method. A POST to a 307 redirects as POST, not GET.

**308 Permanent Redirect** — Like 301, but method-preserving. Use when permanently moving a POST endpoint.

4xx Client Errors

**400 Bad Request** — The request is malformed. Syntax error in the body, invalid JSON, missing required field. The client should not retry without fixing the request.

**401 Unauthorized** — Authentication required (confusingly named — this means "unauthenticated"). The client should send credentials.

**403 Forbidden** — Authenticated but not authorised. The server understood the request but refuses to authorise it. Don't reveal whether the resource exists.

**404 Not Found** — The resource doesn't exist at this URL. Can also be used to hide a 403 — returning 404 for unauthorised access prevents enumeration attacks.

**405 Method Not Allowed** — The HTTP method isn't supported. GET on a POST-only endpoint.

**409 Conflict** — The request conflicts with the current state. Creating a user with a duplicate email, trying to check in a file that's already checked out.

**410 Gone** — Like 404, but the resource used to exist and has been permanently removed. Tells crawlers to remove it from their index.

**422 Unprocessable Entity** — The syntax is valid but the semantics are wrong. The JSON parsed correctly, but the values fail validation. More specific than 400.

**429 Too Many Requests** — Rate limit exceeded. The response should include Retry-After header indicating when the client can retry.

5xx Server Errors

**500 Internal Server Error** — A generic server failure. An unhandled exception, a crashed process, a misconfigured server. Check server logs.

**502 Bad Gateway** — The server (acting as a proxy or gateway) received an invalid response from an upstream server. Common when your app server is down but your reverse proxy (Nginx, Cloudflare) is up.

**503 Service Unavailable** — The server is temporarily unable to handle the request. Maintenance mode, overload, or a deployment in progress. Include Retry-After if you know when it'll be back.

**504 Gateway Timeout** — The upstream server took too long to respond. Your load balancer or CDN couldn't reach your app server in time.

Practical Checklist

  • Never return 200 with an error in the body ("200 OK" + {"error": "not found"} is an anti-pattern)
  • Use 4xx for client mistakes, 5xx for server mistakes
  • 404 is safe for both "not found" and "forbidden" — prevents resource enumeration
  • Include meaningful error details in 4xx responses (what went wrong, what the client should do)
  • 503 during deployments is better than letting requests hang or fail with 502

Try These Free Tools

More Articles