Every time your browser loads a page, an API call returns data, or a server rejects a request, an HTTP status code tells the story. These three-digit numbers are the language of the web — they tell clients whether a request succeeded, failed, was redirected, or needs more information. Understanding them is fundamental to building reliable web applications and debugging issues effectively.
This guide covers every HTTP status code category, the most important codes you will encounter in practice, how to use them correctly in REST APIs, and common mistakes developers make.
Understanding the Status Code System
HTTP status codes are grouped into five classes based on their first digit:
| Class | Range | Meaning |
| 1xx | 100–199 | Informational — request received, continuing process |
| 2xx | 200–299 | Success — request received, understood, and accepted |
| 3xx | 300–399 | Redirection — further action needed to complete request |
| 4xx | 400–499 | Client Error — request contains bad syntax or cannot be fulfilled |
| 5xx | 500–599 | Server Error — server failed to fulfill a valid request |
1xx — Informational
Rarely seen by end users. These codes indicate that the server has received the request and is continuing to process it.
| Code | Name | Description |
| 100 | Continue | Client should continue sending the request body. Used with Expect: 100-continue header. |
| 101 | Switching Protocols | Server agrees to switch protocols as requested (e.g., HTTP to WebSocket). |
| 103 | Early Hints | Returns some headers before the final response, allowing the browser to preload resources. |
2xx — Success
The request was successfully received, understood, and processed. This is the happy path.
| Code | Name | Description |
| 200 | OK | Standard success response for GET requests. The response body contains the requested data. |
| 201 | Created | Resource successfully created (POST). Include a Location header with the URL of the new resource. |
| 204 | No Content | Request succeeded but there is no body to return (DELETE, PUT when no response needed). |
| 206 | Partial Content | Returned when the client requests a range of the resource (e.g., resuming a download or video streaming). |
| 304 | Not Modified | Resource has not changed since the If-Modified-Since or ETag provided by the client. Browser uses cache. |
REST API best practice: Return 201 Created for resource creation (POST), 200 OK for successful reads and updates (GET, PUT, PATCH), and 204 No Content for successful deletions (DELETE) where no response body is needed.
3xx — Redirection
The client needs to take additional action to complete the request, typically by following a different URL.
| Code | Name | Description |
| 301 | Moved Permanently | Resource has permanently moved. Browsers cache this and search engines update their index. Use for URL changes, domain migrations, and HTTP→HTTPS redirects. |
| 302 | Found | Temporary redirect. Browsers will continue to request the original URL on future visits. Use for maintenance pages, A/B testing, and short-term redirects. |
| 304 | Not Modified | Cached version is still valid. Saves bandwidth by avoiding re-transmission of unchanged resources. |
| 307 | Temporary Redirect | Like 302 but ensures the method and body are not changed on the redirect (POST stays POST). |
| 308 | Permanent Redirect | Like 301 but preserves the HTTP method on redirect. |
SEO tip: Use 301 for permanent redirects to preserve search engine rankings. Avoid 302 for permanent changes — Google may not transfer link equity with a temporary redirect.
4xx — Client Error
The request contains an error or lacks sufficient permissions. The client should not retry without modifying the request.
| Code | Name | Description |
| 400 | Bad Request | The server cannot process the request due to malformed syntax, invalid JSON, or missing required parameters. |
| 401 | Unauthorized | Authentication is required and has failed or has not been provided. Response should include a WWW-Authenticate header. |
| 403 | Forbidden | The client is authenticated but does not have permission to access the resource. The server understood the request but refuses to authorize it. |
| 404 | Not Found | The requested resource does not exist on the server. Also commonly used to hide resources the client is not allowed to know about. |
| 405 | Method Not Allowed | The HTTP method (GET, POST, PUT, DELETE) is not supported for this resource. The Allow header lists valid methods. |
| 408 | Request Timeout | The server timed out waiting for the client to send the complete request. |
| 409 | Conflict | The request conflicts with the current state of the resource (e.g., trying to create a user with an email that already exists). |
| 410 | Gone | The resource is no longer available and has been permanently removed. Unlike 404, this indicates the resource existed before. |
| 413 | Payload Too Large | The request body exceeds the server's configured size limit. |
| 415 | Unsupported Media Type | The server does not support the media type of the request body (e.g., sending XML when the API expects JSON). |
| 422 | Unprocessable Entity | The request syntax is correct but the data fails validation (e.g., valid JSON but invalid email format). Commonly used in REST APIs. |
| 429 | Too Many Requests | Rate limit exceeded. The Retry-After header tells the client when to try again. |
5xx — Server Error
The server encountered an error while processing a valid request. These indicate problems on the server side.
| Code | Name | Description |
| 500 | Internal Server Error | Generic server error. Something went wrong on the server side — unhandled exception, configuration error, or bug. |
| 502 | Bad Gateway | The server (acting as a gateway or proxy) received an invalid response from an upstream server. |
| 503 | Service Unavailable | The server is temporarily unavailable, typically due to maintenance or overload. Include a Retry-After header. |
| 504 | Gateway Timeout | The upstream server did not respond in time. Common when a reverse proxy (Nginx) times out waiting for the application server. |
Debugging tip: If you see a 5xx error, check your server logs first. 500 errors usually have stack traces. 502/504 errors suggest infrastructure issues — check upstream service health, network connectivity, and timeout configurations.
How to Check HTTP Status Codes
You can check HTTP status codes using several methods:
Browser Developer Tools
Open DevTools (F12) → Network tab → Reload the page. Every request shows its status code in the "Status" column. Click any request to see full headers and response details.
cURL
# Get just the status code
curl -s -o /dev/null -w "%{http_code}" https://example.com
# Get headers + status code
curl -I https://example.com
# Follow redirects and show final status
curl -sL -o /dev/null -w "%{http_code}" https://example.com
Online HTTP Checker
Risetop's HTTP Status Code Checker lets you enter any URL and instantly see the status code, response headers, and redirect chain. No command line needed — just paste a URL and click Check.
REST API Status Code Best Practices
- Be specific: Use the most accurate code possible. 201 for creation, 204 for deletion, 409 for conflicts, 422 for validation errors. Avoid returning 200 for everything.
- Include useful error bodies: When returning 4xx codes, include a JSON body with an error message, a machine-readable error code, and optionally a link to documentation.
- Use 404 for non-existent resources: When a user requests
/api/users/999 and user 999 does not exist, return 404 — not 200 with a null body.
- Respect HTTP methods: Return 405 if someone sends a POST to an endpoint that only accepts GET.
- Rate limit with 429: Always return 429 (not 503) when a client exceeds rate limits. Include a
Retry-After header.
- Use 401 vs 403 correctly: 401 = not authenticated, 403 = authenticated but not authorized.
Common Mistakes
- Returning 200 for errors — This breaks API contracts and makes error handling harder for clients.
- Using 404 for authentication failures — Use 401 or 403 instead. 404 means "resource not found."
- Not setting Location header on 201 — Clients need to know where the new resource lives.
- Using 500 for client errors — If the client sent bad data, return 400/422, not 500.
- Using 302 instead of 301 for permanent moves — This hurts SEO because search engines won't transfer link equity.
Frequently Asked Questions
What is the difference between 401 Unauthorized and 403 Forbidden?
401 Unauthorized means the client has not authenticated — the server does not know who is making the request. 403 Forbidden means the client is authenticated but does not have permission to access the requested resource. Think of it as 401 = "Who are you?" and 403 = "I know who you are, but you can't do that."
When should I use 400 vs 422 in a REST API?
Use 400 Bad Request for malformed syntax or invalid request format (e.g., missing required fields, invalid JSON). Use 422 Unprocessable Entity when the request syntax is correct but the semantics are wrong (e.g., valid JSON but the email field contains a phone number). 422 says "I understood your format, but the data doesn't make sense."
What HTTP status code should I return for a successful POST request?
Use 201 Created when the POST creates a new resource. Include a Location header pointing to the new resource's URL. If the POST doesn't result in creation (e.g., it triggers a process), use 200 OK or 204 No Content.
What is a 429 Too Many Requests error?
429 is returned when a client has sent too many requests in a given time period. The response should include a Retry-After header telling the client how long to wait before trying again. This is part of rate limiting to protect APIs from abuse and ensure fair usage.
What is the difference between 301 and 302 redirects?
301 Moved Permanently tells the browser and search engines that the resource has permanently moved to a new URL — browsers cache this and will go directly to the new URL on future visits. 302 Found is a temporary redirect — browsers will continue requesting the original URL. For SEO, use 301 for permanent URL changes and 302 for temporary ones.
Related Tools
Check Any URL's Status Code
Instantly see HTTP status codes, headers, and redirect chains — no command line needed.
Check Status Code →