HTTP 2xx success status codes
The 2xx class signals that the client’s request was received, understood, and accepted. Choosing the most specific success code makes your API self-documenting: a 201 tells a client a resource was created, a 204 tells it there is nothing to render, and a 206 tells it the body is only a slice of the whole. Returning a flat 200 everywhere throws this information away. Search the reference above for any code or keyword to see its meaning, expected body, and idempotency notes.
The codes you will actually use
| Code | Name | Body? | Key header | Typical use case |
|---|---|---|---|---|
| 200 | OK | Yes | — | Generic success; GET, PATCH with response body |
| 201 | Created | Optional | Location | Resource created via POST or PUT |
| 202 | Accepted | Yes (status URL) | — | Async processing queued |
| 204 | No Content | No | — | DELETE, PUT update with no echoed body |
| 205 | Reset Content | No | — | Tell the client to clear its form/view |
| 206 | Partial Content | Partial | Content-Range | Resumable download, media seeking |
| 207 | Multi-Status | Yes (XML/JSON) | — | WebDAV batch operations |
| 208 | Already Reported | Yes | — | WebDAV DAV binding already listed |
| 226 | IM Used | Yes | IM, Delta-Base | HTTP delta encoding (rare) |
How it works
A status code is the first machine-readable token of an HTTP response (HTTP/1.1 201 Created). The 2xx range is defined mainly by RFC 9110 with WebDAV additions in RFC 4918 and RFC 5842. The most important distinctions are: whether a body is allowed (204 and 205 forbid one), whether a Location header is expected (201), and whether the response is conditional or partial (206 answers a Range request). Idempotency is a property of the method, not the status code: GET and HEAD are always safe, PUT and DELETE are idempotent, while POST generally is not.
Design decisions in REST APIs
Why not always 200? A client that only ever sees 200 must read the body to know whether a resource was created, updated, or already existed. Status codes are a machine-readable signal at the transport layer — use them so clients can branch without parsing JSON.
201 vs 200 for creation: After a successful POST /users, return 201 Created with Location: /users/42. The client can redirect the user or refetch the resource at the given URL without guessing it. If you return 200, the client has to inspect the body to learn the new resource’s URL.
202 for async work: When a request triggers a background job (for example, sending an email or running a data export), return 202 Accepted immediately with a URL the client can poll: {"jobUrl": "/jobs/abc"}. Never hold the HTTP connection open for work that takes more than a second or two.
204 for updates with no body: If a PUT or PATCH succeeds and you have nothing useful to return, 204 No Content is cleaner than 200 OK with an empty body. It also prevents clients from accidentally parsing empty strings as JSON.
Tips and examples
- Return
201 CreatedwithLocation: /orders/42after creating a resource so clients can fetch it without guessing the URL. - Use
204 No ContentforDELETEand forPUTupdates where echoing the body adds no value — but never put bytes in the body. - For large downloads, support
Rangerequests and answer with206 Partial Contentplus aContent-Rangeheader so interrupted transfers can resume. 202 Acceptedis your friend for queue-backed work; return a job URL and let clients poll rather than holding the connection open.