By Arjun Mehta
Bad API documentation is a special kind of torture. You're trying to integrate with an API. You read the documentation three times and still don't understand what's supposed to happen. The examples don't match the actual API. The error messages aren't documented. You resort to reading source code or guessing.
Good API documentation is like a gift. It's clear, complete, and lets you get work done. The examples work. The error cases are documented. When something goes wrong, the docs tell you why and how to fix it.
The difference between the two isn't complexity. It's intentionality. Bad API docs happen when nobody prioritizes them. Good API docs happen when your team treats documentation as core to the product, not an afterthought.
This guide walks through how to write API documentation that developers actually use.
The Purpose of API Documentation
Let's start with why API documentation matters:
It's a sales tool. A developer evaluating your API will decide in 5 minutes whether it's worth learning. If your documentation is confusing, they'll use a competitor.
It reduces support burden. Every question you answer in documentation is a question you don't have to answer via email or Slack.
It attracts better integrations. Developers who can understand your API easily will build better integrations. Those struggling with unclear docs will build half-baked integrations and then blame your API.
It's code by other means. API documentation is how your API speaks to the world. It's as important as the API code itself.
The Structure of Good API Documentation
1. Getting Started / Quick Start
Your first page should let someone integrate in 5 minutes. It should include:
- How to get API credentials (with specific steps, not vague pointers)
- The simplest possible first API call (with full curl example)
- What to expect as a response
- Where to go next for more
Example:
## Quick Start
1. Get your API key:
- Sign in to your account
- Go to Settings > API Keys
- Click "Generate New Key"
2. Make your first API call:
curl -X POST https://api.example.com/v1/messages \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+1-555-0100",
"body": "Hello World"
}'
3. You'll get a response:
{
"id": "msg_12345",
"status": "sent",
"created_at": "2026-02-23T10:15:30Z"
}
Next: [Learn about webhooks](#webhooks)
Someone completely new should be able to follow this and have success within 5 minutes.
2. Core Concepts
Before diving into specific endpoints, explain concepts your API users need to understand:
- Authentication: How does security work? What formats? Where does the API key go?
- Pagination: If lists are paginated, how does that work?
- Rate limiting: Are there limits? How do they work? What happens when you exceed them?
- Versioning: How are API versions managed? How do you know you're using the latest?
- Webhooks: How do they work? How do you handle them safely?
Example:
## Authentication
The API uses Bearer token authentication. Include your API key in the Authorization header:
curl -X GET https://api.example.com/v1/account \
-H "Authorization: Bearer sk_live_abc123def456"
Your API key is secret. Never share it or commit it to version control. You can regenerate keys in your account settings.
## Rate Limiting
The API has a rate limit of 100 requests per minute. If you exceed this, you'll receive a 429 response:
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Limit: 100 per minute. Retry after 30 seconds."
}
}
You can check your current usage in the X-RateLimit-* response headers:
- X-RateLimit-Limit: 100
- X-RateLimit-Remaining: 42
- X-RateLimit-Reset: 1708689330 (Unix timestamp)
3. Endpoint Reference
For each endpoint, document:
- HTTP method and path
- What it does (in plain English)
- Authentication required (if any)
- Request parameters (what goes in the URL, headers, or body)
- Response format
- Error cases and what they mean
- A complete working example
Example:
## Get Account Details
GET /v1/account
Retrieve information about the authenticated account.
### Authentication
Required. Use Bearer token in Authorization header.
### Parameters
None.
### Response
Returns an Account object.
```json
{
"id": "acc_12345",
"name": "Acme Inc",
"email": "billing@acme.com",
"balance": 2500,
"balance_currency": "USD",
"created_at": "2024-01-15T10:30:00Z"
}
Errors
401 Unauthorized Invalid or missing API key. Check that your API key is valid and included in the Authorization header.
403 Forbidden Your account doesn't have permission for this action. Contact support if you believe this is an error.
Example
curl -X GET https://api.example.com/v1/account \
-H "Authorization: Bearer sk_live_abc123def456"
**4. Error Reference**
List all possible error codes and what they mean:
Error Codes
| Code | HTTP Status | Meaning | What to Do |
|---|---|---|---|
| invalid_request | 400 | Missing required parameter | Check your request parameters |
| authentication_failed | 401 | Invalid API key | Get a new API key |
| rate_limited | 429 | Too many requests | Wait before retrying |
| resource_not_found | 404 | The resource doesn't exist | Check the ID |
| server_error | 500 | Our problem, not yours | Retry after a few seconds |
**5. Code Examples**
Show how to use your API in different languages. At minimum:
- curl (works everywhere)
- JavaScript/TypeScript (Node.js and browser)
- Python
- Go
Example:
```python
import requests
api_key = "sk_live_abc123def456"
response = requests.get(
"https://api.example.com/v1/account",
headers={"Authorization": f"Bearer {api_key}"}
)
if response.status_code == 200:
account = response.json()
print(f"Account balance: {account['balance']} {account['balance_currency']}")
else:
print(f"Error: {response.status_code}")
print(response.json())
6. SDKs and Libraries
If you maintain official SDKs, link to them prominently. If the community has built SDKs, link to those too.
Common API Documentation Mistakes
1. Outdated Examples
Example shows a field that doesn't exist anymore. Shows the wrong response format. The quickest way to lose trust is documentation that's out of sync with reality.
Fix: Review documentation as part of API changes. Include version dates on major sections. Have a process for keeping docs current.
2. Missing Error Cases
Documentation shows the happy path. What about:
- Invalid parameters?
- Permissions denied?
- Rate limits?
- Server errors?
Fix: For each endpoint, document at least 3-5 error cases and what causes them.
3. Assuming Too Much Knowledge
"Creates a webhook" without explaining what webhooks are or why you'd want one.
Fix: Link to explanatory sections. Assume users know HTTP, but not necessarily your domain.
4. No Examples
Documentation with no code examples is hard to follow. Reading explanation for 10 minutes before seeing actual code wastes time.
Fix: Show working code examples for every concept.
5. Vague Parameters
"color: A color string." What format? Hex? RGB? "Named" color like red?
Fix: Be specific. Give examples. Document constraints. "color: Color as hex string (e.g., #FF0000) or named color (red, blue, green)"
Keeping Documentation in Sync with Code
The hardest part of API documentation is keeping it accurate as your API evolves.
1. API Documentation in Code
Some frameworks support inline documentation that becomes API docs automatically (OpenAPI/Swagger, for instance). This forces docs to stay in sync because the code defines the docs.
2. Automated Testing
Your documentation examples should be runnable tests. If someone changes an endpoint and the example breaks, tests fail.
3. Version Your API
Never break existing API versions. When making breaking changes, create a new version (v2). Maintain v1 documentation alongside v2. Let users upgrade at their pace.
4. Changelog
Maintain a detailed changelog. Document when things changed, why, and how to migrate. Users will check this first when updating.
Documentation for Internal APIs
If this is an internal API for your own teams, the standards are the same. In fact, they're more important. Your own engineers have limited patience for bad docs.
Good news: internal API docs are easier to maintain because you can change behavior more easily if docs are unclear. Use that to clarify things.
Frequently Asked Questions
Q: Should we use OpenAPI/Swagger?
A: OpenAPI specifications are great for maintaining documentation automatically. If you have the infrastructure, it's worth it. If you're starting, good hand-written documentation with working examples is better than perfect OpenAPI that's out of date.
Q: How much detail is too much?
A: Document the contract (what goes in, what comes out, what can go wrong). Don't document implementation details. "This endpoint pings three internal services" is internal. "This endpoint takes up to 5 seconds" is useful.
Q: Should we provide interactive documentation?
A: Tools like Swagger UI or Postman let developers try endpoints directly in the browser. This is helpful for exploration, but don't let it replace clear written documentation.
Q: How do we handle deprecation?
A: Mark deprecated endpoints clearly. Give users a long timeline (at least 6 months). Document the replacement endpoint. Show migration examples. Log deprecation warnings in responses.