You can build an APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. where every endpointWhat is endpoint?A specific URL path on a server that handles a particular type of request, like GET /api/users. is a POST and every response is 200 OK, and it will "work." But every developer who consumes it will hate you for it, because HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. already has a perfectly good vocabulary for what you're doing. Using the right method and status codeWhat is status code?A three-digit number in an HTTP response that tells the client what happened: 200 means success, 404 means not found, 500 means the server broke. is how you communicate intent without writing documentation.
GET, read without touching
GET retrieves a resource or a collection of resources. It should never modify data on the server. This is what "safe" means: calling it leaves the world in the same state as before.
GET /api/users/123
GET /api/users
GET /api/users?role=admin&active=trueGET is also idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe., making the same request ten times returns the same result as making it once (assuming the data hasn't changed). That's what makes GET cacheable. Browsers, CDNs, and proxies can all cache GET responses automatically.
GET /api/reports/generate endpoint creates a report in the database, you've violated the safety constraint. Use POST for anything that modifies state.POST, create something new
POST creates a new resource. The server decides where to put it (the new resource's URI is returned in the Location header). POST is neither safe nor idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe., clicking submit twice creates two records.
POST /api/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}The correct response is 201 Created with a Location header pointing to the new resource:
HTTP/1.1 201 Created
Location: /api/users/124
{
"id": 124,
"name": "John Doe",
"email": "john@example.com"
}PUT, replace entirely
PUT replaces the entire resource with whatever you send. If you PUT a user object that's missing the phone field, the phone gets wiped out. You must send the complete resource.
PUT /api/users/123
Content-Type: application/json
{
"name": "John Doe",
"email": "john.doe@example.com",
"age": 30
}PUT is idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe., putting the same data twice has the same result as putting it once. Returns 200 OK with the updated resource, or 204 No Content if you don't want to send a body back.
PATCH, update partially
PATCH applies partial modifications. You only send the fields you want to change.
PATCH /api/users/123
Content-Type: application/json
{
"email": "newemail@example.com"
}This is more bandwidthWhat is bandwidth?How much data can flow through a connection at once - like the number of lanes on a highway rather than the speed limit.-efficient than PUT for large resources, but it requires the server to merge the patch carefully. PATCH is not guaranteed to be idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe., it depends on the implementation.
DELETE, remove it
DELETE removes a resource. It's idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe. in the sense that deleting a resource that no longer exists should return the same result (usually 404 or 204) rather than an error.
DELETE /api/users/123Returns 204 No Content (most common) or 200 OK with a confirmation body if you want to be verbose.
Status codes you'll actually use
Status codes are grouped by meaning. The first digit tells you the category; the restWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. give you the specifics.
2xx, it worked
| Code | Name | Use it when |
|---|---|---|
| 200 | OK | Generic success for GET, PUT, PATCH |
| 201 | Created | POST succeeded, resource created |
| 204 | No Content | Success with no body (DELETE, some PATCHes) |
4xx, the client did something wrong
| Code | Name | Use it when |
|---|---|---|
| 400 | Bad Request | Malformed JSON, invalid syntax |
| 401 | Unauthorized | Not authenticated (no token, expired token) |
| 403 | Forbidden | Authenticated but not allowed to do this |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Duplicate email, version conflict |
| 422 | Unprocessable Entity | Valid format, but validation rules failed |
| 429 | Too Many Requests | Rate limit exceeded |
5xx, the server broke
| Code | Name | Use it when |
|---|---|---|
| 500 | Internal Server Error | Unhandled exception, unknown failure |
| 502 | Bad Gateway | Upstream service returned invalid response |
| 503 | Service Unavailable | Server temporarily down or overloaded |
| 504 | Gateway Timeout | Upstream service took too long |
Method properties at a glance
| Method | Safe | Idempotent | Typical success code |
|---|---|---|---|
| GET | Yes | Yes | 200 |
| POST | No | No | 201 |
| PUT | No | Yes | 200 or 204 |
| PATCH | No | Maybe | 200 |
| DELETE | No | Yes | 204 |