API Documentation skill for Claude Code
First successful call in under five minutes. Claude treats the OpenAPI spec as the single source for reference and writes guides that link into it. Every endpoint gets real request and response examples in curl, JavaScript and Python, every error code gets a cause and a fix, and cross-cutting pages cover auth, pagination, rate limits, idempotency and webhooks. The spec is linted and checked against the running API so it cannot drift.
- name
api-documentation - size246 lines · ≈2,250 tokens
- files1
- licenseMIT
- updated
What Claude sees before loading it
This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.
description: Writes HTTP API documentation developers can integrate from without asking questions — a quickstart to the first successful call, authentication, per-endpoint reference with request and response examples in curl and SDK languages, error catalog, pagination, rate limits, idempotency, webhooks, and versioning — driven from an OpenAPI 3.1 spec that is linted and checked against the running API. Use when documenting a REST API, writing or fixing an OpenAPI spec, building an API reference page, or when integrators keep filing support tickets. Try asking
- Write API docs for our billing endpoints, starting from the Express routes
- Our OpenAPI spec is missing error responses and examples. Fix it
- Write a quickstart that gets a developer to their first successful API call
Use it when
- Documenting a REST or HTTP API for external or internal integrators
- Writing or repairing an OpenAPI specification
- Integrators keep asking the same questions in support
- Adding webhooks, pagination, or rate limit documentation
Skip it when
- You need the docs website framework, navigation and search, use docs-site instead
- You are designing contract tests rather than documentation, use contract-testing instead
How to check the result
Redocly lint passes, every documented curl example succeeds against the sandbox in a script, and a newcomer finishes the quickstart in under five minutes.
The common mistake it prevents
Documenting only the 200 response, so integrators discover 409, 422 and 429 behavior in production and file tickets to learn the fix.
API docs are done when a developer can get a successful response within five minutes of opening them, every endpoint has a copy-pasteable request and a real response, every error the API can return is documented with its fix, and the reference is generated from a spec that is validated against the running service.
Ground rules
- The OpenAPI document is the source of truth for reference. Guides are hand-written and link into it. Never maintain endpoint details in two places.
- Examples are real: captured from a sandbox, with realistic values (
"amount": 2500,"currency": "usd"), never"string"or0. - Document behavior, not just shape: defaults, limits, ordering, idempotency, side effects, and what happens on retry.
- Every response a client must handle is documented, including 4xx and 5xx.
- Time to first call is the metric. Optimize the quickstart before anything else.
Doc set structure
docs/api/
quickstart.md first authenticated call in < 5 min
authentication.md key types, scopes, where to get them, rotation
errors.md error format and catalog
pagination.md
rate-limits.md
idempotency.md
webhooks.md events, payloads, signature verification, retries
versioning.md policy + changelog link
guides/ task how-tos (e.g. "Accept a payment", "Sync users")
reference/ generated from openapi.yaml
openapi.yaml
Workflow
- [ ] 1. Gather: routes, auth model, error shapes, limits (from code and infra config)
- [ ] 2. Write or repair openapi.yaml; lint it
- [ ] 3. Capture real request/response examples from a sandbox
- [ ] 4. Write the quickstart and cross-cutting pages
- [ ] 5. Write task guides for the top 3–5 integration jobs
- [ ] 6. Render the reference; verify spec against the running API
1. Gather from the source
grep -rnE '@(Get|Post|Put|Patch|Delete)\(|router\.(get|post|put|patch|delete)\(|@app\.(get|post|put|patch|delete)\(' src | head -50
grep -rnE 'status\((4|5)[0-9]{2}\)|HTTPException\(|raise .*Error' src | head -50
Ask the owners what the code does not show: rate-limit numbers, retention, SLA, sandbox URL, versioning policy.
2. OpenAPI 3.1 essentials
openapi: 3.1.0
info: { title: Billing API, version: "2026-10-01" }
servers:
- url: https://api.example.com/v1
- url: https://sandbox.api.example.com/v1
security: [{ bearerAuth: [] }]
paths:
/invoices:
post:
operationId: createInvoice
summary: Create an invoice
description: Creates a draft invoice. Drafts are not sent until you call `POST /invoices/{id}/send`.
parameters:
- in: header
name: Idempotency-Key
schema: { type: string, maxLength: 255 }
description: Reuse the same key to safely retry. Keys expire after 24 hours.
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/InvoiceCreate" }
example: { customer_id: "cus_9f2k", amount: 2500, currency: "usd", due_date: "2026-11-01" }
responses:
"201":
description: Invoice created
content:
application/json:
schema: { $ref: "#/components/schemas/Invoice" }
"422": { $ref: "#/components/responses/ValidationError" }
"429": { $ref: "#/components/responses/RateLimited" }
components:
securitySchemes:
bearerAuth: { type: http, scheme: bearer }
responses:
ValidationError:
description: The request body failed validation.
content:
application/problem+json:
schema: { $ref: "#/components/schemas/Problem" }
Rules: every operation has operationId, summary (verb phrase), description with
behavior, request example, and all response codes. Schemas document format,
minimum/maximum, enum, nullable via type: [string, "null"] (3.1), and
readOnly fields.
Lint:
npx @redocly/cli lint openapi.yaml
# or Spectral with a ruleset file containing: extends: ["spectral:oas"]
npx @stoplight/spectral-cli lint openapi.yaml
3. Endpoint reference entry (what each must contain)
| Part | Content |
|---|---|
| Title + one-line purpose | “Create an invoice” |
| Behavior | Side effects, defaults, ordering, async processing |
| Auth | Required scope (invoices:write) |
| Parameters | Name, in, type, required, default, constraints, description |
| Request example | curl + 1–2 SDK languages |
| Response example | Real JSON, success case |
| Errors | Codes specific to this endpoint with causes |
| Related | Linked endpoints, webhooks fired |
Request examples in three forms:
curl https://api.example.com/v1/invoices \
-H "Authorization: Bearer $EXAMPLE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7c1e5a0e-2f5b-4c62-9d1d-1f0e9d0f8a11" \
-d '{"customer_id":"cus_9f2k","amount":2500,"currency":"usd","due_date":"2026-11-01"}'
const res = await fetch("https://api.example.com/v1/invoices", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.EXAMPLE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ customer_id: "cus_9f2k", amount: 2500, currency: "usd", due_date: "2026-11-01" }),
});
const invoice = await res.json();
import os, requests
r = requests.post("https://api.example.com/v1/invoices",
headers={"Authorization": f"Bearer {os.environ['EXAMPLE_API_KEY']}"},
json={"customer_id": "cus_9f2k", "amount": 2500, "currency": "usd", "due_date": "2026-11-01"},
timeout=10)
r.raise_for_status()
4. Cross-cutting pages
Quickstart (template):
1. Get a sandbox key: Dashboard → Developers → API keys (starts with `sk_test_`).
2. Make your first call: curl … /v1/me → shows expected JSON
3. Create something real: curl … POST /v1/invoices → expected JSON
4. Next: Accept a payment (guide), Webhooks, Errors
Errors: document the format once (RFC 9457 problem details recommended), then a catalog.
{
"type": "https://docs.example.com/errors/invalid-due-date",
"title": "Invalid due date",
"status": 422,
"detail": "due_date must be on or after the issue date (2026-10-19).",
"instance": "/v1/invoices",
"request_id": "req_8f2a1c"
}
| Code | HTTP | Cause | Fix |
|---|---|---|---|
invalid-due-date | 422 | due_date before issue date | Send a date ≥ today |
customer-not-found | 404 | Unknown customer_id or wrong environment | Check the ID exists in sandbox vs. live |
rate-limited | 429 | Over 100 req/s per key | Back off; honor Retry-After |
Pagination: state the style (cursor recommended), page size default and max, ordering, and show the loop:
let cursor;
do {
const page = await list({ limit: 100, starting_after: cursor });
handle(page.data);
cursor = page.has_more ? page.data.at(-1).id : undefined;
} while (cursor);
Rate limits: numbers per key/endpoint, headers returned, 429 behavior, recommended
backoff (exponential with jitter, honor Retry-After).
Webhooks: event list with payload examples, signature verification code, retry schedule, ordering guarantees (usually none), idempotent handling advice.
Versioning: how versions are selected (URL, header, date), deprecation notice period,
link to changelog (see changelog-release-notes).
6. Render and verify
npx @redocly/cli build-docs openapi.yaml -o dist/api-reference.html
Or render with Scalar, Redoc, Stoplight Elements, or the docs-site framework’s OpenAPI plugin.
- Contract-check the spec against the running API in CI (Schemathesis, Dredd, or
schema-validating integration tests; see
contract-testing). A spec that drifts from reality is worse than none. - Run every curl example from the docs against the sandbox in a script; fail CI on non-2xx where success is documented.
Gotchas
- Examples with
"string",0, ortrueeverywhere teach nothing; generated SDK docs often do this, so override with real examples. - Undocumented defaults (page size, sort order, timezone) become breaking changes when you change them, because clients depend on them anyway.
- Secret-looking example keys trigger secret scanners; use an obvious fake prefix
(
sk_test_EXAMPLE) or an env var. - Missing
Content-Typein curl examples produces confusing 415/400 errors for readers. - Documenting only 200 responses guarantees support tickets about 409, 422, and 429.
- Changing an
operationIdrenames generated SDK methods: a breaking change.
Verification
npx @redocly/cli lint openapi.yamlpasses with no errors.- A developer new to the API (or a clean shell) completes the quickstart in under five minutes using only the docs.
- Every endpoint has request and response examples and lists its error codes.
- Spec-vs-implementation check runs in CI.
About this skill
Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.