Handbooks / REST API Design / Chapter 1

HTTP Methods and Status Codes

7 pages · ~5 min✓ Reviewed

Start here. Next up: Resource Design.

REST API DesignPage 1

The Request-Response Mental Model

1. The Exchange

  1. Requestmethod + URL + headers + body?
  2. Responsestatus line + headers + body?
PartTells you
Methodwhat to do
URLto which resource
Status codehow it went

2. Nouns in URLs, Verbs as Methods

  • Resources are nouns: /users/42
  • Methods are the verbs: GET, POST, PUT, PATCH, DELETE
AvoidUse
GET /getUser?id=42GET /users/42
POST /deleteUserDELETE /users/42

3. Stateless and Self-Contained

  • HTTP is stateless: the server keeps no memory between requests
  • Each request is self-contained
  • Auth and context travel in headers: Authorization, Cookie
Method semantics are a contract

Clients, caches and proxies rely on them for retrying and caching. Break them (a GET that deletes data) and you get real bugs.

REST API DesignPage 2

GET, POST, PUT, PATCH and DELETE Semantics

1. The five verbs

MethodURLBodySuccess
GET/users/42none200
POST/usersnew resource201
PUT/users/42full copy200 or 204
PATCH/users/42changed fields200
DELETE/users/42none204 or 200

2. Read, create, replace

  • GET has no body semantics: parameters go in the query string
  • POST to the collection: the server picks the ID
  • Reply 201 Created with a Location header
  • PUT sends the full body to a known URL
  • Omitted fields are reset or removed
  • PUT creates the resource if missing
http
POST /users {"name":"Asha"}
201 Created
Location: /users/43

3. Patch and delete

  • PATCH changes only the sent fields
  • PATCH /users/42 {"email":"a@b.com"} keeps the name
  • DELETE returns 204 No Content (or 200 with a body)
  • Deleting again ends in the same state
PUT vs PATCH

PUT replaces the whole resource, so a missing field is lost. PATCH sends only the change.

REST API DesignPage 3

Safe and Idempotent Methods

1. Two Definitions

  • Safe = does not change server state
  • GET, HEAD, OPTIONS: crawlers and prefetchers may call them freely
  • Idempotent = N identical requests leave the same state as one

2. Who Is What

MethodSafeIdempotent
GET, HEAD, OPTIONSyesyes
PUTnoyes
DELETEnoyes
POSTnono
PATCHnonot guaranteed
  • Safe ⊂ idempotent: every safe method is idempotent
  • PUT and DELETE: idempotent, not safe
  • DELETE /users/42 twice: same end state, user gone

3. Retrying After a Timeout

  • Retrying a payment POST needs an Idempotency-Key header
bash
curl -X POST https://api.x.com/payments \
  -H 'Idempotency-Key: 7c1e-42' \
  -d '{"amount":500}'
Same key, one charge

A retry with the same key returns the first result, so no duplicate payment.

REST API DesignPage 4

Status Code Classes and the Common Codes

1. The Five Classes

ClassMeaningNext step
1xxInformationalInterim reply
2xxSuccessDone
3xxRedirectionFollow it or use cache
4xxClient errorFix the request
5xxServer errorRetry may work

2. Success and Redirects

CodeMeaning
200OK
201Created, with Location
204No Content, empty body
301Permanent redirect
302 / 307Temporary redirect; 307 keeps the method
304Not Modified, use the cache copy

3. Client Errors (4xx)

  • 400 bad input
  • 401 not authenticated
  • 403 authenticated, but forbidden
  • 404 not found
  • 409 conflict
  • 422 validation failed
  • 429 rate limited

4. Server Errors (5xx)

  • 500 unhandled server error
  • 502 bad gateway: upstream sent a bad response
  • 503 unavailable or overloaded; may send Retry-After
  • 504 gateway timeout
401 vs 403

401 = who are you? 403 = I know you, still no.

REST API DesignPage 5

Headers That Matter and Common Mistakes

1. Headers and Their Failures

HeaderJobFailure
Content-Typebody you send, e.g. application/json415
Acceptformat you want back406
Authorization: Bearer <token>credentials on every request401 + WWW-Authenticate
Locationnew or redirected resourcenone
Retry-Afterhow long to waitafter 429 / 503

2. Caching and Locking

  • Cache-Control: max-age reuses, no-store never caches
  • ETag + If-None-Match: unchanged gives 304
  • If-Match on PUT = optimistic locking; conflict gives 412
  1. Server sends ETag
  2. Client sends If-None-Match
  3. 304, no body
http
PUT /users/42
If-Match: "v7"

412 if the ETag has changed

3. Common Mistakes

  • 200 with an error body
  • GET that changes data
  • POST for everything
  • 500 for bad client input
401 vs 403

401 = not authenticated. 403 = authenticated but forbidden.

REST API DesignPage 6

HTTP Methods and Status Codes Cheat Sheet

1. Methods

MethodUseSafeIdempotentOK code
GETreadyesyes200
POSTcreate / actionnono201
PUTreplacenoyes200 / 204
PATCHpartial updatenonot guaranteed200
DELETEremovenoyes204

2. Codes and Headers

  • 4xx client: 400 bad request, 401 who are you, 403 not allowed, 404 missing
  • 409 conflict, 422 invalid, 429 slow down
  • 5xx server: 500 server bug, 502/504 upstream, 503 overloaded
  • Content-Type body sent, Accept format wanted, Authorization credentials
  • Cache-Control, ETag / If-None-Match for 304 caching
  • Location new resource, Retry-After wait after 429 / 503

3. curl

bash
curl -i https://api.x.com/users/42
curl -X POST -H 'Content-Type: application/json' \
  -d '{"name":"a"}' https://api.x.com/users

GET, then POST

401 vs 403

401 = not logged in. 403 = logged in, not allowed.

REST API DesignPage 7

Check yourself

A client times out on PUT /users/42 with a full body, then retries it. Can this create a bad state?
  • No: PUT is idempotent, so the second send leaves the same state.
  • Same retry on POST /orders could create a duplicate.
POST /payments times out and the client auto-retries. What can go wrong, and what fixes it?
  • POST is not idempotent, so the customer may be charged twice.
  • Send an Idempotency-Key header so the server ignores the repeat.
A logged-in user without admin rights calls an admin endpoint and gets 401. What is the bug?
  • 401 means not authenticated; this user is known but not allowed.
  • The correct code is 403 Forbidden