api-documentation
verified5fcc0451-c2a5-49d9-b171-759539829d77
Document an API precisely — endpoints, params, auth, request/response examples, and error codes (OpenAPI where possible). Use for any public or internal HTTP API.
Metadata
Skill file
# API Documentation
Use when documenting an HTTP API — public or internal — to ensure every endpoint is clearly described with real, tested examples.
## Per-Endpoint Template
Every endpoint must document these 8 fields:
```markdown
### POST /api/v1/users
**Purpose:** Create a new user account.
**Authentication:** Bearer token (see [Auth](#authentication))
**Path Parameters:** None
**Query Parameters:**
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `send_welcome` | boolean | No | `true` | Send welcome email after creation |
**Request Body:**
```json
{
"email": "user@example.com",
"name": "Jane Doe",
"role": "member"
}
```
**Response `201 Created`:**
```json
{
"id": "usr_abc123",
"email": "user@example.com",
"name": "Jane Doe",
"role": "member",
"created_at": "2025-01-15T10:30:00Z"
}
```
**Errors:**
| Status | Code | Meaning |
|---|---|---|
| 400 | `invalid_email` | Email format is invalid |
| 409 | `email_taken` | A user with this email already exists |
```
## OpenAPI-First Approach
Define the spec first, then implement. Validate with real calls.
```yaml
# openapi.yaml (minimal)
openapi: 3.0.3
info:
title: User API
version: 1.0.0
paths:
/users:
post:
summary: Create a user
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email, name]
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
responses:
'201':
description: Created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
```
### Generate docs from OpenAPI
```bash
# Swagger UI
npx @redocly/cli build-docs openapi.yaml -o docs.html
# Or use a live renderer
docker run -p 8080:8080 -v $(pwd)/openapi.yaml:/openapi.yaml swaggerapi/swagger-ui
```
## Keeping Examples Real
**The rule**: Every request/response example in your docs must be real output captured from a live endpoint.
```bash
# Capture a real response
curl -s -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"email":"demo@example.com","name":"Demo User"}' | jq .
# Paste the ACTUAL output into docs — with the real timestamp, real IDs, real fields.
# Then clean any sensitive data (real emails, tokens).
```
### Validation script pattern
```bash
#!/bin/bash
# verify-docs.sh — ensure examples match reality
set -e
# Test each documented endpoint against the actual API
curl -sf http://localhost:8080/api/v1/users | jq '. | length'
curl -sf -X POST http://localhost:8080/api/v1/users \
-d '{"email":"test@test.com","name":"Test"}' \
-H "Content-Type: application/json" | jq '.email'
```
## Type Documentation Rules
| Scenario | How to Document |
|---|---|
| Nullable field | `"middle_name": "Marie" or null` |
| Enum field | `"status": "active"` — one of: active, suspended, deleted |
| Timestamp | Always include timezone: `"2025-01-15T10:30:00Z"` |
| Optional field | Mark in schema: `required: false` |
| Deprecated field | Add `deprecated: true` and a note: "Use `full_name` instead" |
## Versioning Documentation
```markdown
# API v2 (Current)
Base URL: `https://api.example.com/v2`
# API v1 (Deprecated — sunset 2025-06-01)
Base URL: `https://api.example.com/v1`
Migration guide: [v1 → v2](MIGRATION.md)
```
## Guardrails
- **Never** document types that don't match the actual response — a user copy-pasting your example into their code should have it work.
- **Never** invent example data — curl the live endpoint and paste the output.
- **Never** skip error documentation — callers need to know what can go wrong and how to handle it.
- **Always** include auth requirements on every endpoint — even "no auth required" should be stated.
## Pitfalls
- **Examples that are invented, not captured**: The example shows `"id": "string"` but the actual API returns `"id": "usr_abc123"`. The difference breaks client code.
- **Documenting a future version, not the deployed one**: If the docs say the endpoint accepts `sort_by` but the deployed code doesn't, that's a bug users will hit.
- **Forgetting to document rate limits**: Every endpoint should document its rate limit or state "no rate limit."
- **Schema drift**: Adding a field to the API but not updating OpenAPI. Auto-generate from code annotations where possible (FastAPI, tsoa, etc.).
- **Authentication documented once and assumed everywhere**: Each endpoint should explicitly state its auth requirement or reference a global auth section.
## Verify / Checklist
- [ ] Every endpoint has all 8 fields documented (method+path, purpose, auth, params, request, response, errors)
- [ ] Response examples are real output from a live endpoint (copy-pasted after curl)
- [ ] All types match actual API responses (string vs integer, nullability, enum values)
- [ ] Error codes documented with actionable messages
- [ ] Authentication section is accurate and linked from each endpoint
- [ ] Rate limits documented per endpoint
- [ ] Deprecated endpoints/fields are clearly marked with migration guidance
- [ ] OpenAPI spec (if used) passes validation: `npx @redocly/cli lint openapi.yaml`
Attached files
No attached files.