Skip to main content
โšก Calmops

API Documentation with OpenAPI: Complete Guide 2026

Introduction

Good documentation is crucial for API adoption. OpenAPI (formerly Swagger) provides a standard way to describe your API, enabling auto-generated documentation, SDKs, and client libraries. This guide covers creating and maintaining OpenAPI specs.


OpenAPI Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 OpenAPI Benefits                               โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                             โ”‚
โ”‚  ๐Ÿ“ Documentation                                           โ”‚
โ”‚     โ€ข Auto-generated interactive docs                      โ”‚
โ”‚     โ€ข Always in sync with code                             โ”‚
โ”‚                                                             โ”‚
โ”‚  ๐Ÿ”Œ Client SDKs                                            โ”‚
โ”‚     โ€ข Generate 40+ languages                               โ”‚
โ”‚     โ€ข Type-safe bindings                                   โ”‚
โ”‚                                                             โ”‚
โ”‚  โš™๏ธ Server Stubs                                           โ”‚
โ”‚     โ€ข Quick API prototyping                                โ”‚
โ”‚     โ€ข Multiple language support                             โ”‚
โ”‚                                                             โ”‚
โ”‚  โœ… Validation                                             โ”‚
โ”‚     โ€ข Request/response validation                          โ”‚
โ”‚     โ€ข Contract testing                                     โ”‚
โ”‚                                                             โ”‚
โ”‚  ๐Ÿ”’ Security                                               โ”‚
โ”‚     โ€ข Auth scheme definitions                             โ”‚
โ”‚     โ€ข OAuth flows                                          โ”‚
โ”‚                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

OpenAPI Document Structure

Basic Structure

# openapi.yaml
openapi: 3.1.0
info:
  title: User Management API
  description: API for managing users and permissions
  version: 1.0.0
  contact:
    name: API Support
    email: [email protected]

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

paths:
  /users:
    get:
      summary: List all users
      operationId: listUsers
      tags:
        - Users
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Users'

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        email:
          type: string
          format: email

Defining Schemas

Object Schemas

components:
  schemas:
    User:
      type: object
      required:
        - name
        - email
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
        name:
          type: string
          minLength: 1
          maxLength: 100
        email:
          type: string
          format: email
        role:
          type: string
          enum: [admin, user, guest]
        createdAt:
          type: string
          format: date-time
    
    Error:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
        details:
          type: array
          items:
            type: string

Reusing Schemas

components:
  schemas:
    # Inheritance with allOf
    AdminUser:
      allOf:
        - $ref: '#/components/schemas/User'
        - type: object
          properties:
            permissions:
              type: array
              items:
                type: string
    
    # Partial schemas (JSON:API style)
    UserSummary:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
    
    # Array of users
    Users:
      type: array
      items:
        $ref: '#/components/schemas/User'

Documenting Endpoints

GET Endpoint

paths:
  /users/{userId}:
    get:
      summary: Get a user by ID
      description: Returns a single user
      operationId: getUserById
      tags:
        - Users
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The user's unique identifier
        - name: include
          in: query
          schema:
            type: array
            items:
              type: string
              enum: [posts, comments]
          description: Related resources to include
      responses:
        '200':
          description: User found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          description: User not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

POST Endpoint

paths:
  /users:
    post:
      summary: Create a new user
      operationId: createUser
      tags:
        - Users
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - email
                - password
              properties:
                name:
                  type: string
                email:
                  type: string
                password:
                  type: string
                  minLength: 8
                role:
                  type: string
                  default: user
      responses:
        '201':
          description: User created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

Authentication

Security Schemes

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    
    oauth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://example.com/oauth/authorize
          tokenUrl: https://example.com/oauth/token
          scopes:
            read: Read access
            write: Write access

security:
  - bearerAuth: []
  - apiKeyAuth: []

Using Security

paths:
  /users:
    get:
      summary: List users (requires auth)
      security:
        - bearerAuth: []
        - apiKeyAuth: []
      # ...

Code Generation

Install OpenAPI Generator

# Install generator
npm install @openapitools/openapi-generator-cli

# Generate TypeScript client
npx openapi-generator-cli generate \
  -i openapi.yaml \
  -g typescript-axios \
  -o ./src/api/client

# Generate Python client
npx openapi-generator-cli generate \
  -i openapi.yaml \
  -g python \
  -o ./python_client

# Generate server stubs (Express)
npx openapi-generator-cli generate \
  -i openapi.yaml \
  -g express-server \
  -o ./server

Using Generated Client

// Generated client usage
import { UsersApi, Configuration } from './api/client';

const config = new Configuration({
  basePath: 'https://api.example.com',
  accessToken: 'your-token',
});

const usersApi = new UsersApi(config);

// Fully typed!
const users = await usersApi.listUsers({ limit: 10 });
console.log(users.data);

Interactive Documentation

Swagger UI

// Express with Swagger UI
import swaggerUi from 'swagger-ui-express';
import swaggerJsdoc from 'swagger-jsdoc';

const specs = swaggerJsdoc({
  definition: {
    openapi: '3.0.0',
    info: { title: 'My API', version: '1.0.0' },
    paths: {}, // Your routes
  },
  apis: ['./routes/*.js'],
});

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

ReDoc

# Or use ReDoc (alternative)
# npm install redoc express

app.get('/docs', (req, res) => {
  res.send(`
    <redoc 
      spec-url='/openapi.yaml'
    ></redoc>
    <script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script>
  `);
});

Key Takeaways

  • Start with OpenAPI - Design-first approach
  • Keep it in sync - Generate from code or vice versa
  • Use $ref - Reuse schemas to avoid duplication
  • Document everything - Descriptions, examples, notes
  • Generate clients - Type-safe SDKs for consumers

External Resources

Comments