Back to skills
SkillHub ClubShip Full StackFull StackBackend

api-documenting

Generate API documentation from code. Use when the user wants to document APIs, create API reference, generate endpoint documentation, or needs help with OpenAPI/Swagger specs.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
253
Hot score
98
Updated
March 20, 2026
Overall rating
C3.2
Composite score
3.2
Best-practice grade
B82.7

Install command

npx @skill-hub/cli install huangjia2019-claude-code-engingeering-02-progressive-skill

Repository

huangjia2019/claude-code-engingeering

Skill path: 04-Skills/projects/02-progressive-skill

Generate API documentation from code. Use when the user wants to document APIs, create API reference, generate endpoint documentation, or needs help with OpenAPI/Swagger specs.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack, Backend.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: huangjia2019.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install api-documenting into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/huangjia2019/claude-code-engingeering before adding api-documenting to shared team environments
  • Use api-documenting for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: api-documenting
description: Generate API documentation from code. Use when the user wants to document APIs, create API reference, generate endpoint documentation, or needs help with OpenAPI/Swagger specs.
allowed-tools:
  - Read
  - Grep
  - Glob
  - Write
---

# API Documentation Generator

Generate comprehensive API documentation from source code.

## Quick Reference

For common documentation patterns, see `PATTERNS.md`.

## Documentation Standards

See `STANDARDS.md` for our documentation conventions.

## Process

### Step 1: Identify API Endpoints

Look for:
- Route definitions (Express, FastAPI, etc.)
- Controller methods
- Handler functions

### Step 2: Extract Information

For each endpoint, extract:
- HTTP method (GET, POST, PUT, DELETE, etc.)
- Path/route
- Parameters (path, query, body)
- Request/response schemas
- Authentication requirements

### Step 3: Generate Documentation

Use the template in `templates/endpoint.md` for consistent formatting.

### Step 4: Create Overview

Generate an index of all endpoints with the template in `templates/index.md`.

## Output Formats

### Markdown (Default)
Generate markdown documentation suitable for README or docs site.

### OpenAPI/Swagger
If requested, generate OpenAPI 3.0 spec. See `templates/openapi.yaml` for structure.

## Examples

See `EXAMPLES.md` for sample inputs and outputs.

## Scripts

To auto-detect routes in common frameworks:
```bash
python scripts/detect_routes.py <source_directory>
```

To validate generated OpenAPI spec:
```bash
./scripts/validate_openapi.sh <spec_file>
```


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/detect_routes.py

```python
#!/usr/bin/env python3
"""
Route Detection Script

Automatically detects API routes in common web frameworks.
Supports: Express.js, FastAPI, Flask, Spring Boot, Go (Gin/Echo)

Usage:
    python detect_routes.py <source_directory>

Output:
    JSON list of detected routes with metadata
"""

import os
import re
import sys
import json
from pathlib import Path

# Route patterns for different frameworks
PATTERNS = {
    'express': [
        # app.get('/path', handler)
        r"app\.(get|post|put|delete|patch)\s*\(\s*['\"]([^'\"]+)['\"]",
        # router.get('/path', handler)
        r"router\.(get|post|put|delete|patch)\s*\(\s*['\"]([^'\"]+)['\"]",
    ],
    'fastapi': [
        # @app.get("/path")
        r"@app\.(get|post|put|delete|patch)\s*\(\s*['\"]([^'\"]+)['\"]",
        # @router.get("/path")
        r"@router\.(get|post|put|delete|patch)\s*\(\s*['\"]([^'\"]+)['\"]",
    ],
    'flask': [
        # @app.route('/path', methods=['GET'])
        r"@app\.route\s*\(\s*['\"]([^'\"]+)['\"].*?methods\s*=\s*\[([^\]]+)\]",
        # @blueprint.route('/path')
        r"@\w+\.route\s*\(\s*['\"]([^'\"]+)['\"]",
    ],
    'spring': [
        # @GetMapping("/path")
        r"@(Get|Post|Put|Delete|Patch)Mapping\s*\(\s*['\"]?([^'\")\s]+)",
        # @RequestMapping(value="/path", method=...)
        r"@RequestMapping\s*\([^)]*value\s*=\s*['\"]([^'\"]+)['\"]",
    ],
    'go_gin': [
        # r.GET("/path", handler)
        r"\w+\.(GET|POST|PUT|DELETE|PATCH)\s*\(\s*['\"]([^'\"]+)['\"]",
    ],
}

def detect_framework(content: str) -> str:
    """Detect which framework is being used based on imports/requires."""
    if 'express' in content.lower() or "require('express')" in content:
        return 'express'
    elif 'fastapi' in content.lower() or 'from fastapi' in content:
        return 'fastapi'
    elif 'flask' in content.lower() or 'from flask' in content:
        return 'flask'
    elif '@RestController' in content or '@RequestMapping' in content:
        return 'spring'
    elif 'gin.Default()' in content or 'echo.New()' in content:
        return 'go_gin'
    return None

def extract_routes(file_path: Path) -> list:
    """Extract routes from a single file."""
    routes = []

    try:
        content = file_path.read_text()
    except Exception as e:
        print(f"Warning: Could not read {file_path}: {e}", file=sys.stderr)
        return routes

    framework = detect_framework(content)
    if not framework:
        return routes

    patterns = PATTERNS.get(framework, [])

    for pattern in patterns:
        matches = re.finditer(pattern, content, re.IGNORECASE | re.MULTILINE)
        for match in matches:
            groups = match.groups()
            if len(groups) >= 2:
                method = groups[0].upper()
                path = groups[1]
            else:
                method = 'GET'  # Default
                path = groups[0]

            routes.append({
                'method': method,
                'path': path,
                'file': str(file_path),
                'line': content[:match.start()].count('\n') + 1,
                'framework': framework,
            })

    return routes

def scan_directory(directory: str) -> list:
    """Scan a directory for route definitions."""
    all_routes = []

    # File extensions to scan
    extensions = {'.js', '.ts', '.py', '.java', '.go', '.kt'}

    path = Path(directory)
    if not path.exists():
        print(f"Error: Directory {directory} does not exist", file=sys.stderr)
        sys.exit(1)

    for file_path in path.rglob('*'):
        if file_path.suffix in extensions and file_path.is_file():
            # Skip node_modules, venv, etc.
            if any(skip in str(file_path) for skip in ['node_modules', 'venv', '.git', 'dist', 'build']):
                continue

            routes = extract_routes(file_path)
            all_routes.extend(routes)

    return all_routes

def main():
    if len(sys.argv) < 2:
        print("Usage: python detect_routes.py <source_directory>", file=sys.stderr)
        sys.exit(1)

    directory = sys.argv[1]
    routes = scan_directory(directory)

    # Sort by path for readability
    routes.sort(key=lambda r: (r['path'], r['method']))

    # Output as JSON
    print(json.dumps(routes, indent=2))

    # Summary to stderr
    print(f"\nFound {len(routes)} routes in {directory}", file=sys.stderr)

if __name__ == '__main__':
    main()

```

### scripts/validate_openapi.sh

```bash
#!/bin/bash
# OpenAPI Specification Validator
#
# Validates an OpenAPI spec file for correctness.
# Requires: npx (Node.js) or swagger-cli
#
# Usage:
#   ./validate_openapi.sh <spec_file>
#
# Example:
#   ./validate_openapi.sh api-spec.yaml

set -e

SPEC_FILE="$1"

if [ -z "$SPEC_FILE" ]; then
    echo "Usage: $0 <spec_file>"
    echo "Example: $0 api-spec.yaml"
    exit 1
fi

if [ ! -f "$SPEC_FILE" ]; then
    echo "Error: File '$SPEC_FILE' not found"
    exit 1
fi

echo "Validating OpenAPI spec: $SPEC_FILE"
echo "=================================="

# Check if swagger-cli is available
if command -v swagger-cli &> /dev/null; then
    echo "Using swagger-cli..."
    swagger-cli validate "$SPEC_FILE"

# Check if npx is available (Node.js)
elif command -v npx &> /dev/null; then
    echo "Using @apidevtools/swagger-cli via npx..."
    npx @apidevtools/swagger-cli validate "$SPEC_FILE"

# Check if Python spectral is available
elif command -v spectral &> /dev/null; then
    echo "Using Spectral..."
    spectral lint "$SPEC_FILE"

else
    echo "Warning: No OpenAPI validator found."
    echo "Install one of:"
    echo "  - npm install -g @apidevtools/swagger-cli"
    echo "  - npm install -g @stoplight/spectral-cli"
    echo ""
    echo "Performing basic YAML syntax check instead..."

    # Basic YAML check
    if command -v python3 &> /dev/null; then
        python3 -c "import yaml; yaml.safe_load(open('$SPEC_FILE'))" && echo "YAML syntax: OK"
    elif command -v ruby &> /dev/null; then
        ruby -ryaml -e "YAML.load_file('$SPEC_FILE')" && echo "YAML syntax: OK"
    else
        echo "Cannot perform YAML check without Python or Ruby"
        exit 1
    fi
fi

echo ""
echo "Validation complete!"

```

### templates/endpoint.md

```markdown
# Endpoint Documentation Template

Use this template for each API endpoint:

```markdown
## {METHOD} {PATH}

{Brief description of what this endpoint does.}

### Authentication
{Required | Optional | None}

### Parameters

| Name | Location | Type | Required | Description |
|------|----------|------|----------|-------------|
| {name} | {path/query/header/body} | {type} | {Yes/No} | {description} |

### Request Body
{If applicable}

```json
{
  "field": "value"
}
```

### Responses

#### {Status Code} {Status Text}
{Description of when this response occurs}

```json
{
  "example": "response"
}
```

### Example

**Request**:
```bash
curl -X {METHOD} '{BASE_URL}{PATH}' \
  -H 'Content-Type: application/json' \
  -d '{request_body}'
```

**Response**:
```json
{
  "example": "response"
}
```

### Notes
{Any additional information, caveats, or related endpoints}
```

```

### templates/index.md

```markdown
# API Index Template

Use this template for the API overview page:

```markdown
# {API Name} API Reference

{Brief description of the API}

## Base URL
`{BASE_URL}`

## Authentication
{Description of authentication methods}

## Endpoints

### {Resource Group 1}
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /resource | List all resources |
| POST | /resource | Create a resource |
| GET | /resource/:id | Get a specific resource |
| PUT | /resource/:id | Update a resource |
| DELETE | /resource/:id | Delete a resource |

### {Resource Group 2}
| Method | Endpoint | Description |
|--------|----------|-------------|
| ... | ... | ... |

## Common Response Codes

| Code | Description |
|------|-------------|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |

## Rate Limiting
{Rate limiting information if applicable}

## Versioning
{API versioning strategy}
```

```

### templates/openapi.yaml

```yaml
# OpenAPI Template
# Use this as a starting point for generating OpenAPI specs

openapi: 3.0.0

info:
  title: API Title
  description: API description goes here
  version: 1.0.0
  contact:
    name: API Support
    email: [email protected]

servers:
  - url: https://api.example.com/v1
    description: Production server
  - url: https://staging-api.example.com/v1
    description: Staging server

paths:
  /example:
    get:
      summary: Example endpoint
      description: Detailed description of what this endpoint does
      operationId: getExample
      tags:
        - Examples
      parameters:
        - name: id
          in: query
          required: false
          schema:
            type: string
          description: Filter by ID
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Example'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

components:
  schemas:
    Example:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: string
          description: Unique identifier
        name:
          type: string
          description: Resource name
        createdAt:
          type: string
          format: date-time
          description: Creation timestamp

    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Error code
        message:
          type: string
          description: Error message

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

security:
  - bearerAuth: []

tags:
  - name: Examples
    description: Example endpoints

```

api-documenting | SkillHub