201 (Created)
Status code 201 (Created) indicates the creation of (at least one) new HTTP resource. The URL of the created resource is sent in the response’s Location
header.
If POST /transfer
creates the resource /transaction/123/commit
— that is, if requests to /transaction/123/commit
might now succeed where previously you’d have 404 (Not Found) — then it is correct to respond to POST /transfer
with 201 and Location: /transaction/123/commit
.
If POST /transfer
creates several resources, then Location
must be the “primary” one (in some sense).
If POST /transaction/123/commit
does not create any new resource, then it is incorrect to respond with 201, even if it does create something else (like an internal database record).
If you can’t come up with a URL to send in Location
, that probably means you’re not creating any new resource, in which case 201 is incorrect.
Note: Location
is always relative to the request URL, not to an “API root” or any such concept you might have. For example, if POST /api/v1/foo/bar
creates /api/v1/foo/bar/baz
, correct values for Location
would include bar/baz
and /api/v1/foo/bar/baz
, but not /foo/bar/baz
.
200 (OK)
Status code 200 (OK) indicates general success. It can be used in most successful responses. It’s a kind of a safe fallback: it doesn’t say much, thus it’s guaranteed not to say much wrong and confuse the client.
If POST /transaction/123/commit
succeeds without creating a new resource, then it is correct to respond with 200.
204 (No Content)
Except for responses to GET
/HEAD
, status code 204 (No Content) is mostly the same as 200. If you use 204 to say something different than 200, you’re probably making up a local convention — same as making up your own status code 275.
Other
IANA maintains a registry of standardized status codes. You can look there for a status code that is standardized to mean exactly what you want to say.
You generally don’t want to use a non-standard status code, or to use a standard status code incorrectly, because that would preclude a uniform interface, which is kind of the whole point of REST.
If you find yourself struggling all the time to uphold a uniform interface, it’s possible that you don’t need REST at all, and should be doing RPC instead.