REST APIs in Depth · REST Foundations

Status Codes That Clients Can Act On

Choose 2xx/3xx/4xx/5xx codes precisely and consistently.

Create a free account to save this page, take notes and track your progress. Sign in

Status codes are the first thing clients, SDKs, proxies and monitoring read. Use a small, consistent set and document it. Return 201 Created with a Location header for creations, 202 Accepted for async work, 204 No Content for successful deletes/updates without a body. Distinguish 401 (not authenticated) from 403 (authenticated but forbidden), 404 (not found or hidden), 409 (state conflict), 412 (precondition failed — stale ETag), 422 (semantic validation), 429 (rate limited, with Retry-After). Reserve 5xx for server faults; 503 with Retry-After for temporary unavailability.

Status code cheat sheet

Situation Code Notes
Created a resource 201 Location: /orders/ord_1; return the representation
Accepted async job 202 Location of a status resource
Malformed JSON / bad syntax 400 Client must fix the request
Valid JSON, invalid values 422 Field-level errors in the body
Missing/invalid credentials 401 WWW-Authenticate header
Not allowed 403 (or 404 to hide existence) Be consistent per resource type
Duplicate / wrong state 409 e.g. cancel an already shipped order
Stale If-Match 412 Client reloads and retries
Too many requests 429 Retry-After + RateLimit headers
Dependency down / overload 503 Retry-After when known

Common pitfalls

  • 200 OK with {"error": ...} bodies (breaks retries, monitoring and SDKs).
  • 500 for validation errors.
  • Inventing non-standard codes.

Key points

  • Small, documented, consistent set
  • 401 vs 403 vs 404 deliberately
  • Retry-After on 429/503

Further reading: RFC 9110: Status codes

Practice questions

When would you return 404 instead of 403 for a forbidden resource?

Answer

When revealing that the resource exists is itself a leak (e.g., another tenant's invoice). Returning 404 avoids enumeration; just be consistent.

What's the difference between 409 and 422?

Answer

422: the request is well-formed but semantically invalid (bad field values). 409: the request conflicts with the current state of the resource (duplicate, invalid state transition, version conflict).

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?