# Examples — API Documentation House Style ## Contents - Complete worked example: one endpoint (bad → house style) - Error-table examples - Shared-concepts section pattern - Changelog entries - Gotchas ## Complete worked example: one endpoint **❌ Before:** ```markdown ### Create invoice Creates an invoice. Send a POST request with the invoice data. Returns the invoice object, or an error code if something goes wrong. curl /invoices -d foo=bar ``` **✅ After (house style):** ```markdown ### Create an invoice `POST /v1/invoices` — creates a draft invoice for a customer. Requires: `Authorization: Bearer` with an `invoices:write` key. **Parameters** | Name | Type | Required | Default | Constraints | |---|---|---|---|---| | `customer_id` | string | yes | — | existing customer, `cus_` prefix | | `amount` | integer | yes | — | cents, 50–999999 | | `currency` | string | no | `usd` | ISO 4217, lowercase | | `due_date` | string | no | +30 days | ISO 8601 date, future | **Request** curl https://api.acme.com/v1/invoices \ -H "Authorization: Bearer sk_test_51HxTmA..." \ -d customer_id=cus_9XKzR2 \ -d amount=1999 \ -d currency=usd **Response — 201** { "id": "inv_7GtQpN", "customer_id": "cus_9XKzR2", "amount": 1999, "currency": "usd", "status": "draft", "due_date": "2026-09-04", "created_at": "2026-08-05T14:03:22Z" } **Errors** | Status | Code | When | Fix | |---|---|---|---| | 400 | `amount_out_of_range` | amount below 50 or above 999999 | adjust the amount | | 401 | `invalid_api_key` | missing/revoked key | check the key and its prefix (test vs live) | | 403 | `missing_scope` | key lacks `invoices:write` | create a key with the scope | | 404 | `customer_not_found` | unknown `customer_id` | create the customer first | | 429 | `rate_limited` | over 100 req/min | back off per `Retry-After` | ``` What changed: full seven-part block; five-column parameter table; runnable curl with realistic fake data; actual JSON response; errors with when + fix. ## Error-table examples ✅ Each row actionable: `| 409 | idempotency_conflict | same Idempotency-Key with a different body | use a new key or resend the original body |` ❌ Non-actionable: `| 409 | conflict | conflict occurred | — |` ## Shared-concepts section pattern Write once, link everywhere: ```markdown ## Pagination List endpoints return at most `limit` items (default 20, max 100) and a `next_cursor`. Pass it as `cursor` to fetch the next page. Cursors expire after 24 h. curl "https://api.acme.com/v1/invoices?limit=50&cursor=eyJpZCI6..." ``` Every list endpoint then says: "Paginated — see [Pagination](#pagination)." Never re-explain pagination per endpoint (copies drift). ## Changelog entries ✅ "2026-06-01 — **Breaking:** `total` renamed to `amount_total` on invoice objects. Both fields returned until 2026-09-01; update readers before then." ❌ "June: minor improvements to invoice responses." ## Gotchas - **"foo/bar" sample data** signals the example was never run; use realistic prefixed IDs (`cus_`, `inv_`) and plausible amounts. - **Documenting the spec, not the behavior:** if the server returns fields the spec omits, the docs are wrong until reconciled — test against the real API. - **Error tables copied between endpoints** rot instantly; generate them per endpoint or verify each row. - **Auth examples with live-mode keys** get copy-pasted into scripts; always show `sk_test_` keys. - **Undocumented defaults** force callers to reverse-engineer; every optional parameter states its default, even when it's "empty".