Great API documentation reduces support burden and increases adoption. Here's how to create docs that developers actually want to read.
Documentation Structure#
Essential Sections#
11. Getting Started
2 - Quick start guide
3 - Authentication setup
4 - First API call
5
62. Authentication
7 - How to get API keys
8 - Token management
9 - Security best practices
10
113. API Reference
12 - All endpoints
13 - Request/response examples
14 - Error codes
15
164. Guides & Tutorials
17 - Common use cases
18 - Step-by-step workflows
19 - Best practices
20
215. SDKs & Libraries
22 - Official libraries
23 - Code examples
24 - Community resources
25
266. Changelog
27 - Version history
28 - Breaking changes
29 - Migration guidesOpenAPI Specification#
Complete Example#
1openapi: 3.0.0
2info:
3 title: E-commerce API
4 version: 1.0.0
5 description: |
6 API for managing products, orders, and customers.
7
8 ## Authentication
9 All endpoints require a Bearer token in the Authorization header.
10
11 ## Rate Limits
12 - 100 requests per minute for free tier
13 - 1000 requests per minute for paid plans
14
15servers:
16 - url: https://api.example.com/v1
17 description: Production
18 - url: https://api.staging.example.com/v1
19 description: Staging
20
21paths:
22 /products:
23 get:
24 summary: List products
25 description: Retrieve a paginated list of products
26 tags:
27 - Products
28 parameters:
29 - name: page
30 in: query
31 description: Page number (1-indexed)
32 schema:
33 type: integer
34 default: 1
35 minimum: 1
36 - name: limit
37 in: query
38 description: Items per page
39 schema:
40 type: integer
41 default: 20
42 minimum: 1
43 maximum: 100
44 - name: category
45 in: query
46 description: Filter by category
47 schema:
48 type: string
49 responses:
50 '200':
51 description: Successful response
52 content:
53 application/json:
54 schema:
55 $ref: '#/components/schemas/ProductList'
56 example:
57 data:
58 - id: "prod_123"
59 name: "Widget"
60 price: 29.99
61 pagination:
62 page: 1
63 totalPages: 10
64 '401':
65 $ref: '#/components/responses/Unauthorized'
66
67 post:
68 summary: Create product
69 description: Create a new product
70 tags:
71 - Products
72 requestBody:
73 required: true
74 content:
75 application/json:
76 schema:
77 $ref: '#/components/schemas/CreateProduct'
78 example:
79 name: "New Widget"
80 price: 39.99
81 category: "electronics"
82 responses:
83 '201':
84 description: Product created
85 content:
86 application/json:
87 schema:
88 $ref: '#/components/schemas/Product'
89 '400':
90 $ref: '#/components/responses/BadRequest'
91 '401':
92 $ref: '#/components/responses/Unauthorized'
93
94components:
95 schemas:
96 Product:
97 type: object
98 properties:
99 id:
100 type: string
101 example: "prod_123"
102 name:
103 type: string
104 example: "Widget"
105 price:
106 type: number
107 format: float
108 example: 29.99
109 category:
110 type: string
111 example: "electronics"
112 createdAt:
113 type: string
114 format: date-time
115 required:
116 - id
117 - name
118 - price
119
120 CreateProduct:
121 type: object
122 properties:
123 name:
124 type: string
125 minLength: 1
126 maxLength: 255
127 price:
128 type: number
129 minimum: 0
130 category:
131 type: string
132 required:
133 - name
134 - price
135
136 Error:
137 type: object
138 properties:
139 error:
140 type: object
141 properties:
142 code:
143 type: string
144 message:
145 type: string
146 details:
147 type: array
148 items:
149 type: object
150
151 responses:
152 Unauthorized:
153 description: Authentication required
154 content:
155 application/json:
156 schema:
157 $ref: '#/components/schemas/Error'
158 example:
159 error:
160 code: "UNAUTHORIZED"
161 message: "Invalid or missing API key"
162
163 BadRequest:
164 description: Invalid request
165 content:
166 application/json:
167 schema:
168 $ref: '#/components/schemas/Error'
169 example:
170 error:
171 code: "VALIDATION_ERROR"
172 message: "Validation failed"
173 details:
174 - field: "name"
175 message: "Name is required"
176
177 securitySchemes:
178 bearerAuth:
179 type: http
180 scheme: bearer
181 bearerFormat: JWT
182
183security:
184 - bearerAuth: []Code Examples#
Multiple Languages#
1## Create a Product
2
3<tabs>
4<tab title="cURL">
5```bash
6curl -X POST https://api.example.com/v1/products \
7 -H "Authorization: Bearer YOUR_API_KEY" \
8 -H "Content-Type: application/json" \
9 -d '{
10 "name": "Widget",
11 "price": 29.99,
12 "category": "electronics"
13 }'const product = await response.json();
</tab>
<tab title="Python">
```python
import requests
response = requests.post(
'https://api.example.com/v1/products',
headers={'Authorization': f'Bearer {api_key}'},
json={
'name': 'Widget',
'price': 29.99,
'category': 'electronics',
}
)
product = response.json()
Error Documentation#
1## Error Codes
2
3| Code | Status | Description |
4|------|--------|-------------|
5| `VALIDATION_ERROR` | 400 | Request validation failed |
6| `UNAUTHORIZED` | 401 | Invalid or missing API key |
7| `FORBIDDEN` | 403 | Insufficient permissions |
8| `NOT_FOUND` | 404 | Resource not found |
9| `RATE_LIMITED` | 429 | Too many requests |
10| `INTERNAL_ERROR` | 500 | Server error |
11
12### Error Response Format
13
14All errors follow this format:
15
16```json
17{
18 "error": {
19 "code": "VALIDATION_ERROR",
20 "message": "Validation failed",
21 "details": [
22 {
23 "field": "email",
24 "message": "Invalid email format"
25 }
26 ]
27 }
28}Handling Errors#
1try {
2 const response = await api.createProduct(data);
3} catch (error) {
4 if (error.code === 'VALIDATION_ERROR') {
5 // Show validation errors to user
6 error.details.forEach(d => console.error(`${d.field}: ${d.message}`));
7 } else if (error.code === 'RATE_LIMITED') {
8 // Wait and retry
9 await sleep(error.retryAfter * 1000);
10 return createProduct(data);
11 } else {
12 // Log and show generic error
13 console.error('API error:', error);
14 }
15}
## Interactive Documentation
### Swagger UI / Redoc
```typescript
// Express setup for Swagger UI
import swaggerUi from 'swagger-ui-express';
import YAML from 'yamljs';
const swaggerDoc = YAML.load('./openapi.yaml');
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc, {
customSiteTitle: 'My API Docs',
customCss: '.swagger-ui .topbar { display: none }',
}));
// Redoc alternative
app.get('/docs', (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>API Documentation</title>
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
<style>body { margin: 0; padding: 0; }</style>
</head>
<body>
<redoc spec-url='/openapi.yaml'></redoc>
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
</body>
</html>
`);
});
Best Practices#
1## Writing Style
2
3✅ Do:
4- Use clear, concise language
5- Provide complete, runnable examples
6- Document all error cases
7- Include authentication in every example
8- Show both request and response
9
10❌ Don't:
11- Use jargon without explanation
12- Show partial or broken examples
13- Assume prior knowledge
14- Hide important parameters
15- Forget to update after changesConclusion#
Great API documentation is an investment that pays off in developer adoption and reduced support burden. Start with OpenAPI, add code examples in multiple languages, and keep everything up to date.
Remember: developers judge your API by its documentation. Make it excellent.