API Documentation Generator
What this skill does
This skill reads REST API route handlers (Express, FastAPI, Go net/http, Rails, Django, or any framework) and generates complete OpenAPI 3.0 YAML documentation. It extracts paths, HTTP methods, path/query/body parameters, response shapes, and error codes, then writes properly structured YAML with example request and response bodies. The output can be loaded directly into Swagger UI, Redoc, or any OpenAPI-compatible tool.
Use this when you have undocumented API code and need to produce accurate, usable API documentation quickly.
How to use
Claude Code / Cline
Copy this file to .agents/skills/api-docs-generator/SKILL.md in your project root.
Then point the agent at your routes file and ask:
- "Use the API Documentation Generator skill on
server/routes.ts."
- "Generate OpenAPI docs for all routes in
src/api/ using the API Documentation Generator skill."
The agent will read the route files and any referenced handler functions to extract parameter and response shapes.
Cursor
Add the "Prompt / Instructions" section to your .cursorrules file. Open your routes file in the editor and ask Cursor to generate the OpenAPI YAML.
Codex
Paste your route definitions and handler code into the chat along with the instructions below. Include type definitions or schema files if they exist — they help Codex produce accurate request/response schemas.
The Prompt / Instructions for the Agent
When asked to generate API documentation, follow these steps:
Read the route definitions. For each route, extract:
- HTTP method (GET, POST, PUT, PATCH, DELETE)
- Path, including path parameters (e.g.,
/users/:id → /users/{id})
- Router-level middleware (e.g., authentication guards — these become
security entries)
- The handler function name
Read the handler functions. For each handler, extract:
- Path parameters (e.g.,
req.params.id)
- Query parameters (e.g.,
req.query.page, req.query.limit)
- Request body shape — read from validation schema (Zod, Joi, Pydantic, etc.) if present, otherwise infer from how
req.body fields are used
- All
res.json() / return response shapes — enumerate every response including error paths
- HTTP status codes returned (
200, 201, 400, 401, 404, 500, etc.)
Infer data types accurately:
- If a Zod/Joi/Pydantic/serializer schema exists for the body or response, use it as the source of truth
- Otherwise infer types from usage: string, number, boolean, array, object
- Mark fields as
required if they are destructured without a default or checked for presence
- Note
nullable: true on fields that may be null
Write the OpenAPI 3.0 YAML with this structure:
openapi: "3.0.3"
info: title, version, description
servers: include a localhost dev server at minimum
paths: one entry per route
components/schemas: reusable schema objects referenced with $ref
components/securitySchemes: if auth middleware is detected (Bearer, API key, cookie)
For each path entry, include:
summary: one sentence describing what the endpoint does
description: optional longer explanation
parameters: path, query, and header params with name, in, required, schema, description
requestBody: with content/application/json/schema and a fully-formed example
responses: at minimum the success response and common error responses (400, 401, 404, 500)
- Each response must have a
description and a content/application/json/schema
Include realistic example values in request and response bodies. Do not use placeholder values like "string" or 0 — use realistic data (e.g., "john@example.com", 42, "2026-03-15T12:00:00Z").
Output the complete YAML in a single code block. Do not truncate.
Example
Input to Agent:
"Use the API Documentation Generator skill on this Express route:
router.post('/users', async (req, res) => {
const { name, email, role } = req.body;
if (!name || !email) return res.status(400).json({ error: 'name and email are required' });
const user = await db.users.create({ name, email, role: role ?? 'viewer' });
res.status(201).json({ id: user.id, name: user.name, email: user.email, role: user.role });
});
router.get('/users/:id', requireAuth, async (req, res) => {
const user = await db.users.findById(req.params.id);
if (!user) return res.status(404).json({ error: 'User not found' });
res.json({ id: user.id, name: user.name, email: user.email, role: user.role });
});
```"
Output from Agent:
openapi: "3.0.3"
info:
title: Users API
version: "1.0.0"
description: Endpoints for managing users.
servers:
- url: http://localhost:3000
description: Local development
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
schemas:
User:
type: object
properties:
id:
type: string
example: "usr_a1b2c3"
name:
type: string
example: "Jane Smith"
email:
type: string
format: email
example: "jane@example.com"
role:
type: string
enum: [viewer, admin]
example: "viewer"
Error:
type: object
properties:
error:
type: string
paths:
/users:
post:
summary: Create a new user
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, email]
properties:
name:
type: string
example: "Jane Smith"
email:
type: string
format: email
example: "jane@example.com"
role:
type: string
enum: [viewer, admin]
default: viewer
responses:
"201":
description: User created successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/User'
"400":
description: Missing required fields.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/users/{id}:
get:
summary: Get a user by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
example: "usr_a1b2c3"
responses:
"200":
description: User found.
content:
application/json:
schema:
$ref: '#/components/schemas/User'
"401":
description: Not authenticated.
"404":
description: User not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
1---2name: api-documentation-generator3description: Generates OpenAPI-compatible documentation for REST API endpoints from code or route definitions.4---56# API Documentation Generator78## What this skill does910This skill reads REST API route handlers (Express, FastAPI, Go net/http, Rails, Django, or any framework) and generates complete OpenAPI 3.0 YAML documentation. It extracts paths, HTTP methods, path/query/body parameters, response shapes, and error codes, then writes properly structured YAML with example request and response bodies. The output can be loaded directly into Swagger UI, Redoc, or any OpenAPI-compatible tool.1112Use this when you have undocumented API code and need to produce accurate, usable API documentation quickly.1314## How to use1516### Claude Code / Cline1718Copy this file to `.agents/skills/api-docs-generator/SKILL.md` in your project root.1920Then point the agent at your routes file and ask:21- *"Use the API Documentation Generator skill on `server/routes.ts`."*22- *"Generate OpenAPI docs for all routes in `src/api/` using the API Documentation Generator skill."*2324The agent will read the route files and any referenced handler functions to extract parameter and response shapes.2526### Cursor2728Add the "Prompt / Instructions" section to your `.cursorrules` file. Open your routes file in the editor and ask Cursor to generate the OpenAPI YAML.2930### Codex3132Paste your route definitions and handler code into the chat along with the instructions below. Include type definitions or schema files if they exist — they help Codex produce accurate request/response schemas.3334## The Prompt / Instructions for the Agent3536When asked to generate API documentation, follow these steps:37381. **Read the route definitions.** For each route, extract:39 - HTTP method (GET, POST, PUT, PATCH, DELETE)40 - Path, including path parameters (e.g., `/users/:id` → `/users/{id}`)41 - Router-level middleware (e.g., authentication guards — these become `security` entries)42 - The handler function name43442. **Read the handler functions.** For each handler, extract:45 - Path parameters (e.g., `req.params.id`)46 - Query parameters (e.g., `req.query.page`, `req.query.limit`)47 - Request body shape — read from validation schema (Zod, Joi, Pydantic, etc.) if present, otherwise infer from how `req.body` fields are used48 - All `res.json()` / `return response` shapes — enumerate every response including error paths49 - HTTP status codes returned (`200`, `201`, `400`, `401`, `404`, `500`, etc.)50513. **Infer data types accurately:**52 - If a Zod/Joi/Pydantic/serializer schema exists for the body or response, use it as the source of truth53 - Otherwise infer types from usage: string, number, boolean, array, object54 - Mark fields as `required` if they are destructured without a default or checked for presence55 - Note `nullable: true` on fields that may be null56574. **Write the OpenAPI 3.0 YAML** with this structure:58 - `openapi: "3.0.3"`59 - `info`: title, version, description60 - `servers`: include a localhost dev server at minimum61 - `paths`: one entry per route62 - `components/schemas`: reusable schema objects referenced with `$ref`63 - `components/securitySchemes`: if auth middleware is detected (Bearer, API key, cookie)64655. **For each path entry, include:**66 - `summary`: one sentence describing what the endpoint does67 - `description`: optional longer explanation68 - `parameters`: path, query, and header params with name, in, required, schema, description69 - `requestBody`: with `content/application/json/schema` and a fully-formed `example`70 - `responses`: at minimum the success response and common error responses (400, 401, 404, 500)71 - Each response must have a `description` and a `content/application/json/schema`72736. **Include realistic example values** in request and response bodies. Do not use placeholder values like `"string"` or `0` — use realistic data (e.g., `"john@example.com"`, `42`, `"2026-03-15T12:00:00Z"`).74757. **Output the complete YAML** in a single code block. Do not truncate.7677## Example7879**Input to Agent:**80> "Use the API Documentation Generator skill on this Express route:81>82> ```ts83> router.post('/users', async (req, res) => {84> const { name, email, role } = req.body;85> if (!name || !email) return res.status(400).json({ error: 'name and email are required' });86> const user = await db.users.create({ name, email, role: role ?? 'viewer' });87> res.status(201).json({ id: user.id, name: user.name, email: user.email, role: user.role });88> });89>90> router.get('/users/:id', requireAuth, async (req, res) => {91> const user = await db.users.findById(req.params.id);92> if (!user) return res.status(404).json({ error: 'User not found' });93> res.json({ id: user.id, name: user.name, email: user.email, role: user.role });94> });95> ```"9697**Output from Agent:**98> ```yaml99> openapi: "3.0.3"100> info:101> title: Users API102> version: "1.0.0"103> description: Endpoints for managing users.104> servers:105> - url: http://localhost:3000106> description: Local development107> components:108> securitySchemes:109> bearerAuth:110> type: http111> scheme: bearer112> schemas:113> User:114> type: object115> properties:116> id:117> type: string118> example: "usr_a1b2c3"119> name:120> type: string121> example: "Jane Smith"122> email:123> type: string124> format: email125> example: "jane@example.com"126> role:127> type: string128> enum: [viewer, admin]129> example: "viewer"130> Error:131> type: object132> properties:133> error:134> type: string135> paths:136> /users:137> post:138> summary: Create a new user139> requestBody:140> required: true141> content:142> application/json:143> schema:144> type: object145> required: [name, email]146> properties:147> name:148> type: string149> example: "Jane Smith"150> email:151> type: string152> format: email153> example: "jane@example.com"154> role:155> type: string156> enum: [viewer, admin]157> default: viewer158> responses:159> "201":160> description: User created successfully.161> content:162> application/json:163> schema:164> $ref: '#/components/schemas/User'165> "400":166> description: Missing required fields.167> content:168> application/json:169> schema:170> $ref: '#/components/schemas/Error'171> /users/{id}:172> get:173> summary: Get a user by ID174> security:175> - bearerAuth: []176> parameters:177> - name: id178> in: path179> required: true180> schema:181> type: string182> example: "usr_a1b2c3"183> responses:184> "200":185> description: User found.186> content:187> application/json:188> schema:189> $ref: '#/components/schemas/User'190> "401":191> description: Not authenticated.192> "404":193> description: User not found.194> content:195> application/json:196> schema:197> $ref: '#/components/schemas/Error'198> ```