API Documentation Best Practices: Beyond Swagger and OpenAPI
Auto-generated API documentation is everywhere now. You spin up Swagger UI, point it at your OpenAPI spec, and boom—you've got searchable endpoints with request/response examples. Checkbox ticked. Ship it.
But here's the thing: that's not documentation. That's a reference manual.
Real API documentation tells you why decisions were made, how to avoid the gotchas that tripped up the last five developers, and what mental model you need to use this thing successfully. The difference between a Swagger page and actual docs is the difference between a parts catalog and a repair manual.
The Auto-Generated Docs Trap
Don't get me wrong—OpenAPI specs are useful. They give you:
- Accurate endpoint listings
- Request/response schemas
- Authentication requirements
- Type definitions
That's table stakes. Every API should have this. But if this is all you have, you're making your developers do archaeological work every time they integrate.
I've seen teams spend weeks on beautiful Swagger setups, complete with custom themes and example data, then wonder why developers still flood Slack with questions. The spec tells you what /api/users/{id} accepts. It doesn't tell you:
- Why you need to hit
/auth/refreshbefore batch operations - That rate limits reset at midnight UTC, not rolling windows
- Why webhook retries use exponential backoff starting at 5 minutes, not the industry-standard 1 minute
- That the
statusfield is a legacy string enum that should've been an integer, but changing it would break 10,000 production integrations
That context lives in Slack threads, old Notion pages, and the brains of people who've been here since v1. Auto-generated docs can't capture it.
What Real API Documentation Looks Like
Good API docs answer questions in layers:
Layer 1: The Mental Model
Start with the big picture. How does this API think about the world?
Is it REST-ful resources? GraphQL queries? RPC-style commands? Event-driven webhooks? A weird hybrid because you bolted features onto a 5-year-old architecture?
Say it out loud. "Our API is organized around projects and tasks. Everything happens inside a project context. You can't create tasks without a project, and webhooks are scoped to projects, not accounts."
That's 50 words that save hours of confusion.
Layer 2: Architecture Decisions
Document the why behind non-obvious choices:
- Why pagination uses cursor tokens instead of page numbers (hint: consistency when data changes)
- Why you chose POST for search endpoints even though GET feels right (request body size limits)
- Why webhook signatures use HMAC-SHA256 in the header, not JWT (performance on your side, simpler verification on theirs)
- Why some fields are
snake_caseand otherscamelCase(you acquired another company and merged APIs, didn't you?)
These aren't failures—they're context. Every API has weird corners. Documenting them earns trust.
Layer 3: Gotchas and Sharp Edges
This is where the real value lives. Call out the things that will trip people up:
Rate Limits That Lie:
"The X-RateLimit-Remaining header shows credits left, but batch endpoints consume multiple credits per request. If you POST 50 items to /bulk/create, that's 50 credits, not 1. Watch your math."
Eventual Consistency Surprises:
"Webhook delivery confirms the event was queued, not processed. If you immediately GET the resource, you might see stale data. Wait for the resource.updated webhook or poll with a 2-second delay."
Footguns:
"Never call /users/delete in a loop. Use /users/bulk-delete instead. We've seen single-threaded delete loops trigger rate limits and take 40 minutes to remove 1,000 users. Bulk endpoint does it in under 3 seconds."
This is tribal knowledge. You learned it by screwing up or watching someone else screw up. Write it down.
Layer 4: Migration Guides
APIs change. If you version your API (and you should), document what broke and how to fix it.
Bad migration guide:
"v2 introduces breaking changes. See changelog."
Good migration guide:
"In v2, we renamed user_id to userId for consistency. If you're on v1, search your codebase for user_id and replace with userId. TypeScript users: regenerate types from the OpenAPI spec. The old field will return null until June 2024, then we'll remove it."
That's actionable. It respects the reader's time.
Layer 5: Conceptual Walkthroughs
Show end-to-end flows for common use cases:
Example: "How to Sync a Project"
- GET
/projects/{id}to grab current state - Store the
last_modifiedtimestamp - Poll GET
/projects/{id}/changes?since={last_modified}every 30 seconds - Process incremental updates
- Update your local
last_modified
Why poll instead of webhooks? Webhooks are great for events, but terrible for "what did I miss while I was down?" Polling gives you reliable catch-up. Use both: webhooks for real-time, polling as a safety net.
That narrative structure—step-by-step with the reasoning embedded—is what people actually need.
How to Capture Tribal Knowledge
The hard part isn't writing docs. It's knowing what to write. Here's how to surface the undocumented stuff:
1. Watch Support Tickets
Every repeated question is a documentation gap. If three people ask "why does this endpoint return 202 instead of 200?", add a note:
"Returns 202 Accepted because processing happens async. The response includes a job_id. Poll GET /jobs/{job_id} until status: completed."
Ticket volume drops. Docs improve. Everyone wins.
2. Run Dogfooding Sessions
Sit with a developer (internal or external) and watch them integrate your API from scratch. No hints. Every time they pause or search Slack, that's a gap.
"Wait, do I need to URL-encode this?"
→ Add: "Query parameters are automatically URL-encoded by most HTTP libraries. If you're building requests manually, encode special characters."
This is painful but incredibly effective.
3. Document During Code Review
When you're reviewing a PR that changes the API, ask: "Will someone reading the docs understand why we did this?"
If not, update the docs in the same PR. Don't defer it. You'll never come back.
4. Instrument Your Docs
Use analytics on your documentation site. Which pages get visited most? Where do people bounce? If everyone lands on "Authentication" then immediately jumps to Slack, your auth docs are broken.
Fix the gaps with data, not guesses.
5. Use GitHub (or Similar) for Docs
Store your docs as Markdown in the same repo as your API. This makes them:
- Versionable (docs change with the code)
- Reviewable (docs are part of PR review)
- Searchable (grep works)
- Forkable (community can suggest fixes)
We practice this at Understudy. Our GitHub integration watches your docs repo and surfaces outdated sections when code changes. You get a notification: "3 endpoints were modified in this PR. Related docs: authentication.md, webhooks.md."
Keeps docs fresh without manual audits.
The Tools Don't Matter (Until They Do)
You can write great docs in Markdown, Notion, Docusaurus, readme.io, or a custom static site. The format matters way less than the content.
That said, tools can help:
- Search: Developers will CMD+F for keywords. Make sure search works.
- Code samples: Syntax-highlighted examples in multiple languages (curl, JavaScript, Python, Go). Bonus points if they're runnable.
- Versioning: Clear indicators of what version each page describes. Don't make people guess if this is current.
- Changelogs: Auto-generated from commit messages is fine, but editorialize the breaking changes.
At Understudy, we treat docs like first-class code. Every API change gets a documentation task. How it works: you write features, we track what needs documenting, you review and publish. The system enforces the habit.
What Success Looks Like
Good API documentation means:
- Developers integrate faster (hours, not days)
- Support questions drop (fewer "how do I?" tickets)
- Community contributions increase (people fix your docs when they're accessible)
- Onboarding is self-service (new hires don't need a guided tour)
Bad API documentation means:
- You're the bottleneck (everyone asks you how it works)
- Adoption is slow (people give up and use a competitor)
- Bugs are common (people misunderstand how to use it)
- Slack becomes your real docs (searchable, but not by anyone external)
Start Small, Iterate
You don't need to document everything on day one. Start with:
- Getting Started guide — "Here's how to make your first API call in under 5 minutes"
- Authentication flow — "Here's how to get a token and use it"
- Top 3 use cases — "Here's how 80% of users will use this"
Ship that. Then watch where people get stuck. Add sections as you go.
Documentation is a living thing. It rots if you don't maintain it. But if you bake it into your workflow—docs as part of PRs, support tickets feeding back into content, analytics showing gaps—it stays useful.
The Bottom Line
Auto-generated docs are necessary but not sufficient. Swagger tells you what the API does. Real documentation tells you why it's designed that way, how to avoid common mistakes, and what you need to know to ship confidently.
The difference is tribal knowledge. Capture it. Structure it. Keep it up to date.
Your developers—internal and external—will thank you. And your support team will stop answering the same question 50 times a week.
Building better docs? Understudy helps teams capture knowledge from code, tickets, and Slack—so your documentation actually stays current. See how it works.