HTTP Status Code Reference

Which HTTP Status Code Should I Use? A Decision Guide

An interactive decision guide for choosing the right HTTP status code for your API. Covers success, redirect, client error, and server error responses with real-world examples.

100% client-side. Your data never leaves your browser.

1xx Informational

(4)

2xx Success

(10)

3xx Redirection

(7)

4xx Client Error

(29)

5xx Server Error

(11)
61 of 61 status codes

Related Tools

The Decision Tree

Start here and follow the path that matches your situation.

Did the request succeed?

Yes, and I’m returning data → 200 OK The default success response. Use for GET requests that return data, POST requests that perform actions, and PUT/PATCH requests that update and return the result.

Yes, and I created a new resource → 201 Created Use after POST or PUT creates something new. Include a Location header with the URL of the new resource.

Yes, but there’s no body to return → 204 No Content Use for successful DELETE requests, or PUT/PATCH when the client doesn’t need the updated resource back. The response has no body.

Yes, but I already did this → 200 OK or 204 No Content For idempotent operations (PUT, DELETE) where the end state is the same regardless of how many times you call it, return the same success code you’d return on the first call.

Accepted, but not finished yet → 202 Accepted Use when the server queued the request for async processing. The client should poll or receive a callback later. Good for long running jobs, batch operations, or webhook deliveries.


Does the client need to go somewhere else?

Permanently moved → 301 Moved Permanently The resource has a new URL forever. Browsers and search engines update their records. Safe for GET requests. Note: some older clients change POST to GET on redirect.

Permanently moved, keep method → 308 Permanent Redirect Like 301, but guarantees the HTTP method is preserved. A POST stays a POST. Use when method preservation matters (API redirects).

Temporarily moved → 302 Found The resource is temporarily at a different URL. Browsers cache this for the session but check back. Most common temporary redirect in practice.

Temporarily moved, keep method → 307 Temporary Redirect Like 302, but preserves the HTTP method. Use for temporary API redirects where a POST must stay a POST.

See other → 303 See Other Use after a POST to redirect the client to a GET endpoint. Common pattern: POST /orders returns 303 with Location: /orders/123, then the client GETs the new order.


Is the problem on the client’s side?

Malformed request → 400 Bad Request The request syntax is wrong. Invalid JSON, missing Content-Type, undecodable body. The client needs to fix the request before retrying.

Not authenticated → 401 Unauthorized No credentials provided, or the credentials are expired/invalid. The client should authenticate (login, refresh token) and retry.

Authenticated but not allowed → 403 Forbidden The server knows who the client is but they don’t have permission. Reauthenticating won’t help. Check roles/permissions.

Resource doesn’t exist → 404 Not Found The URL doesn’t match any resource. Also commonly used to hide the existence of resources the client isn’t allowed to know about (instead of 403).

Wrong HTTP method → 405 Method Not Allowed The endpoint exists but doesn’t support this method. Example: trying to DELETE on a read only endpoint. Include an Allow header listing valid methods.

Conflict with current state → 409 Conflict The request conflicts with the resource’s current state. Common uses: duplicate creation attempts, optimistic locking failures (version mismatch), state machine violations (trying to publish an already published post).

Resource was deleted → 410 Gone Like 404, but the server knows this resource used to exist and was intentionally removed. Stronger signal than 404 for search engines and caching.

Validation error → 422 Unprocessable Entity The syntax is valid (it’s proper JSON) but the content is wrong. Missing required fields, wrong data types, values out of range. Use this for business logic validation failures.

Too many requests → 429 Too Many Requests Rate limiting. Include a Retry-After header telling the client when to try again.


Is the problem on the server’s side?

Unexpected server error → 500 Internal Server Error Something broke. Unhandled exception, null pointer, configuration error. The catch-all for “this is our fault.” Log the error, don’t expose internals to the client.

Not implemented → 501 Not Implemented The server doesn’t support this functionality. Use for endpoints that are defined but not built yet, or for HTTP methods the server doesn’t recognize.

Upstream service failed → 502 Bad Gateway The server is acting as a proxy/gateway and received an invalid response from the upstream service. Common with load balancers and reverse proxies when a backend crashes.

Service overloaded or in maintenance → 503 Service Unavailable The server can’t handle the request right now. Could be overloaded, in maintenance, or starting up. Include a Retry-After header if you know when it’ll be back.

Upstream timeout → 504 Gateway Timeout The server is acting as a proxy and the upstream didn’t respond in time. Different from 408 (client timeout): 504 means the server’s own upstream timed out.


Quick Reference Table

Success (2xx)

CodeNameWhen to use
200OKDefault success, returning data
201CreatedNew resource created (include Location header)
202AcceptedAsync processing started
204No ContentSuccess, no body (DELETE, fire and forget PUT)

Redirection (3xx)

CodeNamePreserves method?Permanent?
301Moved PermanentlyNo (may switch to GET)Yes
302FoundNo (may switch to GET)No
303See OtherAlways switches to GETN/A
307Temporary RedirectYesNo
308Permanent RedirectYesYes

Client Error (4xx)

CodeNameWhen to use
400Bad RequestMalformed syntax
401UnauthorizedMissing or invalid credentials
403ForbiddenAuthenticated but lacks permission
404Not FoundResource doesn’t exist
405Method Not AllowedWrong HTTP method
409ConflictState conflict (duplicates, version mismatch)
410GoneResource permanently removed
422Unprocessable EntityValid syntax, invalid data
429Too Many RequestsRate limited

Server Error (5xx)

CodeNameWhen to use
500Internal Server ErrorUnhandled server failure
502Bad GatewayUpstream returned invalid response
503Service UnavailableOverloaded or in maintenance
504Gateway TimeoutUpstream didn’t respond in time

Common API Patterns

REST CRUD operations

OperationMethodSuccess codeError codes
List resourcesGET200401, 403
Get one resourceGET200401, 403, 404
Create resourcePOST201400, 401, 403, 409, 422
Full updatePUT200 or 204400, 401, 403, 404, 422
Partial updatePATCH200 or 204400, 401, 403, 404, 422
Delete resourceDELETE204401, 403, 404

Headers you should include

Status codeRecommended header
201Location: /resource/id
301, 302, 307, 308Location: https://new-url
405Allow: GET, POST
429Retry-After: 60
503Retry-After: 300