Skip to main content
Back to Blog

HTTP Status Codes: Complete Developer Guide 2025

What 2xx, 4xx, and 5xx mean, when to return which code from your API, and how to fix the most common errors.

Kashyap Thakar
10 min
HTTPAPIWeb DevelopmentDebugging
HTTP Status Codes: Complete Developer Guide 2025

HTTP status codes are the language servers use to communicate with clients. Understanding these codes is fundamental to web development, API design, and debugging. A 404 Not Found tells you the resource doesn't exist, while a 500 Internal Server Error indicates a server-side problem. But what about 429 Too Many Requests or 503 Service Unavailable? Let's decode the complete HTTP status code system.

Understanding Status Code Categories

HTTP status codes are organized into five categories, each identified by the first digit:

  • 1xx (Informational): Request received, continuing process
  • 2xx (Success): Request successfully received, understood, 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

2xx Success Codes

These codes indicate that the request was successfully received, understood, and accepted:

200 OK

The standard success response. The request succeeded, and the response body contains the requested data. This is the most common success code for GET, PUT, and PATCH requests.

GET /api/users/123
HTTP/1.1 200 OK
Content-Type: application/json

{"id": 123, "name": "John Doe"}

201 Created

The request succeeded and a new resource was created. Typically used for POST requests that create new resources. The response should include a Location header pointing to the newly created resource.

POST /api/users
HTTP/1.1 201 Created
Location: /api/users/456
Content-Type: application/json

{"id": 456, "name": "Jane Smith"}

204 No Content

The server successfully processed the request but is not returning any content. Commonly used for DELETE requests or PUT/PATCH requests where the response body isn't needed. The response body should be empty.

202 Accepted

The request has been accepted for processing, but processing has not been completed. Used for asynchronous operations where the result will be available later. The response should include information about where to check the status.

3xx Redirection Codes

These codes indicate that further action is needed to complete the request, typically involving a redirect to another location:

301 Moved Permanently

The requested resource has been permanently moved to a new URL. Browsers and search engines should update their links. The new URL should be provided in the Location header.

GET /old-page
HTTP/1.1 301 Moved Permanently
Location: /new-page

302 Found (Temporary Redirect)

The requested resource temporarily resides under a different URL. Unlike 301, this redirect is temporary, and the original URL should still be used for future requests. Commonly used for URL shorteners or temporary maintenance pages.

304 Not Modified

The client's cached version is still valid. Used for conditional GET requests with If-Modified-Since or If-None-Match headers. This saves bandwidth by not sending the resource again.

4xx Client Error Codes

These codes indicate that the client made an error in the request. The client should not retry the request without modification:

400 Bad Request

The server cannot process the request due to a client error (malformed syntax, invalid request message framing, or deceptive request routing). This is a catch-all for client errors that don't fit other 4xx codes.

POST /api/users
HTTP/1.1 400 Bad Request
Content-Type: application/json

{"error": "Invalid email format"}

401 Unauthorized

The request requires authentication. The client must authenticate itself to get the requested response. This is different from 403, which means the client is authenticated but not authorized.

GET /api/protected
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"

403 Forbidden

The client does not have access rights to the content. Unlike 401, the client is authenticated, but it doesn't have permission to access the resource. This is an authorization issue, not an authentication issue.

404 Not Found

The server cannot find the requested resource. This is the most common error code. It means the URL doesn't exist or the resource has been deleted. In REST APIs, this often means the ID doesn't exist in the database.

405 Method Not Allowed

The request method is not allowed for the requested resource. For example, trying to POST to a resource that only accepts GET. The response should include an Allow header listing allowed methods.

409 Conflict

The request conflicts with the current state of the server. Commonly used when trying to create a resource that already exists (e.g., duplicate email) or when a concurrent modification conflict occurs.

422 Unprocessable Entity

The request was well-formed but contains semantic errors. Often used for validation errors where the syntax is correct but the data doesn't meet business rules. This is more specific than 400.

429 Too Many Requests

The user has sent too many requests in a given time ("rate limiting"). The response should include headers indicating when the client can retry, such as Retry-After.

GET /api/data
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0

5xx Server Error Codes

These codes indicate that the server failed to fulfill a valid request. The client can retry the request:

500 Internal Server Error

A generic error message when the server encounters an unexpected condition that prevents it from fulfilling the request. This is a catch-all for server errors. In production, you should never expose detailed error information to clients.

502 Bad Gateway

The server, while acting as a gateway or proxy, received an invalid response from an upstream server. Common when a reverse proxy (like nginx) can't reach the application server.

503 Service Unavailable

The server is temporarily unable to handle the request due to maintenance or overload. The response should include a Retry-After header indicating when the service might be available again.

504 Gateway Timeout

The server, while acting as a gateway or proxy, did not receive a timely response from an upstream server. This indicates the upstream server is too slow or unresponsive.

Best Practices for Using Status Codes

Be Consistent

Use the same status codes for the same situations throughout your API. If 404 means "resource not found" in one endpoint, it should mean the same in all endpoints.

Provide Meaningful Error Messages

While status codes tell you what went wrong, error messages tell you why. Always include helpful error messages in the response body:


{
  "error": "Validation failed",
  "message": "Email address is required",
  "field": "email",
  "code": "VALIDATION_ERROR"
}
                    

Use Appropriate Codes

Don't use 200 OK for errors. If something went wrong, use the appropriate 4xx or 5xx code. Don't use 404 for authentication failures—use 401 or 403.

Include Helpful Headers

Use headers to provide additional context:

  • Location for redirects and created resources
  • Retry-After for rate limiting and service unavailable
  • Allow for 405 Method Not Allowed
  • WWW-Authenticate for 401 Unauthorized

Common Mistakes to Avoid

Using 200 for Errors

Never return 200 OK with an error in the body. This breaks HTTP semantics and makes it impossible for clients to distinguish between success and failure without parsing the response body.

Confusing 401 and 403

401 Unauthorized means "you need to authenticate." 403 Forbidden means "you're authenticated, but you don't have permission." Use them correctly.

Overusing 500

Don't use 500 for client errors. If the client sends invalid data, use 400 or 422. Reserve 500 for actual server failures.

Debugging with Status Codes

When debugging API issues, status codes are your first clue:

  • 4xx errors: Check the request—wrong URL, missing headers, invalid data
  • 5xx errors: Check the server—database issues, code bugs, resource exhaustion
  • 429 errors: Implement rate limiting or reduce request frequency
  • 502/504 errors: Check upstream services, network issues, or timeouts

Conclusion

HTTP status codes are a fundamental part of web development. Understanding them helps you build better APIs, debug issues faster, and communicate more effectively with other developers. Use them correctly, provide meaningful error messages, and be consistent across your application.

For testing and debugging HTTP requests, check out our API Tester tool, which helps you inspect status codes, headers, and response bodies in real-time.

Part of the ThenCatch blog. Learn more about us or browse more guides.