| name | api-doc-generator |
| description | Generate API reference documentation from source code—endpoints, schemas, auth, errors, and examples—when the task is to document an existing API rather than design or implement one. |
API Documentation Generator
Overview
Generate comprehensive, structured API documentation by analyzing source code.
The skill extracts endpoint definitions, HTTP methods, parameters,
request/response schemas, authentication requirements, and error handling
patterns, then produces documentation in both human-readable Markdown and
machine-readable OpenAPI 3.0 JSON format.
When to use
- The task is documenting an existing API from source code, route definitions, handlers, or schemas.
- The deliverable is reference documentation, endpoint docs, or an OpenAPI-style spec.
- The user needs to capture current API behavior, inputs, outputs, auth, and error shapes.
- The code already exists; the problem is documentation quality or completeness.
Do NOT use when:
- The task is designing a new API contract before implementation exists.
- The user only wants to consume or summarize already-written API docs.
- The interface is GraphQL, gRPC, or another protocol that needs a different doc structure.
Response format
Always structure the final response with these top-level sections, in this order:
- Summary — state the task, scope, and main conclusion in 1-3 sentences.
- Decision / Approach — state the key classification, assumptions, or chosen path.
- Artifacts — provide the primary deliverable(s) for this skill. Use clear subheadings for multiple files, commands, JSON payloads, queries, or documents.
- Validation — state checks performed, important risks, caveats, or unresolved questions.
- Next steps — list concrete follow-up actions, or write
None if nothing remains.
Rules:
- Do not omit a section; write
None when a section does not apply.
- If files are produced, list each file path under Artifacts before its contents.
- If commands, JSON, SQL, YAML, or code are produced, put each artifact in fenced code blocks with the correct language tag when possible.
- Keep section names exactly as written above so output stays predictable across skills.
Workflow
1. Scan for route/endpoint definitions
Search the codebase for route registration patterns. Look for framework-specific
patterns:
| Framework | Pattern to find |
|---|
| Express.js | app.get(), router.post(), app.use() with paths |
| FastAPI | @app.get(), @router.post(), path decorators |
| Django REST | urlpatterns, @api_view, ViewSet classes |
| Spring Boot | @GetMapping, @PostMapping, @RequestMapping |
| Go (Gin/Chi) | r.GET(), r.POST(), r.Route() |
| Rails | routes.rb, resources :, controller actions |
| NestJS | @Get(), @Post(), @Controller() decorators |
Output: A list of all endpoints with their file locations.
2. Extract HTTP methods, paths, and parameters
For each endpoint, extract:
- HTTP method (GET, POST, PUT, PATCH, DELETE)
- Path including path parameters (e.g.,
/users/:id)
- Query parameters from request parsing code
- Request body schema from validation or type definitions
- Response body from return statements or serializers
- Content types (JSON, form-data, multipart)
Parse path parameters from the route string. Look for query parameter access
(req.query, request.args, @Query) and body parsing (req.body,
request.json(), @Body).
3. Analyze request/response types
Trace type information from:
- TypeScript interfaces/types used in handlers
- Pydantic models, dataclasses, or serializers
- Zod/Joi/Yup validation schemas
- Database model definitions that map to responses
- JSDoc/docstring annotations
Build a schema for each request body and response body. Include field names,
types, required/optional status, and constraints (min/max, regex, enum values).
4. Document authentication requirements
Look for:
- Middleware applied to routes (
authenticate, requireAuth, jwt_required)
- Decorator-based auth (
@login_required, @Depends(get_current_user))
- Guard classes (NestJS
@UseGuards(AuthGuard))
- API key checks in handler code
- OAuth scopes or role-based access control
Document the auth scheme (Bearer token, API key, session cookie, OAuth2) and
which endpoints require it. Note any role/permission requirements.
5. Generate error response documentation
Analyze error handling to document:
- Validation errors (400) - what triggers them, response format
- Authentication errors (401) - when auth fails or is missing
- Authorization errors (403) - permission denied scenarios
- Not found errors (404) - when resources don't exist
- Conflict errors (409) - duplicate resources, state conflicts
- Rate limit errors (429) - if rate limiting is present
- Server errors (500) - generic error response format
For each error, document the status code, error response schema, and conditions
that trigger it. Look for custom error classes, error middleware, and exception
handlers.
6. Add usage examples
For every endpoint, generate:
- A curl example showing a complete request with realistic data
- A success response example with realistic field values
- An error response example showing the most common failure case
- Request body examples for POST/PUT/PATCH endpoints
Use realistic but obviously fake data (e.g., user@example.com, not
test@test.com). Include all required headers (Content-Type, Authorization).
7. Produce final structured output
Generate TWO output files:
api-docs.md - Human-readable Markdown documentation:
# API Reference
## Overview
Brief description of the API, base URL, and common patterns.
## Authentication
How to authenticate, token format, where to include credentials.
## Endpoints
### Resource Name
#### METHOD /path
Description of what this endpoint does.
**Parameters:**
| Name | In | Type | Required | Description |
| ---- | -- | ---- | -------- | ----------- |
**Request Body:**
```json
{ "example": "value" }
```
**Response (200):**
```json
{ "example": "response" }
```
**Error Responses:**
| Status | Description |
| ------ | ----------- |
**Example:**
```bash
curl -X METHOD https://api.example.com/path ...
```
openapi.json - OpenAPI 3.0 specification:
{
"openapi": "3.0.3",
"info": { "title": "API Name", "version": "1.0.0" },
"paths": { "...": {} },
"components": { "schemas": { "...": {} }, "securitySchemes": { "...": {} } }
}
Checklist
Example
Input: Express.js route file
const express = require("express");
const router = express.Router();
const { authenticate } = require("../middleware/auth");
const { validate } = require("../middleware/validate");
const { body, param, query } = require("express-validator");
router.get("/", authenticate, [
query("page").optional().isInt({ min: 1 }).toInt(),
query("limit").optional().isInt({ min: 1, max: 100 }).toInt(),
query("role").optional().isIn(["admin", "user", "moderator"]),
], async (req, res) => {
const { page = 1, limit = 20, role } = req.query;
const users = await User.find(role ? { role } : {})
.skip((page - 1) * limit)
.limit(limit);
const total = await User.countDocuments(role ? { role } : {});
res.json({ users, total, page, limit });
});
router.post(
"/",
authenticate,
[
body("email").isEmail().normalizeEmail(),
body("name").trim().isLength({ min: 2, max: 100 }),
body("role").isIn(["admin", "user", "moderator"]),
body("password").isLength({ min: 8 }),
],
validate,
async (req, res) => {
const existing = await User.findOne({ email: req.body.email });
if (existing) {
return res.status(409).json({ error: "Email already registered" });
}
const user = await User.create(req.body);
res.status(201).json({ user: user.toPublic() });
},
);
router.get(
"/:id",
authenticate,
[param("id").isMongoId()],
validate,
async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: "User not found" });
}
res.json({ user: user.toPublic() });
},
);
Output: (excerpt from api-docs.md)
# API Reference
## Authentication
All endpoints require a Bearer token in the Authorization header:
Authorization: Bearer <your-jwt-token>
## Endpoints
### Users
#### GET /api/users
List users with optional filtering and pagination.
**Query Parameters:**
| Name | Type | Required | Default | Description |
| ----- | ------- | -------- | ------- | ----------------------------------------- |
| page | integer | No | 1 | Page number (minimum: 1) |
| limit | integer | No | 20 | Results per page (1-100) |
| role | string | No | - | Filter by role: admin, user, or moderator |
**Response (200 OK):**
```json
{
"users": [
{
"id": "507f1f77bcf86cd799439011",
"email": "jane@example.com",
"name": "Jane Smith",
"role": "admin"
}
],
"total": 42,
"page": 1,
"limit": 20
}
```
**Error Responses:**
| Status | Condition | Body |
| ------ | --------------------- | ---------------------------------------- |
| 401 | Missing/invalid token | `{ "error": "Unauthorized" }` |
| 422 | Invalid query params | `{ "errors": [{ "param": "...", ... }]}` |
**Example:**
```bash
curl -H "Authorization: Bearer eyJhbG..." \
"https://api.example.com/api/users?page=1&limit=10&role=admin"
```
---
#### POST /api/users
Create a new user account.
**Request Body:**
| Field | Type | Required | Constraints |
| -------- | ------ | -------- | ------------------------------ |
| email | string | Yes | Valid email format |
| name | string | Yes | 2-100 characters |
| role | string | Yes | One of: admin, user, moderator |
| password | string | Yes | Minimum 8 characters |
```json
{
"email": "jane@example.com",
"name": "Jane Smith",
"role": "user",
"password": "secureP@ss123"
}
```
**Response (201 Created):**
```json
{
"user": {
"id": "507f1f77bcf86cd799439011",
"email": "jane@example.com",
"name": "Jane Smith",
"role": "user"
}
}
```
**Error Responses:**
| Status | Condition | Body |
| ------ | --------------------- | ----------------------------------------- |
| 401 | Missing/invalid token | `{ "error": "Unauthorized" }` |
| 409 | Email already exists | `{ "error": "Email already registered" }` |
| 422 | Validation failed | `{ "errors": [{ "param": "...", ... }]}` |
**Example:**
```bash
curl -X POST https://api.example.com/api/users \
-H "Authorization: Bearer eyJhbG..." \
-H "Content-Type: application/json" \
-d '{"email":"jane@example.com","name":"Jane Smith","role":"user","password":"secureP@ss123"}'
```
Common mistakes
| Mistake | Fix |
|---|
| Missing error responses | Check every res.status() call and error middleware. Document ALL non-2xx responses, not just the happy path. |
| Undocumented auth requirements | Trace middleware chains. If authenticate is applied to a router, ALL sub-routes require auth. |
| No request/response examples | Generate examples for every endpoint. Use realistic data, not "string" or "test". |
| Ignoring query parameters | Search for req.query, request.args, @Query() — these are often undocumented. |
| Missing parameter constraints | Document min/max, regex patterns, enum values — not just the type. |
| Incomplete OpenAPI spec | Validate the JSON against the OpenAPI 3.0 schema. Common gaps: missing required arrays, wrong $ref paths. |
| Documenting internal routes | Skip health checks, metrics endpoints, and internal admin routes unless explicitly requested. |
| Inconsistent formatting | Use the same table structure and section order for every endpoint. Consistency aids scanning. |
Quick reference
| Operation | How |
|---|
| Find Express routes | Search for router.get|post|put|delete|patch |
| Find FastAPI routes | Search for @app.get|post|put|delete|patch or @router. |
| Find auth middleware | Search for authenticate, requireAuth, jwt_required, @login_required |
| Find validation | Search for body(), param(), query(), Zod schemas, Pydantic models |
| Find error handling | Search for res.status(4, raise HTTP, throw new, custom error classes |
| Build OpenAPI paths | One entry per unique path, methods nested under path object |
| Build OpenAPI schemas | Extract from TypeScript types, Pydantic models, or validation schemas |
Key principles
-
Document every parameter - Every path param, query param, header, and
body field must appear in the docs. Undocumented parameters are the #1 source
of API integration bugs.
-
Include realistic examples - Every endpoint needs a curl example with
realistic (but fake) data, a success response, and at least one error
response. Developers copy-paste from docs; make it work.
-
Show error cases explicitly - Document every error status code with its
trigger condition and response body. Developers spend more time debugging
errors than writing happy-path code.
-
Maintain consistent structure - Every endpoint section must follow the
same format: description, parameters table, request body, response, errors,
example. Consistency lets developers scan quickly.
-
Dual output format - Always produce both human-readable Markdown and
machine-readable OpenAPI JSON. The Markdown is for developers reading docs;
the OpenAPI spec is for tooling (Postman, SDK generators, API gateways).