Tutorial REST API API Design HTTP Best Practices Backend Web Development Architecture Developer Tools Cheat Sheet

Free REST API Design Patterns Cheat Sheet Online — 120+ API Architecture Best Practices & Design Reference

· 20 min read

Every REST API you build makes hundreds of small design decisions. Should IDs go in the URL or body? Use PUT or PATCH for updates? Version in the path or header? Return 400 or 422 for validation errors? These choices compound — a well-designed API is a joy to integrate with; a poorly-designed one generates support tickets for years. Our free interactive REST API Design Patterns Cheat Sheet gives you 120 battle-tested patterns across 10 categories, with real-time search, one-click copy, and a Cartographer's Atlas aesthetic inspired by antique map-making and exploration. No signup. No server. 100% client-side.

Why REST API Design Patterns Matter

REST API design is the difference between an API that developers love and one they complain about on Twitter. Developers form opinions about your API within the first five minutes of reading the docs — and those opinions stick. A consistent, well-designed API reduces integration time from days to hours, eliminates support tickets, and makes your product the default choice in a competitive market. At Stripe, the API is the product — their documentation and design quality are legendary precisely because every pattern is intentional. Our cheat sheet organizes 120 REST API design patterns into 10 essential categories so you can make those decisions quickly and confidently.

The 10 categories cover the full API design lifecycle: Resource Naming & URL Design (plural nouns, kebab-case, nesting limits, versioning, filtering/sorting query params, sparse fieldsets, search endpoints, sub-resources, and trailing slash policy), HTTP Methods & Semantics (GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS safety and idempotency, idempotency keys, POST vs PUT for creation, bulk operations, upsert pattern, and the complete method safety matrix), Request & Response Formats (JSON envelope, paginated responses, RFC 7807 error format, HAL/JSON:API/Siren/Collection+JSON hypermedia, ISO 8601 dates, binary responses, content negotiation, compression, and JSONPath partial responses), Status Code Usage (200/201+Location/202 async/204 empty/301 vs 308/400/401 vs 403/404/409/422/429/500 — when to use each and why), Authentication & Authorization (Bearer tokens, API keys, OAuth 2.0 with PKCE, JWT structure, HMAC signing, session cookies, CORS, scope-based and role-based access control, API gateway auth, rate limit headers, and token refresh flow), Pagination, Filtering & Sorting (offset/cursor/keyset/page-based pagination, Link header pagination, filter operators, sort conventions, sparse fieldsets, full-text search, date range filtering, related resource inclusion, and total count strategies), Error Handling (RFC 7807 Problem Details, consistent error schema, machine-readable error codes, validation error details, stack trace policy, correlation IDs, Retry-After, user-facing messages, i18n, error documentation, and error monitoring/alerting), Versioning (URL path, Accept header, query param, custom header, date-based, no-versioning evolution, Sunset/Deprecation headers, version lifecycle, breaking change policy, API changelog, backwards compatibility, and versioned documentation), Performance & Caching (ETag/If-None-Match, Cache-Control headers, conditional requests, response compression, streaming, connection pooling, batch/bulk endpoints, sparse fieldsets, 202 async pattern, webhooks, CDN caching, and database query optimization), and Security Best Practices (HTTPS enforcement, input validation, output encoding, CORS, CSP headers, rate limiting, request size limits, SQL injection prevention, secrets management, audit logging, API key rotation, and security headers checklist). Each entry includes the pattern name, when and why to use it, a detailed code example in multiple languages, and practical guidance.

Resource Naming & URL Design — The Foundation of REST

Resource naming is where REST API design starts — and where most mistakes happen. Our Resource Naming & URLs category covers: Plural Nouns for Collections (/users not /user — plural clearly communicates "this is a collection," singletons like /profile and /me are the exception), kebab-case in URLs (/user-sessions not /user_sessions or /userSessions — hyphens are treated as word separators by search engines, underscores are not), the max 3-level nesting rule (limit to /a/b/c — flatten deeper hierarchies with query params like /tasks?project_id=3), API versioning in the URL path (/api/v1/users — simplest and most common approach, easy to route and debug), filtering via query params (?status=active&role=admin — keep filters flat, standardize [gte]/[lte]/[gt]/[lt]/[like] operators), pagination query params (?page=2&per_page=20 or ?cursor=xxx&limit=20 — include pagination metadata in every list response), sorting (?sort=-created_at,name — descending by date then ascending by name, the minus-prefix convention), sparse fieldsets (?fields=id,name,email — reduces payload by 60-90%, critical for mobile and slow connections), search endpoint design (GET /search?q=term&type=users — separate full-text search from structured filtering), sub-resource endpoints (/posts/42/comments — only for composition relationships where the child can't exist without the parent), trailing slash policy (pick one and redirect the other with 301 — most modern APIs omit trailing slashes), and resource ID in the URL path (/users/42 not POST /users/get with body — keeps resources addressable and bookmarkable).

HTTP Methods — The Verbs of REST

Using HTTP methods correctly is one of the most visible signs of a well-designed API. Our HTTP Methods & Semantics category covers: GET (safe and idempotent — never use for state changes, can be cached, bookmarked, pre-fetched, and retried automatically), POST (create a new resource, return 201 Created with Location header, not idempotent — use idempotency keys for at-most-once semantics), PUT (full replacement — send all fields, missing fields reset to defaults, idempotent), PATCH (partial update — JSON Merge Patch RFC 7396 for simple field updates, JSON Patch RFC 6902 for complex operations, not guaranteed idempotent), DELETE (remove the resource, return 204 No Content or 200 with deleted data, idempotent), HEAD (metadata only — check existence, get Content-Length, verify Last-Modified), OPTIONS (capability discovery — returns Allow header and CORS headers, essential for browser preflight), idempotency keys (Idempotency-Key header for exactly-once POST/PATCH semantics — server stores key→response mapping for 24h), the POST vs PUT for creation decision (server-generated ID → POST to collection; client-specified ID → PUT to /users/{id}), bulk operations (POST /users/bulk with array, return per-item results with partial success), the upsert pattern (PUT with If-None-Match: * for create-only, PUT without header for create-or-replace), and the complete method safety/idempotency matrix (GET/HEAD/OPTIONS = safe + idempotent, PUT/DELETE = not safe but idempotent, POST = neither safe nor idempotent, PATCH = depends on the operation).

Request & Response Formats — The Shared Language

Consistent response formats are the skeleton of a great API. Our Request & Response Formats category covers: the JSON response envelope ({ data, meta, errors, links } — wraps every response in a predictable structure), paginated response format (data array + pagination metadata + next/prev/first/last links), the RFC 7807 Problem Details error format ({ type, title, status, detail, instance } — the standard for API errors, with custom extensions for validation errors), HAL hypermedia (_links for navigation, _embedded for related resources — enables API discoverability), the JSON:API specification (compound documents with included resources, sparse fieldsets, standardized relationships — comprehensive but opinionated), Siren (entities with class, properties, actions, and links — includes action descriptions for state changes), Collection+JSON (specifically for lists and collections — includes templates for creating new items), consistent date formats (ISO 8601 always: 2026-05-18T14:30:00Z with timezone, prefer UTC, use consistent field naming), binary response handling (Content-Type + Content-Disposition headers, presigned URLs for cloud storage instead of proxying), content negotiation (Accept header for format selection, return 406 if unsupported), response compression (gzip/brotli/zstd — 80-90% reduction for JSON, handle at proxy level), and partial responses with JSONPath (advanced field selection beyond simple ?fields= — for complex nested data selection).

Status Code Usage — Saying What Happened

HTTP status codes are the universal language of web APIs — and choosing the right one eliminates confusion. Our Status Code Usage category covers the 12 most important codes for REST APIs: 200 OK (generic success, meaning depends on method — GET returns resource, PUT/PATCH returns updated resource), 201 Created (new resource created — Location header is REQUIRED, response body contains the created resource), 202 Accepted (async processing — return immediately with status URL for polling, use for reports/batch jobs/email), 204 No Content (success with no body — best for DELETE and fire-and-forget actions, browser stays on current page), 301 vs 308 redirects (301 for SEO page moves, 308 for API endpoint moves — 308 preserves HTTP method, 301 may not), 400 Bad Request (syntactically malformed — invalid JSON, missing headers, not for validation errors), 401 vs 403 (the most confused pair: 401 = authentication required "who are you?", 403 = authenticated but forbidden "you can't do that" — 401 needs WWW-Authenticate header), 404 Not Found (resource doesn't exist — for private resources, return 404 instead of 403 to hide existence), 409 Conflict (state conflict — resource was modified since client read it, used with optimistic concurrency), 422 Unprocessable Entity (semantic validation errors — JSON parses but data is wrong, per-field errors for form mapping, standard in Rails/Laravel/FastAPI), 429 Too Many Requests (rate limiting — always include Retry-After, pair with X-RateLimit-* headers), and 500 Internal Server Error (unexpected error — never expose stack traces, always return request ID for support, log full details server-side).

Authentication & Authorization — Who Goes There

Auth is the gateway to your API — get it right and everything else flows. Our Authentication & Authorization category covers: Bearer token authentication (Authorization: Bearer <token> — validate on every request, prefer httpOnly cookies over localStorage), API key authentication (X-API-Key header for server-to-server, long random strings with prefix convention like sk_live_*, support key rotation), OAuth 2.0 Authorization Code flow with PKCE (redirect → approve → code → exchange for tokens → use access → refresh, PKCE required for SPAs/mobile), JWT structure and best practices (Header.Payload.Signature — never store secrets in payload, short expiration 15min, RS256 for microservices, include iss/sub/exp/iat/scope claims), HMAC request signing (sign method+path+timestamp+body with shared secret — prevents replay attacks, used by high-security APIs), session cookie authentication (httpOnly Secure SameSite cookies — more secure than localStorage tokens, include CSRF protection), CORS configuration (never use * with credentials, specify exact origins, handle OPTIONS preflight, set Access-Control-Max-Age), scope-based access control (read:users, write:posts, admin:settings — check scopes on every request, OAuth 2.0 scope parameter), role-based access control (RBAC) (admin/editor/viewer roles with permission sets — simpler than scope-based for many apps), API gateway authentication (centralize auth at the gateway layer — validate tokens before requests reach services, forward user context in headers), rate limit headers (X-RateLimit-Limit/Remaining/Reset on every response — helps clients self-throttle), and the token refresh flow (short-lived access tokens + long-lived refresh tokens + refresh token rotation — detects stolen refresh tokens).

Pagination, Filtering & Sorting — Finding Needles in Haystacks

Any collection endpoint needs pagination, and the strategy you choose has lasting consequences. Our Pagination, Filtering & Sorting category covers: offset pagination (?page=2&per_page=20 — simple with SQL LIMIT/OFFSET, includes total count and prev/next links, but inconsistent when data changes), cursor pagination (?cursor=xxx&limit=20 — stable with real-time data, no OFFSET performance penalty, use for feeds and timelines), keyset pagination (?after_id=42&limit=20 — uses actual field values, efficient with indexes, client knows last value seen), page-based pagination (?page=3&size=20 — same as offset but with size terminology, include total_pages in metadata), Link header pagination (RFC 5988 HTTP Link header — keeps response body clean, used by GitHub API: Link: <url>; rel="next"), filter operator conventions (?price[gte]=100&price[lt]=500 — eq/neq/gt/gte/lt/lte/like/in/nin/exists/regex operators), sort parameter convention (?sort=-created_at,name — minus prefix for descending, always validate against allowlist), sparse fieldsets (?fields=id,name,email — 60-90% payload reduction, JSON:API uses fields[users]=id,name), full-text search (GET /search?q=keyword — separate from filtering, return relevance scores and highlights), date range filtering (?created_at[gte]=2026-01-01&created_at[lt]=2026-02-01 — always ISO 8601, be explicit about inclusive/exclusive), related resource inclusion (?include=author,comments.author — compound documents avoid N+1 client requests), and total count strategies (COUNT(*) can be expensive — consider opt-in with ?include_total=true, estimated counts, or has_more for cursor pagination).

Error Handling — When Things Go Wrong

Good error handling saves more developer hours than any other API design decision. Our Error Handling category covers: RFC 7807 Problem Details (Content-Type: application/problem+json — type URI, title, status, detail, instance — the standard error format), consistent error schema ({ error: { code, message, status, request_id, details } } — every error uses the same structure regardless of status code), machine-readable error codes (VALIDATION_FAILED, RESOURCE_NOT_FOUND, RATE_LIMITED — clients switch on codes, document all codes in API docs), validation error details (per-field [{ field, code, message, constraint }] — enables client-side form mapping), stack trace policy (development: full details, production: generic message + request ID only — never expose file paths, SQL queries, or internal IPs), correlation IDs (X-Request-ID on every response — UUID generated at entry point, logged with all operations, clients include in support tickets), Retry-After for rate limits (always include with 429 — seconds or HTTP-date, client implements exponential backoff with jitter), user-facing error messages (actionable, not cryptic — "An account with this email already exists. Try logging in." not "ERR_DB_DUP_ENTRY"), i18n error messages (return error codes for client-side translation, or use Accept-Language header for server-side), error documentation (each error code has a documented page with cause, solution, and example request/response), API error monitoring (track 5xx rate, 429 spikes, new error codes — alert at 5xx > 1% for 5 minutes), and error rate alerting (separate alerts for 4xx and 5xx, correlate with deployments, dashboard by endpoint).

Versioning — Managing Change

API versioning is about managing change without breaking your consumers. Our Versioning category covers: URL path versioning (/api/v1/users — simplest, most common, easy to route, URLs change with versions), Accept header versioning (Accept: application/vnd.api+json;version=1 — clean URLs, harder to test, more RESTful), query parameter versioning (?version=1 — simple but can conflict with resource params), custom header versioning (API-Version: 2026-05-18 — date-based like Stripe, clean URLs, explicit), no-versioning API evolution (only add fields, never remove or rename — simplest for clients, hardest to maintain), Sunset header (RFC 8594) (Sunset: Sat, 31 Dec 2026 23:59:59 GMT — announce deprecation timelines, give months of notice), the Deprecation header (Deprecation: true + Link to migration docs — pair with Sunset for removal timeline), version lifecycle management (Current ~18 months → Deprecated 6 months → Retired returns 410 Gone — support max 2 versions at once), breaking change policy (removing/renaming fields, changing types, removing endpoints, changing auth = breaking — additive changes are safe), API changelog (public-facing, dated entries with what changed, why, and migration steps — auto-populate from git), backwards compatibility (never break within a major version — test old clients against new API, additive-only changes), and versioned documentation (/docs/v1, /docs/v2 — OpenAPI auto-generated, clearly mark deprecated, include migration guides).

Performance & Caching — Speed as a Feature

An API's performance directly impacts your users' experience and your infrastructure costs. Our Performance & Caching category covers: ETag / If-None-Match (resource versioning with 304 Not Modified — saves bandwidth by skipping unchanged responses), Cache-Control headers (private with max-age=0 for user data, public with s-maxage for CDN, immutable for static data), conditional requests (If-Match for optimistic concurrency, If-None-Match for caching, If-Modified-Since for time-based), response compression (gzip → 80-85% reduction, brotli → 85-90% — handle at Nginx/Cloudflare level, not application code), response streaming (Transfer-Encoding: chunked or Server-Sent Events — client processes data as it arrives, reduces memory and time-to-first-byte), connection pooling (keep-alive connections — avoids TCP/TLS handshake overhead, 30-50% latency reduction for sequential requests), batch/bulk endpoints (POST /users/bulk — multiple operations in one request, limit batch size, return per-item results with partial success), sparse fieldsets for performance (?fields=id,name cuts 5KB to 200 bytes per user — 96% reduction, combined with database column selection for end-to-end optimization), the 202 async processing pattern (return immediately for slow operations, provide status polling endpoint, notify via webhooks on completion), webhook callbacks (register webhook URLs instead of polling — more efficient for long-running operations, include HMAC signature for verification), CDN caching strategy (Cache-Control: public, s-maxage=7200 for CDN TTL, purge on data updates, differentiate authenticated vs anonymous responses), and database query optimization (use indexes on filter/sort fields, SELECT only needed columns, eager loading to avoid N+1, paginate at database level).

Security Best Practices — The Non-Negotiable Layer

Security is not optional — every API must implement these patterns from day one. Our Security category covers: HTTPS everywhere (enforce TLS for all endpoints, redirect HTTP → HTTPS with 301, HSTS header with max-age=31536000, TLS 1.2 minimum), input validation (validate type/format/length/range/enum — allowlist approach, reject unknown fields, return 422 with per-field errors), output encoding (always JSON-encode responses, never concatenate user data, set Content-Type: application/json; charset=utf-8), CORS policy (never * with credentials, specify exact origins, limit allowed methods/headers, handle OPTIONS preflight), Content Security Policy headers (default-src 'none' for JSON APIs, frame-ancestors 'none', X-Content-Type-Options: nosniff), rate limiting (token bucket or sliding window, different limits per tier/endpoint, return 429 with Retry-After), request size limits (1MB for JSON bodies, 10MB for uploads, return 413 Payload Too Large — prevent memory exhaustion), SQL injection prevention (always parameterized queries/prepared statements, never concatenate user input, use ORM with safe API), secrets management (never hardcode — use environment variables or secret managers, rotate regularly, audit access), audit logging (log auth attempts, CRUD on sensitive resources, admin actions — immutable, timestamped, with user ID and IP), API key rotation (POST /api-keys/rotate returns new key, old key works for 24h grace period, support multiple active keys), and the complete security headers checklist (Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, CSP, Referrer-Policy, Permissions-Policy).

How to Use This Cheat Sheet in Your Daily Workflow

Our Cartographer's Atlas-themed cheat sheet is designed for speed and exploration. Press Ctrl+K to jump to the search bar and type any pattern name (e.g., "pagination" or "idempotency") or concept (e.g., "validation" or "versioning"). The cards filter in real-time as you type. Click any card to copy its pattern name to your clipboard. The 10 category tabs let you focus on specific design areas — click "Resource Naming & URLs" when designing new endpoints, "Authentication & Authorization" when setting up auth, or "Error Handling" when defining your error response format. Each card includes the pattern name, when and why to use it, a detailed code example, and the category it belongs to. The antique map aesthetic — with parchment textures, compass rose decorative elements, latitude/longitude grid lines, and IM Fell English / Courier Prime typography — gives the tool a distinctive cartographer's study feel that stands apart from generic developer tools.

For related API and HTTP tools, see our HTTP Status Codes Cheat Sheet (120 status codes across 10 categories, the companion to this design patterns reference), our HTTP Methods Cheat Sheet (complete HTTP method semantics and usage), our curl Commands Cheat Sheet (the essential tool for testing REST APIs from the command line), our Web APIs Cheat Sheet (browser API reference for frontend-backend integration), our jq Commands Cheat Sheet (JSON processing for API responses), and our PostgreSQL Commands Cheat Sheet (database patterns every API developer needs). All tools are free, interactive, and require no signup.

Frequently Asked Questions About REST API Design

What are the most important REST API design patterns?

The most important REST API design patterns form the foundation every API should implement: (1) Resource naming — use plural nouns (/users not /user), kebab-case, and keep nesting to 3 levels max. (2) Correct HTTP method semantics — GET for reading (safe, idempotent), POST for creation (returns 201 with Location header), PUT for full replacement (idempotent), PATCH for partial updates (JSON Merge Patch RFC 7396), DELETE for removal (returns 204). (3) Consistent response formats with a standard envelope containing data, metadata, and errors. (4) Proper status code usage — 201 with Location for creation, 204 for empty success, 422 for validation errors, 429 for rate limiting, with the critical 401 vs 403 distinction. (5) Bearer token authentication with short-lived access tokens (15 min), long-lived refresh tokens, and token rotation. (6) Cursor-based pagination for real-time data — stable, fast, and avoids the inconsistent results of offset pagination. (7) RFC 7807 error format with machine-readable codes, per-field validation details, and correlation IDs for debugging.

Should I use PUT or PATCH for partial updates in REST APIs?

Use PATCH for partial updates — when the client only sends the fields that changed. PATCH has two standard formats: JSON Merge Patch (RFC 7396) where you send only the changed fields (set to null to delete, omit unchanged fields), and JSON Patch (RFC 6902) where you send an array of explicit operations like [{"op": "replace", "path": "/email", "value": "new@email.com"}]. Use PUT when the client sends the complete resource representation — all fields, even unchanged ones. PUT is idempotent (same request sent N times produces the same result), while PATCH is not guaranteed idempotent (depends on the patch operation). Most modern REST APIs use PATCH with JSON Merge Patch for simplicity — it's intuitive and maps naturally to HTML form partial updates.

How should I version my REST API?

The four main REST API versioning approaches each have trade-offs: (1) URL path versioning (/api/v1/users) — the simplest and most common approach, easy to route and debug, but URLs change with each version. Best for public APIs with infrequent breaking changes. (2) Accept header versioning (Accept: application/vnd.api+json;version=1) — clean URLs, more RESTful, but harder to test in browsers and has caching implications. (3) Query parameter versioning (/api/users?version=1) — simple but can conflict with resource query params. (4) Date-based custom header versioning (API-Version: 2026-05-18) — used by Stripe, intuitive ("the API as of this date"), clean URLs. For most teams, URL path versioning is the pragmatic choice. Regardless of approach, always use the Sunset header (RFC 8594) to announce deprecation timelines and give clients at least 6 months of notice before removing old versions.

What is the best pagination strategy for REST APIs?

Cursor-based pagination is recommended for most modern REST APIs. It uses a cursor (?cursor=xxx&limit=20) — typically an opaque base64-encoded string pointing to the last returned item. Key advantages: stable with real-time data (new items added don't shift pages), efficient on large datasets (no SQL OFFSET performance penalty), and simple response format (has_more + next_cursor). Offset pagination (?page=2&per_page=20) is simpler to implement but produces inconsistent results when data changes between requests and performs poorly on large tables due to OFFSET scanning. Keyset pagination (?after_id=42&limit=20) is a middle ground using actual field values instead of opaque cursors. Always include pagination metadata (has_more indicator, next/prev links) in the response. For small datasets (< 1000 records), offset pagination with a total count is perfectly fine.

What is the difference between 401 Unauthorized and 403 Forbidden?

401 Unauthorized means authentication is missing, expired, or invalid — the server doesn't know who the client is. It must include a WWW-Authenticate header telling the client how to authenticate (Bearer, Basic, Digest). Return 401 when the user needs to log in, their token has expired, or credentials are wrong. 403 Forbidden means the server knows who the client is (authentication succeeded) but the authenticated user lacks permission to access this specific resource. Return 403 when an authenticated user tries to access another user's private data, access an admin-only endpoint, or perform an action their role doesn't allow. Mixing these up is the most common REST API design mistake — returning 401 when the user is already authenticated confuses clients because their credentials are valid.

How should I handle validation errors in my REST API?

Return 422 Unprocessable Entity for semantic validation errors — the JSON parses correctly but the field values don't make sense (invalid email format, negative age, missing required field). This is the de facto standard used by Rails, Laravel, and FastAPI. Structure the response with per-field error details: {"error": {"code": "VALIDATION_FAILED", "message": "Validation failed", "status": 422, "details": [{"field": "email", "code": "invalid_format", "message": "Must be a valid email address"}, {"field": "age", "code": "out_of_range", "message": "Must be between 0 and 150"}]}}. This enables client-side form validation mapping — the client can iterate over details and show inline errors next to the corresponding form fields. Use 400 Bad Request for syntactically malformed requests (invalid JSON, missing Content-Type header) — problems that prevent the server from even parsing the request. Machine-readable error codes (invalid_format, out_of_range) let clients handle errors programmatically while human-readable messages support display.