---
name: kodadocs-api-reference
description: "Detect API framework, parse endpoints, and generate comprehensive API reference documentation with curl examples."
---

# API Reference Generator

## Overview

This skill generates comprehensive API reference documentation by detecting the API framework in use, parsing endpoint definitions, extracting request/response schemas, and producing structured markdown with curl examples for every endpoint. The output integrates as a dedicated `/api-reference/` section in your KodaDocs VitePress site.

Use this skill when:
- Your project exposes a REST API and you need endpoint documentation
- You want auto-generated curl examples for every route
- You have a FastAPI, Express, Django REST Framework, or Rails API that needs reference docs
- You want to document authentication schemes, request bodies, and response shapes
- You want the API reference to live alongside your user-facing documentation

## Prerequisites

Before running this skill, ensure the following:

1. **Project codebase:** The project directory must contain API source code with endpoint definitions.
2. **Running application (optional but recommended):** If the API server is running, the skill can fetch live OpenAPI specs and validate endpoints.
3. **KodaDocs manifest (optional):** If integrating with an existing doc site, a previous pipeline run should exist (`.kodadocs/run_manifest.json`).

## Workflow

### Step 1: Detect API Framework

Identify which API framework the project uses by analyzing the codebase.

**Run codebase analysis:**
Call `mcp__kodadocs__analyze_codebase` with the project path:
```
project_path: "<project-root>"
```

**Run framework detection:**
Call `mcp__kodadocs__detect_framework` with the project path:
```
project_path: "<project-root>"
```

**Additionally, scan for framework-specific indicators:**

| Framework | Detection Signals |
|-----------|-------------------|
| FastAPI | `from fastapi import` in Python files, `FastAPI()` instantiation |
| Express | `express()` in JS/TS files, `app.get`, `app.post`, `router.get` |
| Django REST | `rest_framework` in INSTALLED_APPS, `serializers.py`, `ViewSet` classes |
| Rails | `config/routes.rb` exists, `ActionController::API`, `resources :` in routes |
| Hono | `import { Hono }` in TS files, `new Hono()`, `app.get`, `app.post` |
| Flask | `from flask import Flask`, `@app.route` decorators |
| NestJS | `@Controller()` decorators, `@Get()`, `@Post()` in TS files |
| Spring Boot | `@RestController`, `@GetMapping`, `@PostMapping` in Java/Kotlin files |
| Gin (Go) | `gin.Default()`, `r.GET`, `r.POST` in Go files |
| Axum (Rust) | `axum::Router`, `.route()` in Rust files |

**Priority order when multiple frameworks are detected:**
1. Use the framework with the most endpoint definitions
2. If tied, prefer the one in the main application directory (not in tests or examples)
3. If still tied, ask the user which framework is the primary API

### Step 2: Extract Endpoints — FastAPI Path

FastAPI projects generate an OpenAPI specification automatically. This is the richest source of API documentation.

**If the server is running:**
```bash
# Fetch the OpenAPI spec (default FastAPI endpoint)
curl -s http://localhost:<PORT>/openapi.json
```

If `/openapi.json` returns a valid JSON response, parse it directly. This provides:
- All endpoint paths and HTTP methods
- Request body schemas (JSON Schema format)
- Response schemas with status codes
- Query parameters, path parameters, and headers
- Authentication requirements (securitySchemes)
- Descriptions and summary text from docstrings

**If the server is NOT running, use static analysis:**

Scan Python files for FastAPI route decorators:
```
Search patterns:
  @app.get("...")
  @app.post("...")
  @app.put("...")
  @app.patch("...")
  @app.delete("...")
  @router.get("...")
  @router.post("...")
  (and so on for all HTTP methods)
```

For each endpoint found, extract:
1. **Path:** The URL string from the decorator argument
2. **Method:** The HTTP method from the decorator name
3. **Function name:** The decorated function
4. **Parameters:** Function arguments with type annotations
5. **Request body:** Pydantic model referenced in the function signature (`Body(...)`, typed parameter)
6. **Response model:** From `response_model=` in the decorator
7. **Status code:** From `status_code=` in the decorator (default 200)
8. **Dependencies:** From `Depends(...)` — often indicates auth requirements
9. **Tags:** From `tags=` — used for grouping

**Parse Pydantic models** referenced in endpoints:
- Find the model class definition
- Extract all fields with their types, defaults, and descriptions
- Handle nested models recursively
- Handle `Optional[...]`, `List[...]`, `Dict[...]` types

### Step 3: Extract Endpoints — Express / Hono Path

For Express.js, Hono, or similar Node.js frameworks, parse route definitions from source files.

**Scan for route registrations:**

Search for route patterns in JS/TS files:
```
Patterns to match:
  app.get(
  app.post(
  app.put(
  app.patch(
  app.delete(
  router.get(
  router.post(
  router.put(
  router.patch(
  router.delete(
  app.route("...").get(
  app.route("...").post(
```

**For each route found, extract:**
1. **Path:** The first string argument to the method call
2. **Method:** The HTTP method from the method name
3. **Middleware:** Any middleware functions in the argument list (auth, validation)
4. **Handler function:** The last argument (the request handler)

**Determine route prefixes:**
- Check for `app.use("/api/v1", router)` to establish base paths
- Check for `Router()` mounted at sub-paths
- Reconstruct the full URL path by combining prefix + route path

**Extract request/response shapes:**
- Look for `req.body` destructuring or property access to infer request body fields
- Look for `req.params` to identify path parameters
- Look for `req.query` to identify query parameters
- Look for `res.json({...})` or `res.send({...})` to infer response shapes
- If Zod or Joi validation schemas exist, parse those for exact types

**Parse validation schemas (if present):**

| Library | Pattern | Extraction |
|---------|---------|------------|
| Zod | `z.object({...})` | Extract field names, types, and `.optional()` markers |
| Joi | `Joi.object({...})` | Extract field names, types, and `.required()` markers |
| express-validator | `body("field").isString()` | Extract field names and type checks |
| TypeBox | `Type.Object({...})` | Extract field names and types |

**Check for OpenAPI/Swagger middleware:**
If the project uses `swagger-jsdoc`, `tsoa`, or `@nestjs/swagger`, look for an OpenAPI spec endpoint:
```bash
curl -s http://localhost:<PORT>/api-docs
curl -s http://localhost:<PORT>/swagger.json
curl -s http://localhost:<PORT>/docs/json
```

If found, prefer the OpenAPI spec over manual parsing.

### Step 4: Extract Endpoints — Django REST Framework Path

For Django REST Framework projects, parse URL configurations and serializers.

**Scan URL patterns:**

Read `urls.py` files (there may be multiple across apps):
```
Search patterns:
  path("...", view, name="...")
  re_path(r"...", view, name="...")
  router.register(r"...", ViewSet)
  urlpatterns = [...]
```

**For router-based views (ViewSets):**
Each `router.register` creates multiple endpoints automatically:
- `GET /resource/` — list
- `POST /resource/` — create
- `GET /resource/{id}/` — retrieve
- `PUT /resource/{id}/` — update
- `PATCH /resource/{id}/` — partial update
- `DELETE /resource/{id}/` — destroy

Check the ViewSet class to see which actions are enabled (list, create, retrieve, update, partial_update, destroy) and any custom `@action` methods.

**For function-based views:**
- Check the `@api_view(['GET', 'POST'])` decorator for allowed methods
- Parse the function body for `request.data` usage (request body)
- Parse `serializer_class` references for request/response shapes

**Parse serializers:**
- Find `serializers.py` files across all apps
- For each `Serializer` class, extract:
  - Field names and types (`CharField`, `IntegerField`, `BooleanField`, etc.)
  - Read-only fields (`read_only_fields = (...)`)
  - Write-only fields (`extra_kwargs = {"password": {"write_only": True}}`)
  - Nested serializers
  - Validation methods (`validate_<field>`, `validate`)

**Parse permissions:**
- Check `permission_classes` on views for auth requirements
- `IsAuthenticated` -> requires auth token
- `IsAdminUser` -> requires admin role
- `AllowAny` -> public endpoint

### Step 5: Extract Endpoints — Rails Path

For Rails API projects, parse route configuration and controllers.

**Parse routes:**
Read `config/routes.rb`:
```
Search patterns:
  get "...", to: "controller#action"
  post "...", to: "controller#action"
  put "...", to: "controller#action"
  patch "...", to: "controller#action"
  delete "...", to: "controller#action"
  resources :name
  resource :name
  namespace :name do ... end
```

**For `resources` declarations:**
Each `resources :items` generates:
- `GET /items` — index
- `POST /items` — create
- `GET /items/:id` — show
- `PUT /items/:id` — update
- `PATCH /items/:id` — update
- `DELETE /items/:id` — destroy

Check for `only:` or `except:` to filter which routes are generated.

**Parse controllers:**
- Find controller files in `app/controllers/`
- For each action method, look for `params.require(:resource).permit(:field1, :field2)` to infer request body
- Check `render json:` for response shape
- Check `before_action :authenticate!` for auth requirements

**Parse serializers (if ActiveModel Serializers or Blueprinter is used):**
- Find serializer files in `app/serializers/`
- Extract `attributes`, `has_many`, `belongs_to` for response shapes

### Step 6: Document Authentication Schemes

Identify and document the API's authentication mechanism.

**Detection signals:**

| Auth Type | Signals |
|-----------|---------|
| Bearer Token (JWT) | `Authorization: Bearer`, `jwt.verify`, `jsonwebtoken`, `pyjwt` |
| API Key (Header) | `X-API-Key`, `x-api-key`, custom header checks in middleware |
| API Key (Query) | `?api_key=`, `?key=`, query parameter validation |
| Basic Auth | `Authorization: Basic`, `base64`, `btoa` in auth logic |
| OAuth 2.0 | `passport`, `oauth2`, `grant_type`, `/oauth/token` endpoint |
| Session/Cookie | `express-session`, `cookie-session`, `Set-Cookie`, `csrf` |
| No Auth | No auth middleware found on public endpoints |

**For each auth type, generate a documentation section:**

```markdown
## Authentication

### Bearer Token

All authenticated endpoints require a Bearer token in the `Authorization` header.

**Obtaining a token:**
1. Call `POST /auth/login` with your credentials
2. The response includes an `access_token` field
3. Include the token in subsequent requests

**Example:**
```bash
curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://api.example.com/resource
```

**Token expiration:**
Tokens expire after [duration]. Refresh tokens using `POST /auth/refresh`.
```

If multiple auth schemes exist (e.g., API key for external consumers, JWT for the web app), document all of them with clear usage guidance.

### Step 7: Generate Endpoint Documentation

For each endpoint, produce a structured documentation block.

**Endpoint documentation template:**

```markdown
### <METHOD> <path>

<One-line description of what this endpoint does>

**Authentication:** <required | optional | none>

**Parameters:**

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| id | path | string | yes | The resource identifier |
| page | query | integer | no | Page number (default: 1) |
| limit | query | integer | no | Items per page (default: 20) |

**Request Body:**

```json
{
  "name": "string (required)",
  "email": "string (required)",
  "role": "string (optional, default: 'user')"
}
```

**Response:**

`200 OK`
```json
{
  "id": "abc123",
  "name": "Example",
  "email": "user@example.com",
  "role": "user",
  "created_at": "2026-01-15T10:30:00Z"
}
```

`400 Bad Request`
```json
{
  "error": "validation_error",
  "message": "Name is required"
}
```

`401 Unauthorized`
```json
{
  "error": "unauthorized",
  "message": "Invalid or expired token"
}
```

**Example:**

```bash
curl -X POST https://api.example.com/users \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Doe",
    "email": "jane@example.com"
  }'
```
```

**Formatting rules for each endpoint:**
1. Use the HTTP method and path as the heading
2. Write a one-line description (derive from docstrings, function names, or generate from context)
3. List all parameters in a table (path, query, header)
4. Show request body as formatted JSON with type annotations
5. Show response for each possible status code
6. Provide a complete curl example with realistic sample data
7. Note authentication requirements

### Step 8: Group Endpoints by Resource

Organize endpoints into logical groups for the documentation.

**Grouping strategy:**

1. **By tag (if OpenAPI spec available):** Use the tags from the spec
2. **By route prefix:** Group endpoints that share a URL prefix:
   - `/users/*` -> "Users" section
   - `/auth/*` -> "Authentication" section
   - `/orders/*` -> "Orders" section
3. **By controller (Django/Rails):** Group by the controller or ViewSet name
4. **By file (Express):** Group by the router file they are defined in

**Ordering within each group:**
1. Overview/list endpoints first (GET collection)
2. Create endpoint (POST)
3. Read single resource (GET with ID)
4. Update endpoint (PUT/PATCH)
5. Delete endpoint (DELETE)
6. Custom actions last

**Global ordering of groups:**
1. Authentication endpoints first (login, register, token refresh)
2. Core resource endpoints in logical order
3. Utility endpoints last (health check, status, version)

### Step 9: Assemble the API Reference

Compile all endpoint documentation into a complete API reference structure.

**Top-level structure:**

```markdown
# API Reference

## Overview

Base URL: `https://api.example.com`

All endpoints return JSON responses. Request bodies must be JSON with
`Content-Type: application/json`.

## Authentication

<auth section from Step 6>

## Rate Limiting

<if rate limiting is detected in middleware>
- Rate limit: N requests per minute
- Headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`

## Error Format

All errors follow a consistent format:

```json
{
  "error": "error_code",
  "message": "Human-readable description"
}
```

## Common Status Codes

| Code | Meaning |
|------|---------|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful delete) |
| 400 | Bad Request (validation error) |
| 401 | Unauthorized (missing or invalid auth) |
| 403 | Forbidden (insufficient permissions) |
| 404 | Not Found |
| 429 | Too Many Requests (rate limited) |
| 500 | Internal Server Error |

## Endpoints

<grouped endpoint sections from Steps 7-8>
```

### Step 11: Integrate with Doc Site

Add the API reference as a section in the KodaDocs VitePress documentation site.

1. **Load the existing manifest:**
   Call `mcp__kodadocs__load_manifest` to retrieve the current pipeline state.

2. **Create article objects for the API reference:**

   Split the API reference into multiple articles for better navigation:
   ```json
   [
     {
       "title": "API Overview",
       "slug": "api-reference/overview",
       "content": "<overview + auth + error format markdown>",
       "order": 800
     },
     {
       "title": "Authentication API",
       "slug": "api-reference/authentication",
       "content": "<auth endpoints markdown>",
       "order": 801
     },
     {
       "title": "Users API",
       "slug": "api-reference/users",
       "content": "<users endpoints markdown>",
       "order": 802
     }
   ]
   ```

   Create one article per endpoint group. Use order numbers starting at 800 so the API reference appears after user guides but before FAQ/changelog.

3. **Reassemble the site:**
   Call `mcp__kodadocs__assemble_vitepress` with all existing articles plus the new API reference articles. Preserve the existing configuration from the manifest.

4. **Optionally redeploy:**
   Call `mcp__kodadocs__deploy_site` if the user requests it.

5. **Save updated manifest:**
   Call `mcp__kodadocs__save_manifest` to record the API reference generation in the pipeline state. Include metadata:
   ```json
   {
     "api_reference": {
       "framework": "<detected framework>",
       "endpoint_count": <number>,
       "groups": ["<group1>", "<group2>"],
       "auth_type": "<detected auth type>",
       "generated_at": "<ISO timestamp>"
     }
   }
   ```

### Step 12: Save Standalone Output

In addition to (or instead of) doc site integration, save a standalone API reference.

**Default file location:** `docs/api-reference.md`

If the reference is large (more than 50 endpoints), split into multiple files:
- `docs/api-reference/index.md` — overview, auth, error format
- `docs/api-reference/<group>.md` — one file per endpoint group

## Decision Trees

### Framework Detection

```
Does the project have Python files with FastAPI imports?
  YES -> FastAPI path (Step 2)
Does the project have JS/TS files with Express/Hono imports?
  YES -> Express/Hono path (Step 3)
Does the project have Python files with Django REST Framework?
  YES -> Django REST path (Step 4)
Does the project have config/routes.rb (Rails)?
  YES -> Rails path (Step 5)
Does the project expose an OpenAPI/Swagger spec at a known URL?
  YES -> Parse the spec directly (treat like FastAPI path)
None of the above?
  -> Inform user: "Could not detect API framework. Provide the framework name or an OpenAPI spec URL."
```

### OpenAPI Spec Availability

```
Is the API server running?
  YES -> Try fetching /openapi.json, /swagger.json, /api-docs, /docs/json
           Found? -> Use the spec as the primary source (most complete data)
           Not found? -> Fall back to static analysis
  NO  -> Does a static OpenAPI spec file exist? (openapi.json, openapi.yaml, swagger.json)
           YES -> Parse the file directly
           NO  -> Use static code analysis only
```

### Authentication Documentation

```
Are auth middleware or decorators present?
  YES -> Identify the auth type(s) from the signals table
         Document each scheme with examples
  NO  -> Are any endpoints public (no auth check)?
           ALL public -> Note: "This API does not require authentication"
           MIXED      -> Something was missed; scan more carefully
           NONE found -> Default to noting: "Authentication requirements could not be determined"
```

### Request Body Extraction

```
Does the endpoint have a validation schema (Zod, Pydantic, Serializer)?
  YES -> Parse the schema for exact field types and requirements
Does the handler access request body fields directly?
  YES -> Infer fields from property access (less precise, note limitations)
Does the OpenAPI spec include a requestBody?
  YES -> Use the spec (highest accuracy)
NONE of the above?
  -> Mark request body as "Not documented" and flag for manual review
```

### Response Schema Extraction

```
Does the OpenAPI spec define response schemas?
  YES -> Use the spec
Does the endpoint use a serializer or response model?
  YES -> Parse the model for field types
Does the handler call res.json() or render json: with a known structure?
  YES -> Infer the response shape from the argument
NONE of the above?
  -> Mark response as "Response schema not available" and flag for review
```

### Large API Handling

```
More than 50 endpoints detected?
  YES -> Split into multiple pages by group
         Generate a table of contents page
         Warn: "Large API detected. Consider organizing endpoints into versioned groups."
  NO  -> Single page is acceptable if under 30 endpoints
         Between 30-50: ask user preference (single page vs. multi-page)
```

## Output Format

The skill produces:

1. **API reference markdown** (`docs/api-reference.md` or split across multiple files) - Complete endpoint documentation
2. **Doc site pages** (optional) - Integrated into the KodaDocs VitePress site as `/api-reference/`
3. **Console summary:**

```
API Reference generated:
  Framework: FastAPI
  Source: OpenAPI spec (live server)
  Endpoints documented: 24
  Groups: Authentication (3), Users (5), Projects (6), Tasks (8), Webhooks (2)
  Authentication: Bearer Token (JWT)
  curl examples: 24
  Saved to:
    - docs/api-reference/index.md
    - docs/api-reference/authentication.md
    - docs/api-reference/users.md
    - docs/api-reference/projects.md
    - docs/api-reference/tasks.md
    - docs/api-reference/webhooks.md
```

## Error Handling

### No API endpoints found
If no routes or endpoints are detected in the codebase:
- Check whether the project is actually an API (it may be a frontend-only project)
- Inform the user: "No API endpoints found. Is this project a REST API? Specify the framework or provide an OpenAPI spec URL."
- Do not generate an empty API reference

### OpenAPI spec is malformed
If the fetched or local OpenAPI spec fails to parse:
- Log: "OpenAPI spec found but could not be parsed. Falling back to static code analysis."
- Continue with the code-scanning path for the detected framework
- If static analysis also fails, stop and report

### Partial schema information
If some endpoints have full schemas but others do not:
- Document the endpoints with full data completely
- For endpoints with partial data, include what is available and add a note: "[Schema incomplete — verify against source code]"
- Never invent or hallucinate schema fields

### Multiple API versions
If the codebase contains versioned APIs (e.g., `/v1/`, `/v2/`):
- Ask the user which version to document
- If the user says "all", generate separate sections per version
- Note deprecated endpoints if `/v1/` routes are marked as such

### Server not reachable
If the server is expected to be running but does not respond:
- Log: "Could not reach the API server at [URL]. Proceeding with static analysis only."
- Continue with code parsing
- Note in the output that live validation was not performed

### Complex authentication flows
If the API uses OAuth 2.0 with multiple grant types:
- Document each grant type as a separate subsection
- Include the full flow (authorization URL, token exchange, refresh)
- Provide curl examples for each step of the flow
- If scopes are used, list all available scopes and their meanings

### Framework not supported
If the detected framework is not in the supported list:
- Attempt generic route scanning (look for HTTP method strings and URL patterns)
- If an OpenAPI spec exists, use that regardless of framework
- If nothing works, ask the user to provide an OpenAPI spec file or URL

### Endpoints behind feature flags
If some endpoints are conditionally registered (behind environment checks or feature flags):
- Include them in the reference with a note: "[Available when FEATURE_FLAG is enabled]"
- Group them separately if there are many

## Success Criteria

The run is successful when:
- [ ] API framework was correctly detected (or user specified)
- [ ] All endpoints were discovered and documented
- [ ] Each endpoint includes: method, path, description, parameters, request body, response, and curl example
- [ ] Authentication scheme was identified and documented with examples
- [ ] Endpoints are grouped by resource or tag in logical order
- [ ] curl examples use realistic sample data and correct headers
- [ ] Error responses are documented for each endpoint where known
- [ ] API overview includes base URL, error format, and common status codes
- [ ] Files were saved to the correct locations
- [ ] If doc site integration: API reference pages were added and site reassembled
- [ ] Console summary was printed with endpoint statistics
