Reference Documentation
Reference documentation is the lookup table of your API. It is not a tutorial, not a getting-started guide, not a place for narrative. It is a contract: every endpoint, every parameter, every response code, every error shape, documented completely and accurately. When a developer is mid-implementation and needs to know the exact type of a query parameter or the precise HTTP status code for a rate-limited request, they come here. If the answer is not here, your reference docs have failed.
What Reference Docs Must Cover
Every API resource needs the same information, presented in the same order, every time. Consistency is more important than cleverness.
For each endpoint:
- HTTP method and path
- Short description (one sentence)
- Authentication requirements
- Request parameters (path, query, header, body)
- Request body schema with types and constraints
- Response body schema with types and constraints
- Response codes (success and error)
- Rate limiting behavior
- Example request
- Example response
Parameter Documentation
Every parameter needs four things: name, type, whether it is required, and what it does. A fifth — constraints — is necessary whenever the type alone is insufficient.
Good parameter documentation:
Name: page_size
Type: integer
Required: No
Default: 20
Constraints: Minimum 1, maximum 100
Description: Number of results to return per page.
Bad parameter documentation:
page_size (int) - Page size.
The bad version tells you nothing you could not infer from the name. The good version tells you the default, the limits, and that it is optional. That is the difference between documentation and decoration.
Response Codes
Document every response code your API actually returns. Do not document codes you never return. Do not omit codes you sometimes return.
POST /v1/orders
201 Created - Order successfully placed. Returns the order object.
400 Bad Request - Invalid request body. Returns error object with
field-level details.
401 Unauthorized - Missing or invalid API key.
409 Conflict - Idempotency key already used with different parameters.
422 Unprocessable - Valid JSON but business rule violation (e.g.,
insufficient inventory).
429 Too Many Reqs - Rate limit exceeded. Retry-After header included.
500 Server Error - Something broke on our side. Include request ID
in support tickets.
Error Shapes
Document the structure of your error responses with the same rigor as success responses. Developers spend more time debugging errors than celebrating successes.
Error response schema:
{
"error": {
"type": "validation_error",
"message": "Human-readable summary of the problem",
"code": "INVALID_CURRENCY",
"details": [
{
"field": "currency",
"message": "Must be a valid ISO 4217 currency code",
"value": "USDX"
}
],
"request_id": "req_abc123"
}
}
Auto-Generated vs Hand-Written
This is not an either-or decision. It is a both-and decision, with clear boundaries.
What to Auto-Generate
Auto-generate from your OpenAPI/Swagger spec or equivalent source of truth:
Auto-generate:
- Endpoint paths and methods
- Parameter names, types, and constraints
- Request and response schemas
- Authentication requirements
- Basic example requests and responses
The spec is the single source of truth for structural information. If a developer can look at your code and derive it, it should be generated, not hand-written. Hand-written structural docs drift from reality within weeks.
What to Hand-Write
Hand-write:
- Descriptions that explain WHY, not just WHAT
- Gotchas and edge cases
- Relationships between endpoints
- Migration notes when behavior changes
- Semantic meaning of fields that are not obvious from the name
A field called status with type string and enum values active, pending, suspended is auto-generatable. The fact that suspended means the account owner must contact support and cannot be reactivated via API — that is hand-written.
OpenAPI as Source of Truth
OpenAPI (formerly Swagger) is the dominant standard for REST API specification. Use it as the single source from which reference docs are generated.
Good workflow:
1. Developers annotate code with OpenAPI metadata
2. CI generates the OpenAPI spec from code
3. CI generates reference docs from the spec
4. Hand-written descriptions live in the spec itself
5. Tests validate the spec matches actual API behavior
Bad workflow:
1. Developers write code
2. Someone writes docs in a wiki
3. Code changes
4. Docs do not change
5. Developers learn to ignore the docs
The spec-first approach has a cost: developers must maintain the spec alongside the code. But the alternative — docs that lie — is more expensive.
Structuring Reference Docs
Group by Resource, Not by Method
Good structure:
Orders
POST /v1/orders Create an order
GET /v1/orders List orders
GET /v1/orders/{id} Get an order
PATCH /v1/orders/{id} Update an order
DELETE /v1/orders/{id} Cancel an order
Bad structure:
GET endpoints
GET /v1/orders
GET /v1/orders/{id}
GET /v1/products
GET /v1/products/{id}
POST endpoints
POST /v1/orders
POST /v1/products
Developers think in resources, not in HTTP methods.
Versioning Docs
When your API has multiple versions, document each version separately. Do not interleave v1 and v2 in the same page with conditional notes. A developer using v1 should never have to mentally filter out v2 content.
Common Pitfalls
- Undocumented parameters — a parameter exists in the code but not in the docs. This is the single most common reference doc failure. Automated spec generation prevents it.
- Stale examples — example requests that return 400 because the schema changed. Test your examples in CI.
- Missing error codes — documenting only the happy path. Developers need error docs more than success docs.
- Describing implementation instead of behavior — "This endpoint queries the orders table" is an implementation detail. "Returns orders matching the filter criteria" is behavior.
- Inconsistent formatting — one endpoint documents parameters in a table, another uses a list, a third uses prose. Pick a format and enforce it everywhere.
- No example responses — schemas are necessary but not sufficient. A concrete example response saves developers from mentally constructing JSON from a schema definition.
- Documenting internal endpoints — if it is not part of your public contract, do not put it in your public docs. Internal endpoints belong in internal docs.
Testing Reference Docs
Reference docs can and should be tested automatically.
Automated doc tests:
- Validate all example requests against the OpenAPI spec
- Execute example requests against a staging environment
- Confirm response codes match documented codes
- Check for undocumented endpoints (code vs spec drift)
- Verify all linked resources actually exist
Stripe runs their example code snippets as integration tests. Every code sample in their docs is a test that must pass before docs ship. This is the gold standard.
Key Takeaways
- Reference docs are lookup tables, not narratives. Optimize for scanning, not reading.
- Document every parameter with name, type, required/optional, default, constraints, and description.
- Auto-generate structural information from an OpenAPI spec. Hand-write semantic descriptions and edge cases.
- Test your documentation the same way you test your code: automatically, in CI, on every change.
- Group by resource, not by method. Developers think in nouns, not verbs.
- Document errors with the same rigor as successes. Developers spend more time in error states than happy paths.