"Is this just a 200 OK? No, maybe a 202 Accepted… or wait, is it actually a 201 Created? Or should it be a 204 No Content? Why does this feel like a philosophical debate instead of a status code?"
One moment, you are confidently returning a 404 Not Found, only to realize it was actually a 403 Forbidden situation. The next, you're staring at an error log, wondering if this is more of a 503 Service Unavailable or just your sanity slowly timing out.
Deciding on the HTTP status code for my backend REST API has always been a bit tricky. I have been reading through the RFC 7231 and httpstatuses.com, and I am overwhelmed by the number of status codes available. So, in this article, I would like to provide a comprehensive guide on when to use each type of status code.
HTTP status codes are essential for communication between clients and servers in web APIs. They provide quick insights into the outcome of a request, enabling engineers to diagnose issues and improve user experiences. These codes are grouped into five classes:
- 1xx (Informational): The request was received, and the process is continuing.
- 2xx (Successful): The request was successfully received, understood, and accepted.
- 3xx (Redirection): Further action is needed to complete the request.
- 4xx (Client Error): There was an error with the request.
- 5xx (Server Error): The server failed to fulfill a valid request.
1xx: Informational Responses
These codes indicate provisional responses while the request is being processed.
Code | Title | When to Use / Scenario |
---|---|---|
100 | Continue | Use this when the initial part of a request has been received and the client should continue sending the rest. |
101 | Switching Protocols | Use this when the client requests a change in protocols (e.g., from HTTP/1.1 to HTTP/2) and the server agrees. |
102 | Processing (WebDAV) | Use this when the server is still processing the request but no final response is yet available. |
103 | Early Hints | Use this with the Link header to tell the client to begin preloading resources while the server prepares the final response. |
Best Practices:
- Use 100 Continue for large payloads (e.g., file uploads) to avoid unnecessary data transfers if headers are invalid.
- Reserve 1xx codes for niche cases; most APIs don’t need them.
2xx: Successful Responses
These codes indicate the request was successfully received, understood, and processed.
Code | Title | When to Use / Scenario |
---|---|---|
200 | OK | Use this when a request has succeeded. It is the standard response for successful HTTP requests. |
201 | Created | Use this when a request has been fulfilled and has resulted in one or more new resources being created (e.g., after a successful POST request). |
202 | Accepted | Use this when a request has been accepted for processing, but the processing is not yet complete. |
203 | Non-Authoritative Information | Use this when the returned meta-information is not exactly from the origin server but from a local or third-party copy. |
204 | No Content | Use this when the server successfully processed the request but does not need to return any content (e.g., a successful DELETE request). |
205 | Reset Content | Use this when the request was successful and the client needs to reset the document view (e.g., clear a form after submission). |
206 | Partial Content | Use this when only part of the resource is delivered, often in response to a request with a Range header. |
207 | Multi-Status (WebDAV) | Use this when multiple operations need individual status reports (commonly used in WebDAV). |
208 | Already Reported (WebDAV) | Use this when the members of a DAV binding have already been enumerated in a previous response to prevent duplication. |
226 | IM Used | Use this when the server has fulfilled a request and the response is a result of instance manipulations (related to HTTP Delta encoding). |
Best Practices:
- Prefer specific codes (201, 204) over generic 200 responses.
- For 202, provide a way to check the async task’s status (e.g., a pollable endpoint).
3xx: Redirection Messages
These codes signal that the client must take additional action to complete the request.
Code | Title | When to Use / Scenario |
---|---|---|
300 | Multiple Choices | Use this when there are multiple options for the resource, and the client (or user agent) can choose one of them. |
301 | Moved Permanently | Use this when a resource has permanently moved to a new URI. All future requests should be directed to this new URI. |
302 | Found | Use this to indicate that the resource is temporarily located at a different URI. (Originally “Moved Temporarily”.) |
303 | See Other | Use this when the response to a request can be found under a different URI, and the client should use the GET method to retrieve it. |
304 | Not Modified | Use this when the requested resource has not been modified since the last request (commonly used with caching mechanisms). |
305 | Use Proxy (deprecated) | Deprecated: Use not recommended. It indicated that a proxy should be used to access the resource. |
306 | Switch Proxy | Reserved: No longer used. |
307 | Temporary Redirect | Use this when the resource is temporarily located at a different URI; the client should use the same method for future requests to the original URI. |
308 | Permanent Redirect | Use this when the resource has permanently moved, similar to 301, but the request method and body will not change when reissuing the request to the new URI. |
Best Practices:
- Use 301/308 for permanent redirects and 302/307 for temporary ones.
- Leverage 304 to reduce bandwidth via caching.
4xx: Client Error Responses
These codes indicate the client sent an invalid request.
Code | Title | When to Use / Scenario |
---|---|---|
400 | Bad Request | Use this when the server cannot process the request due to a client error (e.g., malformed request syntax). |
401 | Unauthorized | Use this when authentication is required but has failed or not been provided. (Different from 403; the client can try to authenticate.) |
402 | Payment Required | Reserved: Not typically used; originally intended for future use related to digital payment systems. |
403 | Forbidden | Use this when the client’s request is understood, but the server refuses to authorize it (even if authentication is provided). |
404 | Not Found | Use this when the requested resource could not be found on the server. |
405 | Method Not Allowed | Use this when the request method is not supported by the resource (e.g., sending a DELETE request to a read-only resource). |
406 | Not Acceptable | Use this when the requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request. |
407 | Proxy Authentication Required | Use this when the client must first authenticate with a proxy before proceeding with the request. |
408 | Request Timeout | Use this when the server times out waiting for the request from the client. |
409 | Conflict | Use this when the request could not be processed because of a conflict in the request (e.g., simultaneous updates causing an edit conflict). |
410 | Gone | Use this when the requested resource is no longer available and will not be available again. |
411 | Length Required | Use this when the server requires the request to specify the Content-Length header, but it is missing. |
412 | Precondition Failed | Use this when one of the request’s preconditions (using headers like If-Match) is not met by the server. |
413 | Payload Too Large | Use this when the request entity is larger than what the server is willing or able to process. |
414 | URI Too Long | Use this when the URI provided by the client is too long for the server to process. |
415 | Unsupported Media Type | Use this when the request entity has a media type that the server or resource does not support. |
416 | Range Not Satisfiable | Use this when the client requests a portion of the file (using the Range header), but the server cannot supply that portion. |
417 | Expectation Failed | Use this when the server cannot meet the requirements of the Expect request-header field. |
418 | I'm a teapot | Humorous / April Fools': Originally defined in RFC 2324, this is not expected to be implemented on actual HTTP servers. |
421 | Misdirected Request | Use this when the request was directed to a server that is not able to produce a response (e.g., wrong combination of scheme and authority). |
422 | Unprocessable Entity (WebDAV) | Use this when the request was well-formed but could not be followed due to semantic errors (commonly used with WebDAV). |
423 | Locked (WebDAV) | Use this when the resource being accessed is locked, preventing further operations. |
424 | Failed Dependency (WebDAV) | Use this when a request fails due to a failure in a previous request (e.g., one of the dependent operations failed). |
425 | Too Early (Experimental) | Use this experimentally when the server is unwilling to risk processing a request that might be replayed. (Not widely used in production.) |
426 | Upgrade Required | Use this when the client should switch to a different protocol (often seen when secure communication is required). |
428 | Precondition Required | Use this when the server requires the request to be conditional (usually by adding headers like If-Match). |
429 | Too Many Requests | Use this when the user has sent too many requests in a given period (“rate limiting”). |
431 | Request Header Fields Too Large | Use this when the request’s header fields are too large for the server to process. |
451 | Unavailable For Legal Reasons | Use this when the requested resource cannot be provided due to legal reasons (e.g., government censorship). |
Best Practices:
- Avoid vague 400 errors; use specific codes (404, 429) where possible.
- Return 401 for authentication failures and 403 for authorization issues.
- Provide actionable error details in the response body (e.g.,
{ "error": "Invalid API key" }
).
5xx: Server Error Responses
These codes indicate the server failed to fulfill a valid request.
Code | Title | When to Use / Scenario |
---|---|---|
500 | Internal Server Error | Use this as a generic error message when no more specific message is suitable. Indicates an unexpected condition on the server. |
501 | Not Implemented | Use this when the server does not recognize the request method or lacks the ability to fulfill the request. |
502 | Bad Gateway | Use this when a server acting as a gateway or proxy receives an invalid response from the upstream server. |
503 | Service Unavailable | Use this when the server is currently unavailable due to overload or maintenance. This is usually temporary. |
504 | Gateway Timeout | Use this when a server acting as a gateway or proxy does not receive a timely response from the upstream server. |
505 | HTTP Version Not Supported | Use this when the server does not support the HTTP protocol version used in the request. |
506 | Variant Also Negotiates | Use this in cases of transparent content negotiation that result in a circular reference. (Rarely encountered in typical applications.) |
507 | Insufficient Storage (WebDAV) | Use this when the server is unable to store the representation needed to complete the request (mainly seen in WebDAV contexts). |
508 | Loop Detected (WebDAV) | Use this when the server detects an infinite loop while processing a request (common in complex WebDAV operations). |
510 | Not Extended | Use this when further extensions to the request are required for the server to fulfill it. |
511 | Network Authentication Required | Use this when the client needs to authenticate to gain network access (commonly seen in captive portal scenarios, such as in public Wi-Fi networks). |
Best Practices:
- Avoid 5xx errors in development; they signal unhandled exceptions.
- Use 503 for planned downtime and include a
Retry-After
header. - Log 5xx errors for debugging but mask sensitive details in responses.
Conclusion
Hopefully now when I am designing my API or handling HTTP responses, I will be able to choose the status code that best fits the situation
Hope the article above gives some clarity to you too. Mastering these codes not only improves API reliability but also enhances the development experience for everyone using your API. 🚀
Top comments (2)
OMG 🤩 thanks for this article. I just started with rest api journey and I am super confuse with the status codes. Reading through this, give me some basic understanding and also confident. Saving this for future reference.
Thank you very much @mithu34, all the best on your programming journey.