When designing or integrating APIs, HTTP status codes are your primary communication channel. They aren't just arbitrary numbers; they form a standardized contract between the client and the server. Using them correctly is the difference between a clean, self-documenting REST API and a chaotic, unpredictable integration nightmare.
In this guide, we will dissect all the major HTTP status codes, group them by their class, discuss when to use them in production systems, and highlight senior-level design tips.
The Big Picture: Status Code Classes
HTTP status codes are three-digit integers divided into 5 distinct classes based on the first digit:
1xx— Informational: Request received, continuing process.2xx— Success: The action was successfully received, understood, and accepted.3xx— Redirection: Further action must be taken to complete the request.4xx— Client Error: The request contains bad syntax or cannot be fulfilled.5xx— Server Error: The server failed to fulfill an apparently valid request.
Let's dive deep into each category.
1xx — Informational Codes
Informational codes are low-level protocol handshake helpers. They are rarely handled directly by web application code, but are critical for web servers and protocols.
100 Continue
The server has received the request headers and the client should proceed to send the request body (e.g., in a large POST request).
- Production Tip: Useful when uploading large files. The client sends the
Expect: 100-continueheader. If the server approves the headers (e.g., file type is valid, user is authorized), it returns100 Continue, saving bandwidth if the request would have been rejected anyway.
101 Switching Protocols
The requester has asked the server to switch protocols and the server has agreed to do so.
- Real-World Example: Initiating a WebSocket connection. The client sends an HTTP request with
Upgrade: websocket, and the server responds with101 Switching Protocolsbefore upgrading the TCP socket.
102 Processing
An interim response used to inform the client that the server has accepted the complete request, but has not yet completed it.
- Usage: Used in WebDAV environments or long-running queries to prevent the client from timing out.
2xx — Success Codes
These codes tell the client that the operation was successful. Selecting the right success code makes your API highly expressive.
200 OK
The standard response for successful HTTP requests.
- Usage: Returning a resource on
GET, or performing a successful update onPUT/PATCHwhere the updated resource is returned.
201 Created
The request has been fulfilled and has resulted in one or more new resources being created.
- Usage: Successful
POSTrequests. - Best Practice: The response should ideally include a
Locationheader containing the URL of the newly created resource, and the response body should contain the created resource payload.codeHTTP/1.1 201 Created Location: /api/v1/users/42 Content-Type: application/json { "id": 42, "username": "dhavalkurkutiya", "createdAt": "2026-06-01T04:30:00Z" }
202 Accepted
The request has been accepted for processing, but the processing has not been completed.
- Usage: Asynchronous or background tasks (e.g., generating a heavy PDF report, processing a video upload).
- Best Practice: Return a polling URL or a task ID in the payload so the client can check the progress of the job.
204 No Content
The server successfully processed the request, but is not returning any content.
- Usage: Successful
DELETErequests, orPOST/PUTrequests where the UI does not need to refresh any local state. - Constraint: The response must not contain a body.
206 Partial Content
The server is delivering only part of the resource due to a range header sent by the client.
- Usage: Multi-part downloads, video/audio streaming players, or resuming paused downloads. The client requests a range (e.g.,
Range: bytes=0-1023) and the server replies with206 Partial Content.
3xx — Redirection Codes
Redirections tell the client to look elsewhere for the resource.
The Crucial Redirection Nuance: 301/302 vs 307/308
There is a critical architectural distinction between these two groups of redirection codes:
- 301 / 302: Originally designed to redirect. However, many browsers historically changed the HTTP method from
POSTtoGETfor the redirected request (ignoring the original request body). - 307 / 308: Strictly enforce that the HTTP method and request body cannot be changed during redirection.
Request: POST /api/v1/old-endpoint (with body)
↓
HTTP 301 Redirect to /api/v1/new-endpoint
↓
Browser / Client: GET /api/v1/new-endpoint (Body is LOST!)
---------------------------------------------------------
Request: POST /api/v1/old-endpoint (with body)
↓
HTTP 308 Redirect to /api/v1/new-endpoint
↓
Browser / Client: POST /api/v1/new-endpoint (Body is PRESERVED!)301 Moved Permanently
The target resource has been assigned a new permanent URI. Any future references to this resource should use the returned URI.
- Usage: Domain migrations, or restructuring URL paths (e.g., changing
/old-blogto/blog).
302 Found (Temporary Redirect)
The target resource resides temporarily under a different URI.
- Usage: Short-term campaign redirects, geo-targeting based routing.
304 Not Modified
Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.
- Usage: Browser and CDN caching.
- Benefit: The server does not send a response body, saving massive amounts of outbound bandwidth and network latency.
307 Temporary Redirect
The target resource resides temporarily under a different URI, preserving the HTTP method.
308 Permanent Redirect
The target resource has been permanently moved to a new URI, preserving the HTTP method.
4xx — Client Error Codes
Client errors indicate that there is something wrong with the client's request. Expressive 4xx error handling is a hallmark of premium APIs.
400 Bad Request
The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large).
- Usage: When the client sends invalid JSON syntax. Do not use this for semantic validation errors (use
422instead).
401 Unauthorized vs 403 Forbidden
One of the most common points of confusion in web security:
- 401 Unauthorized: "I don't know who you are." The client has not provided authentication credentials, or the credentials are invalid.
- 403 Forbidden: "I know who you are, but you do not have permission to do this." The client is authenticated but does not possess the required scopes or role (e.g., a regular user trying to access the admin dashboard).
404 Not Found
The requested resource could not be found but may be available in the future.
- Security Tip: If a resource is restricted, you may want to return
404 Not Foundinstead of403 Forbiddento hide its existence from unauthorized scanners.
405 Method Not Allowed
A request method is not supported for the requested resource (e.g., sending a POST request to a read-only endpoint /api/v1/configs).
- Requirement: The response must include an
Allowheader listing the supported methods (e.g.,Allow: GET, HEAD).
408 Request Timeout
The server timed out waiting for the request.
- Usage: When the client takes too long to upload its headers or body.
409 Conflict
The request could not be completed due to a conflict with the current state of the target resource.
- Usage: When a user tries to sign up with an email address that is already registered, or when a git-like concurrent update fails optimistic locking check.
410 Gone
Indicates that the resource is no longer available and will not be available again.
- Usage: Used when deleting historical API versions, or deactivated user accounts where you explicitly want to tell search crawlers to stop indexing.
413 Payload Too Large
The request entity is larger than limits defined by server.
- Usage: File uploads that exceed max file size limits.
414 URI Too Long
The URI requested by the client is longer than the server is willing to interpret.
- Usage: Overly long query strings, sometimes caused by infinite client redirect loops.
415 Unsupported Media Type
The request entity has a media type which the server or resource does not support.
- Usage: The client sends a
POSTrequest with XML payload (Content-Type: application/xml) but the server only supports JSON (Content-Type: application/json).
422 Unprocessable Entity
The request was well-formed but was unable to be followed due to semantic errors.
- Usage: Form validation errors, missing fields, invalid ranges (e.g., password too short).
- Best Practice: Return a structured JSON detailing each validation failure.
429 Too Many Requests
The user has sent too many requests in a given amount of time ("rate limiting").
- Best Practice: Include a
Retry-Afterheader telling the client how many seconds they must wait before making another request.
5xx — Server Error Codes
Server errors represent a failure inside your backend or infrastructure. Your API should catch these gracefully and never expose raw database stack traces to the client.
500 Internal Server Error
A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
- Production Tip: Log the exact stack trace internally with a unique Correlation ID, but return only the Correlation ID to the client. Never leak internal details.
501 Not Implemented
The server either does not recognize the request method, or it lacks the ability to fulfill the request.
- Usage: Stubbing endpoints before their actual implementation is deployed.
502 Bad Gateway
The server, while acting as a gateway or proxy, received an invalid response from the inbound server it accessed while attempting to fulfill the request.
- Usage: Nginx or Cloudflare cannot communicate with your Node.js/Go backend app process.
503 Service Unavailable
The server cannot handle the request (because it is overloaded or down for maintenance). Generally, this is a temporary state.
- Best Practice: Include a
Retry-Afterheader to advise the client when the service will be back up.
504 Gateway Timeout
The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server.
- Usage: The API Gateway timed out waiting for the database query or microservice to finish processing.
505 HTTP Version Not Supported
The server does not support the HTTP protocol version used in the request.
🛠️ The Production Essentials: Most Used Codes in Modern APIs
While HTTP lists dozens of codes, modern API design centers around a core set of 11 status codes. Mastering these guarantees an intuitive, standardized developer experience.
| Code | Status Text | Typical API Scenario |
|---|---|---|
200 | OK | Standard successful GET, PUT, PATCH. |
201 | Created | Successful record creation (POST). |
204 | No Content | Successful deletion (DELETE), no body returned. |
400 | Bad Request | Syntax error, malformed JSON. |
401 | Unauthorized | Authentication missing or failed. |
403 | Forbidden | Authenticated, but lacks permissions (role conflict). |
404 | Not Found | Resource or route does not exist. |
422 | Unprocessable Entity | Validation errors (e.g., invalid email address). |
429 | Too Many Requests | Rate-limiting active. |
500 | Internal Server Error | Unhandled backend exception / database failure. |
503 | Service Unavailable | Backend server is crashing or in maintenance mode. |
Designing a Premium API Error Response (RFC 7807)
For client errors (4xx) and server errors (5xx), do not just return raw status codes or flat strings like {"error": "something went wrong"}. Use the standard RFC 7807 (Problem Details for HTTP APIs) layout.
Here is what a production-ready validation error looks like:
{
"type": "https://api.dhavalkurkutiya.dev/errors/validation-error",
"title": "Unprocessable Entity",
"status": 422,
"detail": "The email address provided is already registered.",
"instance": "/api/v1/auth/register",
"invalidParams": [
{
"name": "email",
"reason": "Email address must be unique."
}
],
"correlationId": "err_req_9f3c7028fa"
}By sticking to this unified standard, you build web systems that are predictable, resilient, and incredibly easy for other developers to integrate with!