TidyURLs
Go to Tools
BLOG
The TidyURLsJournal

Practical guides, tutorials, and insights about URLs, SEO, web development, and online marketing. Learn, troubleshoot, and get the most of the web.

Back to the Journal
TidyURLs Journal

How to Choose the Right HTTP Status Code for Your API

Practical insights, clear explanations, and useful ideas for understanding the web.

October 25, 202610 min read5 topics
How to Choose the Right HTTP Status Code for Your API
Explore the details
#HTTP#REST API#API design#status codes#backend development
October 25, 202610 min read

An API response does more than deliver data: its HTTP status code tells clients whether a request succeeded, needs another step, failed because of the request, or encountered a server problem. Choosing the wrong code can make integrations harder to debug and lead clients to retry when they should correct their request—or stop when they should retry.

This guide explains common HTTP status codes for REST API responses, when to use them, and which choices are protocol semantics versus API design conventions.

Key takeaways

  • Choose a status code based on what happened to the HTTP request, not just on whether your application has a result to return.
  • Use 2xx for successful or accepted work, 3xx for redirection or cache validation, 4xx for request or client-context problems, and 5xx for server-side failures.
  • Some protocol details matter: for example, 401 requires a WWW-Authenticate challenge, and 405 requires an Allow header.
  • Many decisions—such as using 400 or 422 for validation errors—are API design conventions. Document them and apply them consistently.

Start with what happened to the request

Before selecting a code, answer three questions:

  1. Did the server fulfill the request? If so, choose a success response that accurately describes the result.
  2. Does the client need to do something different? A corrected request, authentication, or a different method may be required.
  3. Did the server fail while processing a request it could otherwise handle? If so, a server-error response may be appropriate.

The status code is part of HTTP semantics. Your API’s JSON error format, field names, and validation conventions are design choices layered on top of those semantics. For example, two APIs might both use 400 for invalid input while returning different documented error bodies.

Common 2xx success codes

A successful response does not always mean that a resource was created or that a response body is present.

CodeUse it whenPractical note
200 OKThe request succeeded and the response contains a result.Common for reads and successful updates that return a representation.
201 CreatedThe request created one or more resources.A Location header can identify the primary created resource.
202 AcceptedThe request was accepted for processing, but processing is not complete.Do not imply that the work has already succeeded. Explain how clients can check its progress when relevant.
204 No ContentThe request succeeded and there is no response content to return.Do not include a response body. Useful for deletes or updates where no representation is needed.
206 Partial ContentThe server is returning part of a representation in response to a range request.This is for HTTP range handling, not a general-purpose “partial success” code.

For example, an API that creates a task could return 201 Created with the new task representation and a Location header. An API that queues a long-running export might return 202 Accepted; the response should make clear that the export is still pending.

A common design convention is to return 200 after a successful update even if the resource did not change. Another valid approach is to use 204 when there is no response body. Pick the behavior that best communicates the result, then document it.

Common 3xx redirection and cache responses

Not every 3xx response means “send the client to a new URL.” 304 Not Modified, for example, supports conditional requests and tells a client with a cached representation that it can reuse that representation. It is not a normal response with a JSON body.

For redirects, distinguish whether the request method should be preserved:

  • 301 Moved Permanently and 302 Found describe redirects, but clients may change a POST into a GET when following them.
  • 303 See Other directs the client to retrieve another resource, typically with GET or HEAD.
  • 307 Temporary Redirect and 308 Permanent Redirect preserve the request method when followed.

These distinctions matter for APIs, especially when a request has a body or causes a change. Do not use a redirect code as a substitute for returning the result of an API operation. If your API does redirect, make sure clients can safely follow it and understand the destination.

Common 4xx client and request errors

A 4xx response indicates that the request cannot be fulfilled as received. It does not necessarily mean the user personally made a mistake: the cause might be missing credentials, a stale version, or an application rule.

CodeTypical useImportant detail
400 Bad RequestThe request is malformed or cannot be processed because of invalid request syntax or framing.Often used by APIs as a broad invalid-request response; document the exact conditions.
401 UnauthorizedValid authentication credentials are missing or not accepted.Despite its name, this is about authentication. Include a WWW-Authenticate challenge.
403 ForbiddenThe server understood the request but refuses to fulfill it.Use when authentication does not change the outcome, such as when an authenticated caller lacks permission.
404 Not FoundThe target resource was not found, or the server is not willing to disclose that it exists.A common choice for an unknown resource; it can also avoid revealing protected-resource existence.
405 Method Not AllowedThe method is known but not supported for the target resource.Include an Allow header listing the methods that are supported.
409 ConflictThe request conflicts with the current state of the target resource.Useful for state conflicts, such as attempting an operation that cannot be applied to the resource’s current state.
410 GoneThe resource is no longer available and that condition is expected to be permanent.Use only when you can make that distinction; otherwise 404 is often more suitable.
412 Precondition FailedA request condition, such as one expressed with a conditional header, was not met.Useful for preventing changes based on a stale representation.
415 Unsupported Media TypeThe request content format is not supported for this method or resource.Check the request’s Content-Type and the formats your endpoint accepts.
422 Unprocessable ContentThe content type and syntax are understood, but the instructions in the request content cannot be processed.Often used for semantic validation errors; whether an API uses 422 or 400 for validation is a design convention.
429 Too Many RequestsThe client has sent too many requests in a given period.A Retry-After header can tell clients when to try again.

A useful distinction is 401 versus 403: use 401 when authentication is absent or invalid, and 403 when the request is understood but access is refused. In practice, systems sometimes use 404 instead of 403 to avoid disclosing that a protected resource exists; document that behavior so clients are not surprised.

For a validation failure, return details that help the caller fix the request without exposing internal implementation data. For example, identify the invalid field and expected format. The status code alone rarely provides enough context.

If you are unsure what a particular code means, use the HTTP status checker as a quick reference, then confirm that the code matches the behavior of your endpoint.

Common 5xx server errors

A 5xx response indicates that the server failed to fulfill an otherwise valid request. Avoid using these codes for ordinary validation failures or permission denials.

CodeTypical use
500 Internal Server ErrorAn unexpected server condition prevented the request from completing.
501 Not ImplementedThe server does not support the functionality required to fulfill the request. It is not a general code for an endpoint that returned an error.
502 Bad GatewayA server acting as a gateway or proxy received an invalid response from an upstream server.
503 Service UnavailableThe server is temporarily unable to handle the request, such as during overload or maintenance. A Retry-After header can communicate when to retry.
504 Gateway TimeoutA gateway or proxy did not receive a timely response from an upstream server.

Clients may retry some server errors, but retrying is not always safe. A request that creates a payment or resource might have completed even if the client did not receive the response. Design retry behavior with idempotency and duplicate-request handling in mind; a status code alone cannot resolve uncertainty about whether an operation took effect.

A practical decision workflow

Use this sequence when designing an endpoint:

  1. Identify the outcome. Was the request completed, accepted for later work, redirected, or rejected?
  2. Choose the broad class. Use 2xx for success or acceptance, 3xx for applicable redirection or cache behavior, 4xx for request or client-context problems, and 5xx for server failures.
  3. Select the most specific accurate code. For example, distinguish 401 from 403, and 409 from a generic validation failure.
  4. Check required headers and body behavior. Examples include WWW-Authenticate with 401, Allow with 405, and no response content with 204.
  5. Define the error representation. Return stable, documented fields and useful messages. Do not expose stack traces, secrets, or internal infrastructure details.
  6. Document and test the contract. Ensure the API specification, implementation, and client expectations agree.

An illustrative response for a missing authentication challenge might look like this:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
Content-Type: application/json

{"error":"authentication_required"}

The JSON shape is an API design choice; the status code and authentication challenge carry the HTTP-level meaning. Adapt the challenge to the authentication scheme your service actually supports.

Common mistakes and pitfalls

  • Returning 200 for every outcome. Clients then have to inspect custom fields to learn whether the request succeeded, and generic HTTP tooling cannot interpret the result correctly.
  • Treating 401 and 403 as interchangeable. Authentication and permission refusal are distinct conditions, and 401 has a protocol requirement for a challenge.
  • Using 404 for every failure. It can be appropriate to conceal resource existence, but it obscures other cases such as invalid input or a state conflict.
  • Using 206 to mean “some items succeeded.” 206 has range-response semantics. Use a documented application-level result for partial batch outcomes instead.
  • Returning a body with 204. A no-content response must not carry response content. Choose 200 if clients need a representation.
  • Assuming every 5xx should be retried. Retrying can duplicate side effects or add load during an outage. Document safe retry behavior and use idempotency protections where appropriate.
  • Treating one validation mapping as a universal rule. Whether validation errors use 400 or 422 is often a design convention. Consistency and clear documentation matter more than adopting a code without considering its semantics.

Recommendations for a consistent API

Create a status-code policy for your API and apply it across endpoints. Specify how the API handles authentication, authorization, missing resources, validation failures, conflicts, rate limits, and unexpected server failures. Include example responses and note any intentional exceptions.

Keep status codes aligned with the actual outcome, make error responses actionable, and ensure clients can distinguish permanent request problems from temporary service problems. When changing established behavior, consider how existing clients interpret both the code and the response body.

Conclusion

The right HTTP status code describes the outcome in terms clients and HTTP infrastructure can understand. Use specific success codes when they clarify what happened, choose client-error codes that accurately identify the problem, and reserve server-error codes for failures on the service side. Where the protocol leaves room for API design conventions, be consistent, document the choice, and test the complete response—including required headers and body behavior.