Skip to main content

API Documentation Recipes

Comprehensive patterns for creating and maintaining API documentation in GISE methodology. Learn to create living documentation that stays current with your code.

OpenAPI Specification

Complete API Documentation Template

Use When: Documenting REST APIs with comprehensive specifications

openapi: 3.0.3
info:
title: Project Management API
description: |
RESTful API for project management system built with GISE methodology.

## Authentication
All endpoints require JWT authentication unless otherwise specified.
Include the token in the Authorization header: `Bearer <token>`

## Rate Limiting
API requests are limited to 1000 requests per hour per user.

## Error Handling
All errors follow RFC 7807 Problem Details format.
version: 1.0.0
contact:
name: API Support
url: https://example.com/support
email: api-support@example.com
license:
name: MIT
url: https://opensource.org/licenses/MIT

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

paths:
/auth/login:
post:
summary: Authenticate user
description: Authenticate user credentials and return JWT token
tags:
- Authentication
security: [] # No authentication required for login
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LoginRequest'
example:
email: john.doe@example.com
password: securepassword123
responses:
'200':
description: Authentication successful
content:
application/json:
schema:
$ref: '#/components/schemas/AuthResponse'
example:
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
user:
id: 123e4567-e89b-12d3-a456-426614174000
email: john.doe@example.com
name: John Doe
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/TooManyRequests'

/projects:
get:
summary: List user projects
description: Retrieve a paginated list of projects owned by the authenticated user
tags:
- Projects
parameters:
- $ref: '#/components/parameters/PageParam'
- $ref: '#/components/parameters/LimitParam'
- name: search
in: query
description: Search projects by name or description
required: false
schema:
type: string
maxLength: 100
- name: status
in: query
description: Filter projects by status
required: false
schema:
type: string
enum: [draft, active, completed, archived]
responses:
'200':
description: Projects retrieved successfully
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Project'
meta:
$ref: '#/components/schemas/PaginationMeta'
example:
data:
- id: 123e4567-e89b-12d3-a456-426614174000
name: E-commerce Platform
description: Modern e-commerce solution
status: active
owner_id: 789e4567-e89b-12d3-a456-426614174000
created_at: '2024-01-15T10:00:00Z'
updated_at: '2024-01-20T14:30:00Z'
meta:
page: 1
limit: 20
total: 45
total_pages: 3
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'

post:
summary: Create new project
description: Create a new project with the provided information
tags:
- Projects
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateProjectRequest'
example:
name: Mobile App Development
description: iOS and Android mobile application
status: draft
responses:
'201':
description: Project created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Project'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'409':
$ref: '#/components/responses/Conflict'

/projects/{projectId}:
get:
summary: Get project details
description: Retrieve detailed information about a specific project
tags:
- Projects
parameters:
- $ref: '#/components/parameters/ProjectIdParam'
responses:
'200':
description: Project details retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectDetails'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'

put:
summary: Update project
description: Update project information
tags:
- Projects
parameters:
- $ref: '#/components/parameters/ProjectIdParam'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateProjectRequest'
responses:
'200':
description: Project updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Project'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'

delete:
summary: Delete project
description: Permanently delete a project and all associated data
tags:
- Projects
parameters:
- $ref: '#/components/parameters/ProjectIdParam'
responses:
'204':
description: Project deleted successfully
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'

components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT

parameters:
ProjectIdParam:
name: projectId
in: path
required: true
description: Unique identifier for the project
schema:
type: string
format: uuid
example: 123e4567-e89b-12d3-a456-426614174000

PageParam:
name: page
in: query
description: Page number for pagination (1-based)
required: false
schema:
type: integer
minimum: 1
default: 1

LimitParam:
name: limit
in: query
description: Number of items per page
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20

schemas:
User:
type: object
required: [id, email, name, created_at]
properties:
id:
type: string
format: uuid
description: Unique identifier for the user
email:
type: string
format: email
description: User's email address
name:
type: string
minLength: 2
maxLength: 100
description: User's full name
avatar_url:
type: string
format: uri
nullable: true
description: URL to user's avatar image
created_at:
type: string
format: date-time
description: User account creation timestamp
updated_at:
type: string
format: date-time
description: Last account update timestamp

Project:
type: object
required: [id, name, status, owner_id, created_at, updated_at]
properties:
id:
type: string
format: uuid
description: Unique identifier for the project
name:
type: string
minLength: 1
maxLength: 255
description: Project name
description:
type: string
maxLength: 2000
nullable: true
description: Project description
status:
type: string
enum: [draft, active, completed, archived]
description: Current project status
owner_id:
type: string
format: uuid
description: ID of the project owner
created_at:
type: string
format: date-time
description: Project creation timestamp
updated_at:
type: string
format: date-time
description: Last project update timestamp

ProjectDetails:
allOf:
- $ref: '#/components/schemas/Project'
- type: object
properties:
owner:
$ref: '#/components/schemas/User'
task_count:
type: integer
minimum: 0
description: Number of tasks in the project
team_members:
type: array
items:
$ref: '#/components/schemas/User'
description: List of team members

LoginRequest:
type: object
required: [email, password]
properties:
email:
type: string
format: email
description: User's email address
password:
type: string
minLength: 8
description: User's password

AuthResponse:
type: object
required: [token, user]
properties:
token:
type: string
description: JWT authentication token
user:
$ref: '#/components/schemas/User'

CreateProjectRequest:
type: object
required: [name]
properties:
name:
type: string
minLength: 1
maxLength: 255
description: Project name
description:
type: string
maxLength: 2000
description: Project description
status:
type: string
enum: [draft, active]
default: draft
description: Initial project status

UpdateProjectRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 255
description: Project name
description:
type: string
maxLength: 2000
nullable: true
description: Project description
status:
type: string
enum: [draft, active, completed, archived]
description: Project status

PaginationMeta:
type: object
required: [page, limit, total, total_pages]
properties:
page:
type: integer
minimum: 1
description: Current page number
limit:
type: integer
minimum: 1
description: Number of items per page
total:
type: integer
minimum: 0
description: Total number of items
total_pages:
type: integer
minimum: 0
description: Total number of pages

Error:
type: object
required: [error]
properties:
error:
type: string
description: Error message
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
description: Detailed validation errors

responses:
BadRequest:
description: Bad request - invalid input parameters
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: Validation failed
details:
- field: email
message: Invalid email format

Unauthorized:
description: Unauthorized - authentication required
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: Authentication required

Forbidden:
description: Forbidden - insufficient permissions
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: Insufficient permissions

NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: Resource not found

Conflict:
description: Conflict - resource already exists
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: Email already exists

TooManyRequests:
description: Too many requests - rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: Rate limit exceeded

security:
- BearerAuth: []

tags:
- name: Authentication
description: User authentication endpoints
- name: Projects
description: Project management endpoints
- name: Users
description: User management endpoints

Interactive Documentation

Redoc Integration

<!DOCTYPE html>
<html>
<head>
<title>API Documentation</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
<style>
body { margin: 0; padding: 0; }
</style>
</head>
<body>
<redoc spec-url='./openapi.yaml'></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@2.0.0/bundles/redoc.standalone.js"></script>
</body>
</html>

Code Examples Integration

SDK Code Samples

JavaScript/TypeScript:

// Auto-generated SDK usage examples
import { ProjectAPI } from '@company/api-client';

const api = new ProjectAPI({
baseURL: 'https://api.example.com/v1',
apiKey: 'your-api-key'
});

// Create a new project
const project = await api.projects.create({
name: 'My New Project',
description: 'Project description',
status: 'draft'
});

// List projects with filtering
const projects = await api.projects.list({
page: 1,
limit: 20,
status: 'active',
search: 'ecommerce'
});

// Error handling
try {
const project = await api.projects.get('invalid-id');
} catch (error) {
if (error.status === 404) {
console.log('Project not found');
} else if (error.status === 401) {
console.log('Authentication required');
}
}

Python:

from company_api import ProjectAPI
from company_api.exceptions import NotFoundError, AuthenticationError

# Initialize client
api = ProjectAPI(
base_url="https://api.example.com/v1",
api_key="your-api-key"
)

# Create project
project = api.projects.create(
name="My New Project",
description="Project description",
status="draft"
)

# List with filtering
projects = api.projects.list(
page=1,
limit=20,
status="active",
search="ecommerce"
)

# Error handling
try:
project = api.projects.get("invalid-id")
except NotFoundError:
print("Project not found")
except AuthenticationError:
print("Authentication required")

cURL:

# Authentication
curl -X POST https://api.example.com/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password"
}'

# Create project
curl -X POST https://api.example.com/v1/projects \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "My New Project",
"description": "Project description",
"status": "draft"
}'

# List projects
curl -X GET "https://api.example.com/v1/projects?page=1&limit=20&status=active" \
-H "Authorization: Bearer <token>"

AI-Generated Documentation

Documentation Generation Prompts

API Endpoint Documentation:

Generate comprehensive OpenAPI 3.0 documentation for the following API endpoint:

[PASTE ENDPOINT CODE]

Requirements:
- Include detailed descriptions for all parameters
- Provide realistic examples for requests and responses
- Document all possible error responses
- Include proper data validation schemas
- Add security requirements
- Use consistent naming conventions
- Include deprecation notices if applicable

Format: OpenAPI 3.0 YAML specification

SDK Usage Examples:

Create SDK usage examples for the following API endpoints in JavaScript, Python, and cURL:

[PASTE OPENAPI SPEC]

Requirements:
- Show common use cases and workflows
- Include proper error handling
- Demonstrate authentication
- Use realistic example data
- Show both synchronous and asynchronous patterns where applicable
- Include comments explaining key concepts

Documentation Automation

GitHub Actions for Documentation

name: API Documentation

on:
push:
paths:
- 'src/routes/**'
- 'openapi.yaml'
branches: [main, develop]

jobs:
generate-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Generate OpenAPI spec from code
run: npm run generate:openapi

- name: Validate OpenAPI spec
run: npx @apidevtools/swagger-cli validate openapi.yaml

- name: Generate SDK clients
run: |
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-fetch \
-o ./clients/typescript

npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml \
-g python \
-o ./clients/python

- name: Build documentation site
run: |
mkdir -p docs
npx redoc-cli build openapi.yaml --output docs/index.html

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/main'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs

Automated Testing

// API documentation testing
import { validateApiSpec } from './helpers/openapi-validator';
import { testApiEndpoints } from './helpers/endpoint-tester';

describe('API Documentation', () => {
it('should have valid OpenAPI specification', async () => {
const spec = await validateApiSpec('./openapi.yaml');
expect(spec.errors).toHaveLength(0);
});

it('should have examples that work with actual API', async () => {
const results = await testApiEndpoints({
baseUrl: process.env.API_BASE_URL,
authToken: process.env.API_AUTH_TOKEN
});

expect(results.failedTests).toHaveLength(0);
});

it('should have up-to-date schema definitions', async () => {
// Compare generated schema with actual API responses
const schemaValidation = await validateSchemaAgainstAPI();
expect(schemaValidation.isValid).toBe(true);
});
});

Documentation Best Practices

Writing Guidelines

Clear Descriptions:

  • Start with a verb for operation summaries
  • Explain the business purpose, not just technical details
  • Include context about when to use each endpoint
  • Provide realistic use case scenarios

Consistent Structure:

  • Use consistent parameter and response naming
  • Follow RESTful conventions for HTTP methods
  • Group related endpoints with tags
  • Maintain consistent error response format

Developer Experience:

  • Include working code examples
  • Provide authentication setup instructions
  • Document rate limits and pagination
  • Explain error handling patterns

Versioning Strategy

# API versioning in OpenAPI
openapi: 3.0.3
info:
title: Project Management API
version: 2.1.0

servers:
- url: https://api.example.com/v2
description: Current version (v2)
- url: https://api.example.com/v1
description: Legacy version (v1) - deprecated

paths:
/projects:
get:
summary: List projects
deprecated: false
# Current implementation

/legacy/projects:
get:
summary: List projects (legacy)
deprecated: true
description: |
**DEPRECATED**: This endpoint is deprecated and will be removed in v3.0.0.
Use `/projects` instead.

Next: Database Design Recipes | API Testing Patterns

Great API documentation is the bridge between your implementation and your users' success.