HTTP/1.1 200 OKUse `200 OK` for successful reads and updates when you are returning a representation.
Practical HTTP status codes, error response bodies, validation failures, and troubleshooting-friendly API error contracts.
Return the narrowest success code that matches the outcome.
HTTP/1.1 200 OKUse `200 OK` for successful reads and updates when you are returning a representation.
HTTP/1.1 201 Created
Location: /users/usr_123`201 Created` is ideal when a new resource has been created and you can identify its URL.
HTTP/1.1 202 AcceptedUse this when the work has started or been queued but is not finished yet.
HTTP/1.1 204 No ContentCommon for deletes and some updates where the client does not need a representation back.
HTTP/1.1 304 Not ModifiedUseful with ETag or Last-Modified validators for efficient client caching.
Distinguish invalid input, missing auth, conflicts, and server failures.
HTTP/1.1 400 Bad RequestUse 400 when the request cannot be understood or parsed as sent.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer401 means the client needs valid authentication. It is not the same as lacking permission.
HTTP/1.1 403 ForbiddenReturn 403 when the identity is known but access is denied.
HTTP/1.1 404 Not FoundUse 404 when the targeted resource cannot be found or should not be disclosed.
HTTP/1.1 409 ConflictCommon for uniqueness violations, version conflicts, and invalid state transitions.
HTTP/1.1 412 Precondition FailedA strong fit when using conditional requests such as `If-Match` with ETags.
Well-formed request but semantic validation failed.
HTTP/1.1 422 Unprocessable ContentUse 422 when the JSON shape is valid but business validation rules are not satisfied.
HTTP/1.1 429 Too Many Requests
Retry-After: 60Useful for API abuse protection and fair usage enforcement.
HTTP/1.1 500 Internal Server ErrorReserve 500 for unhandled errors or unknown failures; do not use it for predictable validation problems.
Return structured error details clients can act on.
{
"error": {
"code": "EMAIL_ALREADY_EXISTS",
"message": "An account with that email already exists.",
"details": {
"field": "email"
},
"request_id": "req_01HXYZ..."
}
}Machine-readable codes plus a human-readable message help both client UX and support troubleshooting.
{
"error": {
"code": "VALIDATION_FAILED",
"message": "One or more fields are invalid.",
"fields": [
{ "name": "email", "code": "INVALID_FORMAT" },
{ "name": "password", "code": "TOO_SHORT" }
]
}
}Returning all field failures reduces trial-and-error for API consumers and form builders.