07 · API Documentation Best Practices¶
An API is only as usable as its documentation. This module covers what makes docs actually work for a developer trying to integrate against your API for the first time, at 11pm, with no one to ask.
The documentation stack¶
- Reference docs — generated from the OpenAPI spec (Level 1, module 7): every endpoint, parameter, and response shape, always accurate because it's generated, not hand-written.
- Guides / tutorials — hand-written, task-oriented walkthroughs ("Authenticate and make your first request", "Set up webhooks").
- Changelog — dated, human-readable list of what changed, linked to migration guides for breaking changes (module 6).
- Interactive playground — lets a developer make a real call from the browser (Swagger UI, Redoc, Postman collections).
Reference docs generated from OpenAPI¶
paths:
/v1/orders/{id}:
get:
summary: Retrieve an order
parameters:
- name: id
in: path
required: true
schema: { type: integer }
responses:
"200":
description: The order
content:
application/json:
schema: { $ref: "#/components/schemas/Order" }
example: { id: 42, total: 42.50, status: "shipped" }
"404":
description: Order not found
The example block matters as much as the schema — most developers
copy the example and modify it rather than constructing a request from
the schema alone.
A good "Quickstart" guide¶
The single highest-leverage doc page. It should take a developer from zero to one successful authenticated call in under five minutes:
# 1. Get an API key from https://example.com/dashboard/keys
# 2. Make your first call:
curl https://api.example.com/v1/orders \
-H "Authorization: Bearer YOUR_API_KEY"
If step 2 doesn't work copy-pasted exactly as shown (real hostname, real header format, realistic response), the guide has failed its one job.
Documenting errors, not just happy paths¶
{
"error": {
"code": "insufficient_funds",
"message": "Account balance is too low to complete this order.",
"field": null,
"docs_url": "https://docs.example.com/errors/insufficient_funds"
}
}
An errors reference page listing every code your API can return, what
it means, and how to handle it, saves far more support tickets than
polishing the happy-path docs further.
Changelog entries that actually help¶
## 2026-08-15
### Added
- `GET /v1/orders` now supports `sort=-created_at` (module 2, Level 2).
### Deprecated
- `v1/orders.total` is deprecated in favor of `total_amount`. See the
[migration guide](/migration/total-field). Sunset: 2026-11-01.
Dated, categorized (Added/Changed/Deprecated/Removed), and every breaking or deprecating entry links to a migration guide — not just "we changed some stuff."
Worked example: docs for a new endpoint¶
A team ships POST /v1/orders/{id}/refund. A complete doc addition
includes:
- OpenAPI spec entry (auto-generates the reference page).
- A short guide section: "Refunding an order" with a working curl
example and both success and
409 Conflict(already refunded) responses shown. - A changelog entry under "Added."
- If this replaces an older
POST /v1/refundsendpoint, a deprecation entry for the old one, per module 6.
How It Actually Works¶
Good API docs aren't just prose — the mechanism that keeps them accurate is generating them from the same source that defines the API's actual behavior, rather than maintaining a separate hand-written description that drifts.
An OpenAPI-driven doc site (like Swagger UI or Redoc) works like this:
1. Your OpenAPI YAML/JSON is the single source of truth.
2. A doc-generator tool parses it and renders interactive HTML —
route list, parameter tables, example requests/responses — directly
from the schema's structure.
3. Swagger UI's "Try it out" button constructs a REAL HTTP request using
the schema's parameter definitions and sends it to the actual server,
rendering the real response — this only works because the schema
contains enough machine-readable detail (base URL, auth scheme,
parameter types) to build a valid request without a human writing it.
This is mechanically why "docs that lie" (a documented parameter that no
longer exists, an example that 400s) happen almost exclusively in
hand-written documentation systems disconnected from the code — nothing
forces prose to stay in sync with a route handler's actual if checks.
A schema-driven pipeline, by contrast, can be linted in CI: a contract
test (module 5) or schema-validation step that fails the build if the
implementation's actual response shape diverges from the documented
schema, catching drift before it reaches a published doc site at all.
Exercise¶
- Why should example values in an OpenAPI spec be realistic (
"id": 42) rather than placeholders ("id": "string")? - What's the difference in purpose between a quickstart guide and full reference docs — why do you need both?
- Design an errors-reference entry for a
rate_limitederror code, including what a client should do in response. - A breaking change ships without a changelog entry. What's the most likely support-team consequence a week later?