REST API Status Codes — Best Practices & When to Use Each
All 34 status codes · Search · Filter · Snippets · cURL Tester · Favorites
REST API status code best practices — which HTTP code to use for each operation. GET success: 200. POST creates: 201. DELETE: 204. Not authenticated: 401. No permission: 403. Not found: 404. Validation fail: 422. Rate limited: 429. Server error: 500. Use the tag filter "REST" to see only REST-relevant codes with code snippets.
Click any status code to see full details, code snippets, and usage guide
Frequently Asked Questions
What HTTP status codes should a REST API use for CRUD operations?
GET (read): 200 OK with resource, 404 if not found. POST (create): 201 Created with Location header and resource body. PUT/PATCH (update): 200 OK with updated resource, or 204 No Content if not returning body, 404 if not found. DELETE: 204 No Content on success, 404 if not found. For async operations, POST returns 202 Accepted with job ID.
Should a REST API return 200 or 204 for a successful DELETE?
Both are acceptable. 204 No Content is semantically correct — the resource is gone, there's nothing to return. 200 OK is acceptable if you want to return a confirmation message or the deleted resource's final state. Some APIs return 200 {"deleted": true} for frontend convenience. Pick one convention and be consistent across your API.
What status code should I return for a duplicate resource (unique constraint)?
409 Conflict is the correct code for duplicate resource violations — for example, trying to register with an email that already exists. Return a clear error body: {"error": "EMAIL_ALREADY_EXISTS", "message": "This email is already registered"}. Do not return 400 for duplicates (400 is for malformed requests, not business logic conflicts).
How should REST APIs handle authentication vs authorization errors?
Missing or invalid auth token (not logged in): 401 Unauthorized with WWW-Authenticate: Bearer header. Valid token but insufficient permissions (logged in, wrong role): 403 Forbidden. Expired token: 401 with error code TOKEN_EXPIRED so clients know to refresh. For sensitive resources, consider 404 instead of 403 to hide resource existence.
What should a REST API return for async operations?
For long-running tasks: POST /jobs → 202 Accepted with body {"jobId": "abc123", "statusUrl": "/jobs/abc123", "estimatedTime": 30}. Client polls GET /jobs/abc123 → returns {"status": "processing"} (200) until complete, then {"status": "done", "result": {...}} (200). This pattern keeps HTTP semantics correct while supporting async workflows.
Should REST APIs use 422 or 400 for validation errors?
422 Unprocessable Content is more semantically correct for business validation failures when the JSON is syntactically valid. Most modern frameworks (Rails, Laravel, FastAPI) use 422 for validation. However, many teams use 400 for all client errors including validation — both are acceptable. Pick one and document it in your API specification. Include field-level errors: {"errors": [{"field": "email", "message": "Invalid format"}]}.