Documentation Is Part of the Contract
For every consumer you never meet, the docs are the API. What must be documented is exactly what consumers are forced to assume — auth, errors, pagination, rate limits, idempotency, guarantees — and the examples are the most-executed code you ship. Undocumented behavior gets reverse-engineered and depended on anyway.
Frame the contract
API design starts with a consumer, a design question and a guarantee — never with a URL.
The checklist is the contract's table of contents
What belongs in API docs is not a style question — it is derivable: everything a consumer is forced to assume must be written down, because whatever you leave out gets reverse-engineered from behavior and depended on anyway (What an API Contract Actually Is's core argument, now applied to prose). The checklist below is that principle unrolled. Most real docs cover the first three entries and stop; every entry after "operations" is where integrations actually go wrong, because the happy path is easy to guess and the guarantees are not.
Structure follows audience task. Getting-started answers "make one successful call in five minutes" — auth setup through first 200, nothing else; its length is your adoption funnel. Guides answer "accomplish this task" (accept a payment, process a webhook) as ordered walkthroughs. Reference answers "exactly what does this operation do" — generated from the spec so it cannot drift (see OpenAPI: Describing the Contract, Not Designing It), fleshed with the behavioral prose the spec cannot hold. The changelog and migration guides answer "what changed and what must I do" (see Deprecation as a Process, Not a Label). These four serve different moments in a consumer's life; a docs site that is only reference has abandoned the first and last moments to support tickets.
- Purpose and model — what the API is for, its resources and their relationships; the mental model that makes every endpoint guessable (see From Domain to Resources).
- Authentication — how to get and send credentials, scopes, token lifetimes, and what
401vs403mean here (see Authentication in the Contract). - Operations — per endpoint: parameters, shapes, statuses. The spec-generated part.
- Errors — the taxonomy, every code a client may branch on, retryability per code, and a full example body per family (see An Error Taxonomy Clients Can Branch On and Retryability: Telling Clients What To Do Next).
- Pagination, filtering, limits — the house convention once, centrally, plus per-endpoint page-size caps (see Pagination: Choosing How Lists End).
- Rate limits and quotas — numbers, headers, and correct 429 handling with backoff (see The Rate-Limit Contract).
- Idempotency and retries — which operations are safe to retry, how keys work, what replays return (see Idempotency Keys: The Mechanism).
- Guarantees and non-guarantees — consistency, ordering, enum extensibility, tolerant-reader obligations: the Backward Compatibility: The Real Rules clauses, stated where consumers will read them.
- Versioning and deprecation policy — what "stable" promises, notice periods, where changes are announced (see Versioning: What a Version Even Promises).
Examples are executable claims — and failure needs them most
Developers integrate by copying examples: the example is often the only part of the page that gets read, and it is certainly the part that gets pasted into production code. That gives examples a quality bar higher than prose — realistic values (not "foo"), consistent entities across pages (the same ord_812 traced through creation, retrieval and webhooks becomes a corpus that teaches the object model by osmosis), and mechanical verification: examples extracted and run against a real environment in CI, because a broken example is a bug that every new consumer hits on day one. Docs that cannot be tested drift exactly like specs that are not diffed (see Testing the Contract, Not Just the Code).
The examples that separate adequate docs from good ones are the failure examples. Every consumer will meet your 422, your 409 and your 429 — most docs never show them, so every consumer's error handling is improvised. Show the full exchange for each error family: what triggers it, the exact body, and what the client should *do* — parse which field, retry after what, surface what to whom. This is also where honesty pays twice: documented failure behavior is failure behavior consumers can code against, which converts your error taxonomy from an internal design into a working contract (see The Error Model: Structure Over Apology).
POST /v1/payments HTTP/1.1
Authorization: Bearer sk_test_…
Idempotency-Key: 8c1f4b2a-77aa-4f0e-9c1d-2e5a6b7c8d9e
Content-Type: application/json
{
"amount": 1999,
"currency": "EUR",
"source": "card_expired_visa"
}HTTP/1.1 402 Payment Required
Request-Id: req_01J8ZQ…
Content-Type: application/json
{
"error": {
"code": "card_expired",
"message": "The card has expired.",
"request_id": "req_01J8ZQ…",
"retryable": false
}
}
Handling: not retryable — do NOT retry the same source.
Surface error.message to the payer; collect a new payment
method; reuse a fresh Idempotency-Key for the new attempt.Docs drift like code, and honesty is a feature
Documentation has the same enemy as specs: drift. The server changes; the prose does not; consumers now integrate against fiction that carries your logo. The defenses are structural, not moral. Generate the reference from the governed spec so shapes cannot drift (see Schema-First vs Code-First). Test the examples in CI so they cannot rot. Put docs changes in the definition of done for every contract change — the PR that alters behavior updates the page, or it does not merge. And date or version the guides, because a 2024 walkthrough silently wrong about 2026 behavior is worse than a page that says "outdated" on it.
Two habits mark documentation written by teams that have been consumers themselves. First, document the sharp edges: cursor expiry windows, eventual-consistency delays ("the object may take up to a few seconds to appear in list results" — see Consistency as a Contract Clause), rate-limit interactions with batch endpoints. Every documented limitation is a support ticket pre-answered and a trust deposit; the alternative is consumers discovering the edge in production and wondering what else you did not mention. Second, write the non-guarantees — error text may change, field order is not promised, new enum values will appear. Those sentences are what keep your own evolution options open (Backward Compatibility: The Real Rules is enforceable only if consumers were told the rules).
1GET /v1/orders2Returns the orders.3 4Parameters:5 limit (integer, optional)6 7Response: 200 OK8{ "data": [ Order ] }9 10# unstated: default/max limit, order,11# pagination, staleness, error shapes,12# whether new fields/enum values appear.13# every consumer now assumes answers.1GET /v1/orders2Lists orders, newest first (created_at desc,3id desc tiebreak — ordering is guaranteed).4 5limit: default 25, max 100. Results are6paginated (cursor — see Pagination guide);7new orders may take ~1s to appear (see8Consistency). Responses MAY gain fields9and `status` MAY gain values without10notice — see Compatibility rules.11 12Errors: 401, 403, 422 (examples below).The left version documents the shape and leaves every guarantee to the consumer's imagination. The right version costs six sentences and answers precisely the questions whose wrong guesses become integration bugs and support load.
Key points
- For consumers you never meet, docs are the API: whatever is undocumented gets reverse-engineered and depended on anyway.
- The checklist is derivable — auth, errors, pagination, limits, idempotency, guarantees, change policy — because it is exactly what consumers are otherwise forced to assume.
- Four structures for four moments: getting-started, task guides, spec-generated reference, changelog/migration — reference alone abandons the first and last to support.
- Examples are the most-executed code you ship: realistic, consistent across pages, and run in CI — and failure examples matter more than happy-path ones.
- Fight drift structurally: generated reference, tested examples, docs-in-definition-of-done, dated guides.
- Documented limitations and explicit non-guarantees are features — they pre-answer support tickets and keep your evolution rights intact.
Follow the failure
How the contract fails or gets misused, hop by hop — and what it costs when it completes.
- 1Team → docs: publishes an endpoint list with parameter tables; guarantees, errors and limits feel obvious to the people who built them, so nobody writes them.
- 2Consumers → docs: copy the one happy-path example, guess at error handling, and infer pagination and ordering from observed behavior.
- 3Server → change: a deploy changes default ordering — a behavior no doc ever promised but every consumer inferred.
- 4Consumers → support: integrations misbehave; tickets ask questions the docs should have answered; the team answers them one by one, in private, forever.
- 5Docs → fiction: two years of undocumented changes later, even the team routes around the docs — the real contract now lives in a support engineer's head.
- Every consumer improvises failure handling: retries on non-retryable errors (duplicate side effects), no backoff on 429s, error strings parsed as API (see Retryability: Telling Clients What To Do Next).
- Support load scales with consumer count instead of flattening — each undocumented answer is delivered privately N times rather than written once.
- Docs drift converts documentation from asset to liability: consumers integrate against fiction with your name on it, and discovering which pages are true becomes their job.
Design, observe, evolve
A contract decision is incomplete until you know how you would notice it failing and how it changes later.
- • Write docs against the checklist and review them like contract text — a missing guarantees section is a defect, not a style gap.
- • Generate reference from the governed spec, and hand-write the behavioral prose the spec cannot hold (idempotency, consistency, extensibility) next to each operation.
- • Test examples in CI against a real environment, keep one consistent entity cast across all pages, and show a full request/response exchange for every error family.
- • Make docs part of the definition of done for any contract change, and date or version every guide so staleness is visible instead of silent.
- • Cluster support tickets by which doc page should have answered them — the cluster map is your docs backlog, ranked by real cost.
- • Track time-to-first-successful-call for new consumers (sandbox telemetry): it is the getting-started guide's quality, measured.
- • Watch integration errors per endpoint (422 shapes, retry storms after 429): they concentrate where failure documentation is thinnest.
- • Docs are where evolution meets consumers: deprecation notices, changelogs and migration guides are documentation artifacts, and their credibility is set by the docs' everyday accuracy (see [[deprecation]]).
- • Spec-generated reference inherits contract governance for free — every approved spec diff updates the reference; the prose half still needs the definition-of-done rule to keep pace (see [[api-migration]]).
- • Written non-guarantees compound: each one is a future change you can make without a migration program, which is the cheapest evolution capital an API accumulates.
- • Complete docs are genuinely expensive — writing, example plumbing, CI verification, upkeep on every change — and the payoff accrues to consumers and future support load, not to this sprint.
- • Documented guarantees are commitments: every promise written down (ordering, consistency, limits) constrains the implementation exactly as [[what-is-an-api-contract]] says it will.
- • Internal APIs justify a thinner version — generated reference plus a guarantees paragraph may be the right cost — but "thinner" is a chosen point on the same checklist, not an exemption from it (see [[public-vs-internal-apis]]).
Misconceptions
status gains values. Those are sentences, and someone must write them.