HTTP Status Codes Overview
Introduction
Whenever a client sends an HTTP request to a server, the server returns an HTTP response. One of the most important parts of that response is the status code. The status code is a three-digit number that tells the client what happened to the request. It tells whether the request succeeded, failed because of the client's input, failed because of authentication, failed because of server trouble, or requires another action such as redirection.
HTTP status codes are one of the first things API testers validate because they give the first technical signal about how the server handled the request. A response body may contain details, but the status code gives the top-level result. If a login fails because the password is wrong, the response should not look like a success. If a new user is created, the response should communicate creation. If a resource does not exist, the response should make that clear. Correct status codes help clients, testers, monitoring systems, gateways, and support teams understand API behavior quickly.
In real applications, status codes influence client behavior. A browser may follow redirects. A mobile app may redirect the user to login after 401 Unauthorized. A retry mechanism may retry 503 Service Unavailable but not retry 400 Bad Request. Monitoring dashboards may alert on increased 5xx errors. API automation may fail a test when the returned code does not match the expected outcome. Status codes are therefore not decorative values; they are part of the API contract.
In simple terms, an HTTP status code is a standardized three-digit number returned by a server to indicate the outcome of an HTTP request.
What Are HTTP Status Codes?
HTTP status codes are standardized numeric codes returned in the HTTP response status line. They are understood by browsers, API clients, servers, proxies, load balancers, gateways, testing tools, and monitoring systems. Because they are standardized, different technologies can communicate results consistently even when they are built using different languages and frameworks.
A typical request may look like this:
GET /users/101 HTTP/1.1
Host: api.example.com
The server may respond like this:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 101,
"name": "John"
}
The first response line is the status line:
HTTP/1.1 200 OK
In this line, HTTP/1.1 is the HTTP version, 200 is the status code, and OK is the reason phrase. The reason phrase is a readable description, but the numeric code is the most important signal for clients and tools.
Why HTTP Status Codes Are Important
Status codes give clients a standard way to understand the result of a request. Without them, a client would need to parse every response body to guess what happened. That would be unreliable because every API might use a different body format. Status codes create a shared language. A 200 means success. A 401 points to authentication. A 404 means the resource was not found. A 500 means the server hit an unexpected problem.
Status codes also help API testers design clear assertions. For example, retrieving an existing user should return 200 OK. Creating a new user should often return 201 Created. Deleting a user may return 204 No Content. Sending an invalid request body should return 400 Bad Request. Calling a protected API without a token should return 401 Unauthorized. These expectations make tests precise.
Status codes improve debugging. If a test receives 400, the tester should inspect request syntax, required fields, data types, and validation rules. If it receives 401, the tester should inspect authentication. If it receives 403, authorization is more likely. If it receives 500, server logs and backend exceptions need attention. The status code guides the investigation.
Status codes also matter for production monitoring. A sudden increase in 5xx codes may indicate a server outage. A spike in 401 may indicate token expiry, login problems, or authentication configuration issues. A rise in 429 may indicate rate limiting. Good API observability depends on meaningful status code usage.
Structure of an HTTP Status Line
The status line is the first line of the HTTP response. It contains three main parts: HTTP version, status code, and reason phrase. The structure is:
HTTP-Version Status-Code Reason-Phrase
For example:
HTTP/1.1 404 Not Found
Here, HTTP/1.1 is the version, 404 is the status code, and Not Found is the reason phrase. In modern APIs, clients usually rely on the numeric code more than the reason phrase. The response body often provides more detailed application-specific information.
For API testers, the status line is usually the first assertion. If the status code is wrong, the rest of the response may be misleading. A validation error returned as 200 OK can make clients think the operation succeeded. A missing token returned as 500 Internal Server Error can hide an authentication defect behind a generic server failure.
Categories of HTTP Status Codes
HTTP status codes are grouped into five categories based on the first digit. This grouping helps testers quickly understand the type of response even before memorizing specific codes.
| Range | Category | Meaning |
|---|---|---|
| 1xx | Informational | Request received and processing continues |
| 2xx | Success | Request processed successfully |
| 3xx | Redirection | Client must take additional action |
| 4xx | Client Error | Problem with the client's request |
| 5xx | Server Error | Problem occurred on the server |
This classification is useful in API testing. A successful scenario should usually return a 2xx code. If the client sends invalid input, a 4xx code is normally expected. If the server crashes or a dependency fails unexpectedly, a 5xx code may appear. A redirect may produce a 3xx code. Informational 1xx responses are less common in everyday REST API testing but still part of HTTP.
1xx Informational Responses
The 1xx range means the server has received the request and processing is continuing. These responses are intermediate signals rather than final business responses. Common examples include 100 Continue, 101 Switching Protocols, 102 Processing, and 103 Early Hints.
100 Continue can be used when a client wants confirmation before sending a large request body. 101 Switching Protocols is used when the server agrees to switch protocols, such as during a WebSocket upgrade. 103 Early Hints may allow clients to start loading resources before the final response is ready.
Most REST API testers do not validate 1xx responses frequently because application APIs usually return final 2xx, 3xx, 4xx, or 5xx responses. Still, knowing the category helps avoid confusion when working with lower-level HTTP behavior, streaming, protocol switching, or advanced gateway configurations.
2xx Success Responses
The 2xx range indicates that the request was received, understood, and processed successfully. These are the most common expected responses in positive API testing. However, not every success should return the same code. Choosing the right success code makes API behavior clearer.
200 OK is the most common success code. It is commonly used for successful GET requests and many successful operations that return a response body. For example, GET /users/101 may return 200 OK with user data.
201 Created is used when a new resource is successfully created. For example, POST /users may return 201 Created with the new user id. The response may also include a Location header pointing to the created resource.
202 Accepted means the request was accepted for processing, but processing may not be complete yet. This is useful for asynchronous operations such as report generation, video processing, large imports, or background jobs. A client may need to poll a status endpoint or wait for notification.
204 No Content means the request succeeded and there is no response body. This is common for delete operations or updates where the server does not return the updated resource. Testers should verify that a 204 response does not include a body.
3xx Redirection Responses
The 3xx range means the client must take additional action to complete the request. Redirection is more common in browser navigation than in pure REST APIs, but APIs can still use redirects in specific cases. A redirect may tell the client that a resource has moved, that a different URL should be used, or that cached content is still valid.
301 Moved Permanently means the resource has permanently moved to a new URL. 302 Found indicates a temporary redirect in many practical systems. 304 Not Modified tells the client that cached content can be reused. 307 Temporary Redirect and 308 Permanent Redirect preserve the original HTTP method more clearly than older redirect behavior.
For API testing, redirects should be handled deliberately. Some clients automatically follow redirects, which can hide the original status code. Testers should know whether their tool follows redirects by default. If an API endpoint should not redirect, a 3xx response may indicate routing, gateway, or trailing-slash configuration issues.
4xx Client Error Responses
The 4xx range means the request cannot be completed because of something related to the client's request. This does not always mean the end user personally made a mistake. The client application may have sent malformed JSON, missing headers, invalid parameters, expired tokens, unsupported content types, or unauthorized requests. The key idea is that the server is saying the request cannot be accepted as sent.
400 Bad Request is commonly used for malformed syntax, invalid request body, missing required fields, or general validation problems. 401 Unauthorized means authentication is missing or invalid. Despite the word "Unauthorized," it is mainly about authentication. 403 Forbidden means the client is authenticated or known, but not allowed to perform the action.
404 Not Found means the requested resource or route was not found. 405 Method Not Allowed means the endpoint exists but does not support the HTTP method used. 409 Conflict indicates a conflict with current resource state, such as duplicate records or version conflicts. 415 Unsupported Media Type means the server does not support the request content type. 422 Unprocessable Entity is often used for semantic validation errors where the syntax is valid but the content fails business validation. 429 Too Many Requests means the client exceeded rate limits.
4xx codes are extremely important in negative API testing. A strong API does not return 500 for every bad request. It returns precise 4xx responses that help clients correct the request.
5xx Server Error Responses
The 5xx range means the server failed to process a request because of a server-side problem. The request may be valid, but the server, gateway, upstream service, database, or infrastructure layer could not complete it. These errors are serious because they usually require provider-side investigation.
500 Internal Server Error indicates an unexpected server failure. It is often caused by unhandled exceptions, null values, configuration issues, or bugs. 501 Not Implemented means the server does not support the functionality required to fulfill the request. 502 Bad Gateway often appears when a gateway or proxy receives an invalid response from an upstream server. 503 Service Unavailable means the service is temporarily unavailable, overloaded, down for maintenance, or not ready. 504 Gateway Timeout means a gateway did not receive a timely response from an upstream service.
API testers should not accept 500 as a normal response for invalid user input. If the client sends bad data, the response should usually be a 4xx error. A 5xx response indicates that the server failed to handle the condition gracefully. In production, 5xx rates are often monitored closely because they indicate provider-side instability.
Visual Overview of Status Code Ranges
A simple way to remember status codes is by the first digit:
100-199 -> Information
200-299 -> Success
300-399 -> Redirection
400-499 -> Client Errors
500-599 -> Server Errors
For daily API testing, the most commonly used categories are 2xx, 4xx, and 5xx. Positive tests usually expect 2xx responses. Negative request tests usually expect 4xx responses. Server failure and dependency failure tests may expect 5xx responses. Redirection and informational responses are less common but still important in browser-facing APIs, gateways, and caching flows.
Real-World Examples
A successful login request may return 200 OK when the user authenticates successfully:
POST /login
HTTP/1.1 200 OK
A new user creation request may return 201 Created because a new resource was created:
POST /users
HTTP/1.1 201 Created
Invalid login credentials may return 401 Unauthorized because authentication failed. A request for a product id that does not exist may return 404 Not Found. A malformed JSON request may return 400 Bad Request. A duplicate account creation attempt may return 409 Conflict. A request sent too many times within a short period may return 429 Too Many Requests.
If the server crashes while processing a request, it may return 500 Internal Server Error. If an API gateway cannot reach the backend service, it may return 502 Bad Gateway or 504 Gateway Timeout. These distinctions help testers identify where the problem likely occurred.
HTTP Status Codes in API Testing
One of the first validations in API testing is verifying that the returned status code matches the expected behavior. The status code should align with the API contract, HTTP semantics, and business outcome. A passing business operation should not return an error code. A failed validation should not return a success code. Authentication and authorization failures should not be hidden as generic server errors.
| Scenario | Expected Status Code |
|---|---|
| Retrieve existing user | 200 OK |
| Create new user | 201 Created |
| Delete existing user | 204 No Content or 200 OK |
| Invalid request body | 400 Bad Request |
| Missing authentication | 401 Unauthorized |
| Access denied | 403 Forbidden |
| Resource not found | 404 Not Found |
| Unsupported HTTP method | 405 Method Not Allowed |
| Duplicate resource | 409 Conflict |
| Unsupported media type | 415 Unsupported Media Type |
| Validation errors | 422 Unprocessable Entity |
| Rate limit exceeded | 429 Too Many Requests |
| Internal server failure | 500 Internal Server Error |
These are common expectations, but the final decision should match the API specification. Some organizations use 400 for all validation errors, while others use 422 for business validation. Some delete operations return 204, while others return 200 with a confirmation body. Consistency and documentation matter.
Status Codes and Error Response Bodies
Status codes provide the high-level outcome, but error response bodies provide useful details. A good error body may include an application error code, message, field-level errors, trace id, timestamp, and documentation link. For example:
{
"errorCode": "VALIDATION_FAILED",
"message": "Request contains invalid fields",
"details": [
{
"field": "email",
"message": "Email format is invalid"
}
],
"traceId": "abc-123"
}
The status code and body should agree. A validation body should not be returned with 200 OK. A server exception body should not expose stack traces or database internals. A security error should not reveal sensitive details that help attackers. Good APIs combine accurate status codes with safe, consistent, and useful error bodies.
API testers should validate both the status code and error body. If an invalid request returns 400 but the message is blank or misleading, client applications may struggle to show useful feedback. If a response contains sensitive internal information, that is a security defect.
Status Codes and Client Behavior
Clients often make decisions based on status codes. If a mobile app receives 401 Unauthorized, it may clear the token and ask the user to log in again. If it receives 403 Forbidden, it may show an access-denied message. If it receives 404 Not Found, it may show that the resource no longer exists. If it receives 429 Too Many Requests, it may wait before retrying.
Incorrect status codes can therefore create incorrect client behavior. If an expired token returns 404, the client may show that a resource is missing instead of asking the user to authenticate. If a validation error returns 500, the client may show a server outage message instead of asking the user to correct input. If a rate limit returns 200 with an error message, automation and clients may treat the operation as successful.
For this reason, status code testing should be part of functional, negative, security, and integration testing. It directly affects user experience and system reliability.
Status Codes in Gateways and Microservices
In microservices systems, status codes may be generated by different layers. A request may fail at the API gateway before reaching the service because authentication is missing or rate limits are exceeded. A load balancer may return a gateway error if no healthy backend is available. A backend service may return a validation error. A downstream service may timeout and cause the upstream service to return a failure.
This layered architecture means testers should understand where the code came from. A 401 may be produced by the gateway. A 404 may come from routing or from the backend resource lookup. A 502 may point to gateway-to-service communication. A 504 may indicate upstream timeout. Logs, response headers, trace ids, and gateway diagnostics help isolate the source.
API tests should exercise the real consumer path when validating public behavior. Direct service tests are useful, but they do not prove gateway behavior. Gateway status codes should be documented and consistent so clients can handle failures predictably.
How to Choose the Right Status Code
Choosing the right status code starts with identifying the outcome. If the request succeeded, use a 2xx response that matches the operation. If a resource was retrieved, 200 OK is usually correct. If a resource was created, 201 Created is clearer. If the request was accepted for background processing, 202 Accepted communicates that the final result is not ready yet. If the operation succeeded but there is no body to return, 204 No Content is usually suitable.
If the request failed because of the client's input or context, use a 4xx response. Bad syntax, malformed JSON, missing fields, invalid data types, and unsupported input usually belong in the client-error range. Authentication and authorization should be separated. Missing or invalid credentials usually point to 401 Unauthorized, while valid identity with insufficient permission usually points to 403 Forbidden. A missing resource usually points to 404 Not Found, while a duplicate or conflicting state may point to 409 Conflict.
If the request was valid but the server could not process it because of an internal failure, use a 5xx response. These codes should be treated seriously because they indicate provider-side trouble. A well-designed API should not use 500 Internal Server Error for predictable validation failures. It should reserve 5xx responses for unexpected exceptions, unavailable dependencies, gateway failures, overload, or timeouts.
The status code should also match the response body. If the body says payment failed, the status code should not blindly say 200 OK unless the API contract clearly defines that the HTTP request succeeded while the business payment result failed. Even in those designs, the distinction must be documented carefully because clients and testers may otherwise misunderstand the outcome.
Automating Status Code Assertions
Status code validation should be automated for important APIs. A test should send a request and assert the exact expected code, not only that the response is not empty. For a positive user lookup, the test may expect 200. For user creation, it may expect 201. For deletion, it may expect 204. For invalid input, it may expect 400 or 422 depending on the documented standard.
Automation should also test negative scenarios intentionally. A missing token test should assert 401. A user without permission should assert 403. A nonexistent resource should assert 404. An unsupported method should assert 405. A duplicate create request should assert 409 if that is the agreed design. These tests protect API behavior from accidental changes.
When APIs are behind gateways, tests should capture enough details to debug failures. The response status code, response body, headers, correlation id, request id, and endpoint should appear in the test report. If a test receives 502 or 504, the team needs to know whether the request reached the backend service or failed at the gateway. Good reporting reduces investigation time.
Status code assertions should be strict but not blind. If the API specification allows more than one valid response for a case, the test should reflect that contract. For example, some delete endpoints may return 200 with a body, while others return 204 without a body. The point is not to force one universal answer for every API. The point is to make the expected behavior explicit and consistent.
Status Codes and API Documentation
Every API endpoint should document its possible status codes. Consumers should know what success looks like, what validation failure looks like, what authentication failure looks like, what authorization failure looks like, and what happens when resources are missing or conflicts occur. Without this information, clients must guess how to handle errors.
Documentation should include examples. A create endpoint should show a successful request and 201 Created response. It should also show common error responses such as missing required field, duplicate value, unsupported content type, and unauthorized access. These examples help developers, testers, and support teams align on expected behavior.
API documentation and implementation must stay synchronized. If documentation says invalid data returns 400 but the API returns 500, either the implementation has a defect or the documentation is wrong. Both are quality problems. Automated tests can help enforce the documented contract.
For versioned APIs, status codes should be documented per version. Version one and version two may handle some cases differently during migration. Testers should verify the correct behavior for each supported version rather than assuming one version's status-code rules apply everywhere.
Best Practices
Return the correct status code for every scenario. Do not return 200 OK for all responses just because the server technically returned a body. The code should reflect the actual outcome. Success, validation failure, authentication failure, authorization failure, missing resource, conflict, rate limit, and server failure are different situations and should not all look the same.
Use standard HTTP status codes instead of inventing custom numeric codes. Application-specific error codes can be included in the response body, but the HTTP status code itself should remain standard. This allows browsers, clients, gateways, monitoring tools, and test frameworks to interpret responses correctly.
Keep status code usage consistent across APIs. If one service returns 401 for missing token and another returns 400, clients and testers become confused. Organization-level API standards help maintain consistency.
Include meaningful error messages for error responses. A status code tells the category of failure, but the response body should explain the specific issue safely. Messages should be clear enough for legitimate clients and testers, while avoiding sensitive internal details.
Document status codes for every endpoint. API consumers should know which success and error codes are possible. Testers should use that documentation to build precise positive and negative assertions.
Common Mistakes
A common mistake is returning 200 OK for every request, even when the operation failed. For example, if login fails but the API returns 200 OK with an error message, clients may treat the login as successful unless they inspect the body carefully. Authentication failure should usually return 401 Unauthorized.
Another mistake is returning 500 Internal Server Error for invalid client input. If the request body is malformed or required fields are missing, the server should return a client error such as 400 Bad Request. A 500 suggests that the server failed unexpectedly rather than rejecting bad input correctly.
Returning 404 Not Found for authentication failures is also misleading in many APIs. If the problem is missing or invalid authentication, 401 is clearer. Some security-sensitive systems intentionally hide resource existence, but that should be a deliberate documented choice, not accidental inconsistency.
Another common issue is inconsistent status code usage across endpoints. One endpoint may return 409 Conflict for duplicates, while another returns 400 Bad Request. Some inconsistency may be justified, but unexplained variation makes clients and tests harder to maintain.
API Testing Checklist for Status Codes
Start with positive scenarios. Verify that read operations return 200 OK, create operations return 201 Created where appropriate, asynchronous operations return 202 Accepted when processing continues in the background, and no-content operations return 204 No Content.
Then test request validation. Send malformed JSON, missing required fields, invalid data types, unsupported enum values, invalid query parameters, and boundary values. Verify that the API returns documented 4xx codes instead of uncontrolled 5xx errors.
Test authentication and authorization separately. Missing or invalid credentials should return authentication-related responses such as 401. Valid credentials with insufficient permissions should return authorization-related responses such as 403.
Test resource and method behavior. Missing resources should return documented not-found behavior. Unsupported methods should return 405 Method Not Allowed where supported by the API design. Unsupported content types should return 415 Unsupported Media Type.
Test operational errors where possible. Simulate dependency failure, timeout, unavailable backend, or rate limit behavior in controlled environments. Verify 429, 502, 503, or 504 responses according to the system design.
Interview-Ready Explanation
HTTP status codes are standardized three-digit numeric codes returned by a server to indicate the result of an HTTP request. They help clients understand whether a request was successful, requires additional action, failed because of a client-side issue, or failed because of a server-side problem.
Status codes are grouped into five categories. 1xx codes are informational. 2xx codes indicate success. 3xx codes indicate redirection. 4xx codes indicate client errors. 5xx codes indicate server errors. Common examples include 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, and 500 Internal Server Error.
In API testing, validating the correct HTTP status code is one of the most important checks because it confirms whether the API behaved as expected at a high level. Testers should verify that successful operations return appropriate 2xx codes, invalid requests return correct 4xx codes, and server failures return controlled 5xx responses. Status codes should be consistent with the response body and API documentation.
Key Takeaway
HTTP status codes are the standard result signals of HTTP and API communication. They tell clients and testers what happened to a request before the response body is interpreted. Correct status codes improve client behavior, debugging, monitoring, automation reliability, and API quality.
For API testers, status codes provide a practical validation map. Test success scenarios, invalid requests, authentication failures, authorization failures, missing resources, conflicts, unsupported methods, rate limits, and server errors. Verify that the returned code matches the business outcome and the API contract.
The simplest summary is this: status codes are not just numbers. They are part of the API contract, and a well-designed API uses them accurately and consistently.