RESTful APIs cheat sheet

A scannable RESTful APIs reference: 20 short snippets across 11 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
Resource modelling and methodsREST is a style built on one idea: identify things with URLs, and use HTTP's methods to act on them. A resource is alesson
Status codes, pagination and filteringA client should be able to decide what to do from the status line alone: retry, re-authenticate, or stop. Returning 200lesson
Versioning and error shapesEvery failure should look the same, so a client can handle errors generically and add special cases only where it mustlesson
Content negotiation and media typesAccept and Content-Type are how a client and a server agree on representation, and getting the failure codes rightlesson
Authentication and authorisationChoosing between API keys, OAuth 2.0 and signed tokens, and validating what you accept rather than trusting what itlesson
Caching with ETag and Cache-ControlValidators and directives let a client skip a body it already has, which is the cheapest performance work available onlesson
Idempotency, retries and rate limitingNetworks fail after the server has done the work. Idempotency keys make a retried write safe, and honest rate limitslesson
Handling uploads and binary payloadsSmall files can go through the API. Large ones should not, and pre-signed URLs move the bytes without touching yourlesson
Long-running operations, webhooks and bulk endpointsSome work cannot finish inside an HTTP request. Returning 202 with a status resource is the pattern that keeps clientslesson
Testing and contract testing REST APIsTest the failures as carefully as the happy path, and let a contract test catch the change that would break a clientlesson
REST compared with GraphQL, gRPC and tRPCPick the protocol that matches the shape of the data and the shape of the clients, and expect to run more than onelesson

Quick snippets

Resource modelling and methods

Model nouns, not actions

GET    /orders                 # the collection
POST   /orders                 # create one; server assigns the id
GET    /orders/1042            # a single order
PATCH  /orders/1042            # change part of it
DELETE /orders/1042            # remove it

GET    /orders/1042/items      # a sub-collection
PUT    /orders/1042/items/3    # replace one line item

URL design rules that age well

# an action that does not fit CRUD: model it as a resource instead of a verb
POST /orders/1042/cancellation        # creates a cancellation
{ "reason": "customer_request" }

# if the client must not create duplicates on retry, use an idempotency key
POST /payments HTTP/1.1
Idempotency-Key: 8f14e45f-ea3b-4c2d-9f10-2c3d4e5f6a7b
Content-Type: application/json

{ "amount": 2500, "currency": "USD", "order_id": "1042" }

Representations and content negotiation

GET /orders/1042 HTTP/1.1
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
ETag: "7f2c9a"
Cache-Control: private, max-age=60

{ "id": "1042", "status": "shipped", "total": { "amount": 2500, "currency": "USD" } }

Full lesson: Resource modelling and methods →

Status codes, pagination and filtering

Offset versus cursor pagination

GET /orders?status=shipped&per_page=50&page=3 HTTP/1.1

HTTP/1.1 200 OK
Link: <https://api.example.com/orders?status=shipped&per_page=50&page=4>; rel="next",
      <https://api.example.com/orders?status=shipped&per_page=50&page=9>; rel="last"
X-Total-Count: 412

{ "data": [ { "id": "1042" } ], "meta": { "page": 3, "per_page": 50, "total": 412 } }

Offset versus cursor pagination

GET /orders?status=shipped&limit=50&cursor=eyJpZCI6MTA0Mn0 HTTP/1.1

HTTP/1.1 200 OK
Link: <https://api.example.com/orders?status=shipped&limit=50&cursor=eyJpZCI6MTA5Mn0>; rel="next"

{ "data": [ { "id": "1042" } ], "next_cursor": "eyJpZCI6MTA5Mn0" }

Filtering, sorting and field selection

GET /orders?status=shipped&created_after=2026-01-01
GET /orders?status=shipped&status=refunded        # repeated = OR
GET /orders?sort=-created_at,total                # - means descending
GET /orders?fields=id,status,total                 # sparse fieldsets
GET /orders?include=customer,items                 # related resources
GET /orders?q=laptop+stand                         # free-text search

Full lesson: Status codes, pagination and filtering →

Versioning and error shapes

Strategies for change

# deprecated endpoint: tell clients before you remove anything
HTTP/1.1 200 OK
Deprecation: Sat, 01 Aug 2026 00:00:00 GMT
Sunset: Mon, 01 Feb 2027 00:00:00 GMT
Link: <https://api.example.com/v2/orders>; rel="successor-version"

Making change survivable

{
  "data": { "id": "1042", "status": "shipped" },
  "meta": { "request_id": "01J8Z4K2M9QH", "deprecated": ["status_detail"] },
  "links": { "self": "/v2/orders/1042" }
}

Full lesson: Versioning and error shapes →

Content negotiation and media types

The two headers and what they mean

GET /articles/42 HTTP/1.1
Accept: application/json, text/csv;q=0.5, */*;q=0.1

The two headers and what they mean

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Vary: Accept

{"id":42,"title":"Caching","status":"published"}

Full lesson: Content negotiation and media types →

Authentication and authorisation

Choosing a mechanism

POST /oauth/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=orders:write&client_id=svc-billing
# client_secret goes in the body or, preferably, in HTTP Basic auth

Choosing a mechanism

GET /orders HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImtfMSJ9...

Full lesson: Authentication and authorisation →

Caching with ETag and Cache-Control

Conditional requests

PUT /articles/42 HTTP/1.1
If-Match: "9f2b1c"
Content-Type: application/json

{"title":"Caching, revised"}

HTTP/1.1 412 Precondition Failed
# someone else updated the article first; reload and retry

Full lesson: Caching with ETag and Cache-Control →

Idempotency, retries and rate limiting

Idempotency keys

POST /payments HTTP/1.1
Idempotency-Key: 8f14e45f-ceea-467a-9f6f-3f2b1c9d4a77
Content-Type: application/json

{"amount":2500,"currency":"GBP","reference":"INV-1041"}

Retry strategy and rate limiting

HTTP/1.1 429 Too Many Requests
Retry-After: 30
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 30

Full lesson: Idempotency, retries and rate limiting →

Handling uploads and binary payloads

Small uploads through the API

POST /avatars HTTP/1.1
Content-Type: multipart/form-data; boundary=----X

------X
Content-Disposition: form-data; name="file"; filename="me.png"
Content-Type: image/png

...binary...
------X--

Large uploads and downloads

# Range requests let a client resume a download in pieces
from flask import Response

def send_range(path: str, start: int, end: int, total: int) -> Response:
    with open(path, "rb") as fh:
        fh.seek(start)
        chunk = fh.read(end - start + 1)
    return Response(chunk, 206, headers={
        "Content-Range": "bytes " + str(start) + "-" + str(end) + "/" + str(total),
        "Accept-Ranges": "bytes",
        "Content-Length": str(len(chunk)),
    })

Full lesson: Handling uploads and binary payloads →

Long-running operations, webhooks and bulk endpoints

202 and a status resource

POST /reports HTTP/1.1
Content-Type: application/json

{"from":"2026-01-01","to":"2026-06-30","format":"csv"}

HTTP/1.1 202 Accepted
Location: /operations/7f3c9a1e
Retry-After: 5

{"id":"7f3c9a1e","state":"pending"}

Full lesson: Long-running operations, webhooks and bulk endpoints →

Testing and contract testing REST APIs

Contract testing in practice

# The provider verifies every consumer's contracts before it can ship
pact-verifier --provider-base-url=http://localhost:8080 \
              --pact-url=./pacts/reporting-service-orders-api.json

# And a breaking-change check on the specification itself
oasdiff breaking --base main:openapi.yaml --revision HEAD:openapi.yaml

Full lesson: Testing and contract testing REST APIs →

REST compared with GraphQL, gRPC and tRPC

The honest comparison

# GraphQL solves the aggregate screen: one request, exactly the fields needed
query OrderScreen($id: ID!) {
  order(id: $id) {
    id
    status
    total { amount currency }
    customer { name }
    items(first: 5) { sku name }
  }
}
# The same screen over REST is typically four calls, or one bespoke endpoint
# that exists only to serve this one page.

Full lesson: REST compared with GraphQL, gRPC and tRPC →

FAQ

Is this RESTful APIs cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 11 lessons of the RESTful APIs course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full RESTful APIs course — it carries the worked explanations, the edge cases and the exercises behind every line here.

XML XPath XSLT SOAP RSS & Atom

Last refreshed 2026-09-27.