Every HTTP response carries a three-digit status code. The first digit assigns it to one of five classes and tells the client, in broad terms, what happened. For an API, the status code is the most important contract: clients and monitoring evaluate it programmatically before they even look at the response body.
1xx (Informational): preliminary interim responses, processing is still ongoing. Example 100 Continue: the client may proceed with sending the request body. According to RFC 9110, 1xx responses contain no content and mostly play no role in everyday API work.
2xx (Success): the request was understood and accepted.
- 200 OK: standard success. With
GET, the resource is in the body. - 201 Created: a new resource was created, typically after a
POSTor somePUTrequests. Useful with aLocationheader pointing to the new resource. - 204 No Content: success without a body, for example after a
DELETEor an update that doesn't need to return anything. Headers can still be useful.
3xx (Redirection): further steps are needed, usually a change of URL.
- 301 Moved Permanently: the resource now permanently resides at a new URL (in the
Locationheader). Clients and caches should adopt the new URL. - 302 Found: only temporarily moved. The original URL remains authoritative for future requests.
4xx (Client error): the fault lies with the caller, for example incorrect data or missing permissions. Retrying with an identical request usually doesn't help here.
- 400 Bad Request: the request is malformed, for example invalid JSON or missing required fields.
- 401 Unauthorized: valid authentication credentials are missing. Semantically this actually means not authenticated. According to RFC 9110, the server must send a
WWW-Authenticateheader. The client can try again with valid credentials. - 403 Forbidden: the server understood the request but refuses it. The user is known but has no access rights. Logging in again doesn't help.
- 404 Not Found: resource not found. For APIs, this can also occur when the endpoint exists but the specific resource doesn't.
- 429 Too Many Requests: rate limiting, the client sent too many requests in too short a time.
5xx (Server error): the server recognizes the request as valid but cannot fulfill it.
- 500 Internal Server Error: unexpected, generic server error.
- 503 Service Unavailable: the server isn't ready, for example due to maintenance or overload. Often useful with a
Retry-Afterheader.
Security-relevant: 401 vs. 403. 401 means who are you? (authentication is missing or invalid). 403 means I know who you are, but you're not allowed to do that (authentication ok, authorization missing). Implementing this distinction cleanly matters: a 403 indirectly confirms that a resource exists, which can unintentionally leak information for sensitive endpoints. Anyone who wants to avoid this deliberately responds to forbidden access with 404 instead, to obscure its existence.
POST /api/orders HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
{ "productId": 42, "quantity": 2 }--- possible responses ---
201 Created Location: /api/orders/1001 (order created)
400 Bad Request (quantity missing or not a number)
401 Unauthorized WWW-Authenticate: Bearer (token missing/expired)
403 Forbidden (token valid, but no order permissions)
429 Too Many Requests Retry-After: 30
503 Service Unavailable Retry-After: 120A POST request and typical status codes an API might return for it.
Sources
- HTTP response status codes MDN Web Docs
- RFC 9110: HTTP Semantics RFC Editor / IETF