Understanding HTTP Status Codes
6 min read
Every time your application makes an API request, the server responds with a three-digit number. This number—the HTTP status code—tells you exactly what happened. Did the request succeed? Did something go wrong? Is the resource somewhere else?
Understanding these codes is fundamental to building reliable applications. Yet many developers only know a handful: 200 means success, 404 means not found, 500 means something broke. There's much more to the story.
The Five Classes of Status Codes
HTTP status codes are grouped into five classes, each identified by the first digit:
- 1xx (Informational) - Request received, continuing process
- 2xx (Success) - Request successfully received and accepted
- 3xx (Redirection) - Further action needed to complete the request
- 4xx (Client Error) - Request contains bad syntax or cannot be fulfilled
- 5xx (Server Error) - Server failed to fulfill a valid request
Let's explore the most important codes in each category.
2xx Success Codes
These are the codes you want to see. They mean your request worked.
200 OK - The standard success response. The request succeeded, and the response body contains the requested data. This is what you'll see most often for successful GET requests.
201 Created - The request succeeded and a new resource was created. Typically returned after successful POST requests. The response usually includes the created resource or its location.
204 No Content - The request succeeded, but there's nothing to return. Common for successful DELETE requests or updates where you don't need confirmation data.
202 Accepted - The request was accepted for processing, but processing isn't complete. Used for asynchronous operations where the server queues the work for later.
3xx Redirection Codes
These codes tell the client to look elsewhere for the requested resource.
301 Moved Permanently - The resource has permanently moved to a new URL. Clients should update their bookmarks and use the new URL for future requests. Search engines transfer SEO value to the new URL.
302 Found - The resource temporarily resides at a different URL. Unlike 301, clients should continue using the original URL for future requests.
304 Not Modified - Used with caching. The client's cached version is still valid, so the server doesn't send the resource again. This saves bandwidth and improves performance.
307 Temporary Redirect - Similar to 302, but guarantees the request method won't change. If you POST to a URL that returns 307, you'll POST to the new location too.
4xx Client Error Codes
These codes indicate the client did something wrong. The request was malformed, unauthorized, or asked for something that doesn't exist.
400 Bad Request - The server couldn't understand the request due to invalid syntax. Maybe the JSON was malformed, a required field was missing, or a value had the wrong type.
401 Unauthorized - Authentication is required but wasn't provided or failed. Despite the name, this is about authentication (who you are), not authorization (what you can do).
403 Forbidden - The server understood the request but refuses to authorize it. Unlike 401, authenticating won't help. You simply don't have permission.
404 Not Found - The requested resource doesn't exist. Either the URL is wrong, or the resource was deleted. This is probably the most famous HTTP status code.
405 Method Not Allowed - The HTTP method isn't supported for this resource. You tried to DELETE something that only accepts GET, for example.
409 Conflict - The request conflicts with the current state of the server. Common when trying to create a resource that already exists or update a resource that was modified by someone else.
422 Unprocessable Entity - The request was well-formed but contains semantic errors. The JSON syntax is valid, but the data doesn't make sense (like a negative age or invalid email format).
429 Too Many Requests - You've hit the rate limit. Slow down and try again later. The response often includes a Retry-After header telling you how long to wait.
5xx Server Error Codes
These codes mean the server failed. The request was valid, but something went wrong on the server side.
500 Internal Server Error - The generic "something broke" error. The server encountered an unexpected condition. This usually indicates a bug in the server code.
502 Bad Gateway - The server, acting as a gateway or proxy, received an invalid response from an upstream server. Often seen when a backend service is down.
503 Service Unavailable - The server is temporarily unable to handle the request. Usually due to maintenance or overload. Should be temporary.
504 Gateway Timeout - The server, acting as a gateway, didn't receive a timely response from the upstream server. The backend is too slow or unresponsive.
Why Status Codes Matter for Your Application
Proper status code handling makes your application robust and user-friendly.
Different errors need different responses. A 401 should prompt a login. A 429 should trigger a retry with backoff. A 500 should show an error message and maybe alert your monitoring system. Treating all errors the same leads to poor user experience.
Retry logic depends on the code. You should retry 503 (temporary) but not 400 (your fault). You should retry 429 after waiting, but not 401 without re-authenticating.
Debugging is faster. When you know what each code means, you can quickly identify whether a problem is in your code (4xx) or the server (5xx).
Testing Status Code Handling
Here's the challenge: how do you test that your application handles a 503 correctly? You can't just ask a production API to fail for you.
This is where mock servers become essential. With Mocklantis, you can configure any endpoint to return any status code you need:
Test error handling. Create endpoints that return 400, 401, 403, or 422 to verify your validation error displays work correctly.
Test retry logic. Configure an endpoint to return 503 or 429 and verify your application waits and retries appropriately.
Test edge cases. What happens when your app receives a 418 (I'm a teapot) or any other unusual code? Mock it and find out.
Combine with error injection. Set up an endpoint to succeed 80% of the time and return random 5xx errors 20% of the time. This simulates real-world API reliability.
Understanding status codes is the first step. Testing your handling of every code is what separates robust applications from fragile ones.
Quick Reference
| Code | Name | Meaning |
|---|---|---|
| 200 | OK | Success |
| 201 | Created | Resource created |
| 204 | No Content | Success, nothing to return |
| 301 | Moved Permanently | Use new URL forever |
| 400 | Bad Request | Invalid syntax |
| 401 | Unauthorized | Authentication needed |
| 403 | Forbidden | No permission |
| 404 | Not Found | Resource doesn't exist |
| 429 | Too Many Requests | Rate limited |
| 500 | Internal Server Error | Server broke |
| 502 | Bad Gateway | Upstream server error |
| 503 | Service Unavailable | Temporarily down |
Memorize these, and you'll understand 95% of the API responses you encounter.