HTTP cheat sheet

A scannable HTTP reference: 28 short snippets across 13 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
HTTP methodsIdempotent means repeating it has the same effect as doing it once — sending the same DELETE twice should leave thingslesson
HTTP status codesThe class is the part a client should branch on. Only the first digit is semantic; the other two are a label. That islesson
HTTP headersContent negotiation, auth, compression and security headers — the metadata that controls real behaviourlesson
Caching and conditional requestsOnce a response goes stale, the client asks 'has this changed?' rather than downloading it again. Confirmation costs alesson
CORS explainedYour browser attaches cookies and tokens to requests automatically. Without protection, any site you visited could readlesson
HTTPS and TLSNote what it does not do: HTTPS does not make a site trustworthy, and it encrypts only the transport — the server stilllesson
Message anatomy and framingEvery HTTP exchange is two messages with the same skeleton: a start line, header fields, one empty line, and anlesson
Cookies, sessions and stateHTTP is stateless: each request stands alone. Cookies are the mechanism that lets a server recognise the same clientlesson
Authentication on the wireThe WWW-Authenticate header is what turns a 401 into a usable protocol: it names the scheme and its parameters, so alesson
Compression, content negotiation and media typesAccept and Accept-Encoding with quality values, gzip, Brotli and zstd, charset handling, multipart uploads, andlesson
Proxies, load balancers and connection managementOnce a request passes through anything — CDN, load balancer, service mesh, corporate proxy — the connection the serverlesson
HTTP API design in practiceApplying method semantics, pagination strategies, ETags in APIs, problem-detail error bodies, versioning, webhooks andlesson
Debugging HTTP: tools, logs and observabilitycurl and API clients, browser network panel analysis, HAR capture, server access logs, tracing and correlation headerslesson

Quick snippets

HTTP methods

PUT vs PATCH vs POST

PUT /users/42
{ "name": "Ada", "email": "[email protected]", "role": "admin" }
// replaces the whole record - omitted fields may be cleared

PATCH /users/42
{ "role": "admin" }
// modifies only the fields provided

POST /users
{ "name": "Ada" }
// creates something new; server assigns the id

Full lesson: HTTP methods →

HTTP status codes

The five classes

HTTP/1.1 404 Not Found
Content-Type: application/problem+json
Cache-Control: no-store

{
  "type": "https://example.com/errors/not-found",
  "title": "No such article",
  "status": 404,
  "detail": "Article 8f2c was deleted on 2026-08-01."
}

Full lesson: HTTP status codes →

HTTP headers

Security headers worth setting

Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=()
X-Frame-Options: DENY   (or CSP frame-ancestors)

Full lesson: HTTP headers →

Caching and conditional requests

Controlling freshness

Cache-Control: max-age=3600, public
Cache-Control: no-store          # never keep it (sensitive data)
Cache-Control: no-cache          # store, but revalidate every time
Cache-Control: private, max-age=600
Cache-Control: immutable, max-age=31536000  # fingerprinted assets

Conditional requests

# first response
HTTP/1.1 200 OK
ETag: "a1b2c3"
Cache-Control: max-age=0, must-revalidate

# later request
GET /api/profile HTTP/1.1
If-None-Match: "a1b2c3"

# unchanged response - no body transmitted
HTTP/1.1 304 Not Modified

Full lesson: Caching and conditional requests →

CORS explained

Simple requests vs preflight

OPTIONS /api/item HTTP/1.1
Origin: https://app.example
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: authorization

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example
Access-Control-Allow-Methods: GET, POST, DELETE
Access-Control-Allow-Headers: authorization
Access-Control-Max-Age: 600

Fixing it in practice

// Express: allow one trusted app
app.use(cors({
  origin: 'https://app.example',
  credentials: true
}));

// fetch side: include cookies when needed
fetch(url, { credentials: 'include' });

Full lesson: CORS explained →

HTTPS and TLS

Certificate chains

openssl s_client -connect example.com:443 -servername example.com

echo | openssl s_client -connect example.com:443 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer

Renewal without drama

# Let's Encrypt with Certbot
certbot certonly --webroot -w /var/www/app -d example.com -d www.example.com
certbot renew --dry-run

# certificates typically last 90 days; automate renewal
systemctl list-timers | grep certbot

Mixed content

<!-- do not hardcode the scheme -->
<script src='//cdn.example/lib.js'></script>

<!-- better: same-origin, scheme-relative as fallback -->
<script src='/vendor/lib.js'></script>

Full lesson: HTTPS and TLS →

Message anatomy and framing

The shape of a message

POST /api/orders?dry=1 HTTP/1.1
Host: api.example.com
Content-Type: application/json; charset=utf-8
Content-Length: 27
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.abc

{"sku":"A-1","qty":2}

The shape of a message

HTTP/1.1 201 Created
Location: /api/orders/1042
Content-Type: application/json; charset=utf-8
Content-Length: 62

{"id":1042,"sku":"A-1","qty":2,"status":"pending"}

HTTP/1.1, HTTP/2 and HTTP/3 on the wire

curl -sS -v --http2 https://example.com/ -o /dev/null 2>&1 | grep -iE 'ALPN|using HTTP'
curl -sSI --http3 https://cloudflare.com/ | head -n 1   # needs a curl built with HTTP/3

Full lesson: Message anatomy and framing →

Cookies, sessions and state

Set-Cookie and its attributes

HTTP/1.1 200 OK
Set-Cookie: sid=8f3c1a...; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=604800
Set-Cookie: theme=dark; Path=/; Max-Age=31536000; SameSite=Lax

Session identifiers

GET /dashboard HTTP/1.1
Host: app.example.com
Cookie: sid=8f3c1a...; theme=dark
If-None-Match: "v7"

Full lesson: Cookies, sessions and state →

Authentication on the wire

Challenge and response

GET /admin HTTP/1.1
Host: app.example.com

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="admin", charset="UTF-8"

GET /admin HTTP/1.1
Host: app.example.com
Authorization: Basic YWRhOnMzY3JldA==

Bearer tokens, JWTs and API keys

Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImtmMSJ9.eyJzdWIiOiJ1c2VyLTQyIiwiYXVkIjoiYXBpLmV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9sb2dpbi5leGFtcGxlLmNvbSIsImV4cCI6MTc3MDAwMDAwMCwic2NvcGUiOiJvcmRlcnM6cmVhZCJ9.signature

OAuth 2.1, scopes and mutual TLS

GET /authorize?response_type=code&client_id=app123&
    redirect_uri=https://app.example/cb&scope=orders:read%20orders:write&
    state=x8f2...&code_challenge=E9Melhoa...&code_challenge_method=S256 HTTP/1.1

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlO&code_verifier=dBjftJeZ...

Full lesson: Authentication on the wire →

Compression, content negotiation and media types

Negotiating the representation

GET /report HTTP/1.1
Host: api.example.com
Accept: text/html, application/json;q=0.9, */*;q=0.1
Accept-Language: en-GB, en;q=0.8, fr;q=0.5
Accept-Charset: utf-8

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

Compression in practice

GET /app.js HTTP/1.1
Accept-Encoding: br, gzip, zstd;q=0.9, identity;q=0.1

HTTP/1.1 200 OK
Content-Type: application/javascript; charset=utf-8
Content-Encoding: br
Vary: Accept-Encoding
Content-Length: 41230

Compression in practice

# pre-compress static assets at build time, then serve by name
brotli -q 11 -k app.js        # produces app.js.br
gzip -9 -k app.js             # produces app.js.gz

# verify what a server actually sent
curl -sS -o /dev/null -H 'Accept-Encoding: br,gzip' -w '%{size_download} %{content_type}\n' https://example.com/app.js
curl -sSI -H 'Accept-Encoding: br,gzip' https://example.com/app.js | grep -iE 'content-encoding|vary'

Full lesson: Compression, content negotiation and media types →

Proxies, load balancers and connection management

What an intermediary changes

GET /api/me HTTP/1.1
Host: app.example.com
Forwarded: for=203.0.113.7;proto=https;host=app.example.com
X-Forwarded-For: 203.0.113.7, 10.0.0.5
X-Forwarded-Proto: https
X-Forwarded-Host: app.example.com
X-Request-Id: 01J8Y7Q2ZK3M4N5P6R7S8T9V0W

Keep-alive, pooling and timeouts

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 82
Connection: keep-alive
Keep-Alive: timeout=5, max=100

Full lesson: Proxies, load balancers and connection management →

HTTP API design in practice

Conditional writes, errors and versioning

HTTP/1.1 409 Conflict
Content-Type: application/problem+json

{
  "type": "https://api.example.com/problems/out-of-stock",
  "title": "Out of stock",
  "status": 409,
  "detail": "SKU A-1 has 0 units available.",
  "errors": [ { "field": "qty", "issue": "exceeds_available" } ]
}

Webhooks and delivery guarantees

POST /hooks/orders HTTP/1.1
Host: consumer.example.com
Content-Type: application/json
X-Event-Id: 01J8Y7Q2ZK3M4N5P6R7S8T9V0W
X-Event-Timestamp: 1770000000
X-Signature: t=1770000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

{"type":"order.shipped","data":{"id":1042,"status":"shipped"}}

Webhooks and delivery guarantees

import crypto from 'node:crypto';

export function verify(rawBody, header, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(header.split(',').map(p => p.trim().split('=')));
  const age = Math.abs(Date.now() / 1000 - Number(parts.t));
  if (age > toleranceSeconds) return false;
  const expected = crypto.createHmac('sha256', secret)
    .update(parts.t + '.' + rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Full lesson: HTTP API design in practice →

Debugging HTTP: tools, logs and observability

HAR capture, logs and tracing

HTTP/1.1 200 OK
Traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
Server-Timing: db;dur=53.2, cache;desc="MISS";dur=1.7, app;dur=12.4
X-Request-Id: 01J8Y7Q2ZK3M4N5P6R7S8T9V0W

HAR capture, logs and tracing

203.0.113.7 - - [18/Sep/2026:10:04:11 +0000] "GET /v1/orders?limit=50 HTTP/1.1" 200 1843 0.042 "https://app.example.com/" "Mozilla/5.0" rid=01J8Y7Q2ZK3M4N5P6R7S8T9V0W u=user-42

Full lesson: Debugging HTTP: tools, logs and observability →

FAQ

Is this HTTP 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 13 lessons of the HTTP 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 HTTP course — it carries the worked explanations, the edge cases and the exercises behind every line here.

Node.js PHP Java Go Rust Spring Boot

Last refreshed 2026-09-27.