Skip to main content

Overview

The Docs member type automatically generates and serves beautiful, interactive API documentation for your Conductor project. Choose from multiple UI frameworks and let Conductor scan your ensembles and members to create a complete OpenAPI specification. Key Features:
  • 📚 Auto-Generation - Scans ensembles/members to build OpenAPI spec
  • 🎨 Multiple UIs - Stoplight, Redoc, Swagger, Scalar, or RapiDoc
  • 🤖 AI Enhancement - Use AI to generate better descriptions
  • 🔒 Auth Support - Document API keys, OAuth flows
  • Edge Caching - Fast docs delivery with configurable TTL
  • 🎯 Multiple Formats - Serve YAML, JSON, and interactive HTML

Quick Start

Simplest Setup (New in v1.1!)

Create a docs member at members/api-docs.yaml:
name: api-docs
type: docs
description: Public API documentation

# Simplest routing - uses file location as route
route: default  # Auto-resolves to /api-docs
That’s it! Your docs are now available at /api-docs with default settings.

Public Documentation

For public API docs accessible to everyone:
name: api-docs
type: docs
description: Public API documentation

# Route configuration
route:
  path: /docs  # Or use 'default' for /api-docs
  methods: [GET]
  auth:
    requirement: public  # No authentication required

# UI framework
ui: stoplight

# Auto-generate from your project
autoGenerate:
  enabled: true
  useAI: true  # Optional: AI-enhanced descriptions
  aiMember: docs-writer

# Caching (uses Cloudflare KV)
cache:
  enabled: true
  ttl: 3600  # 1 hour
Your docs are now available at:
  • /docs - Interactive documentation
  • /docs/openapi.yaml - OpenAPI spec (YAML)
  • /docs/openapi.json - OpenAPI spec (JSON)

Authenticated Documentation

For internal API docs that require authentication:
name: internal-docs
type: docs
description: Internal API documentation

# Route with authentication
route:
  path: /docs/internal
  methods: [GET]
  auth:
    requirement: required
    methods: [bearer, apiKey]  # Accept bearer tokens or API keys

# UI framework
ui: scalar  # Scalar works great with auth

# Auto-generate
autoGenerate:
  enabled: true
  include:
    - /api/*
    - /api/internal/*

# Caching
cache:
  enabled: true
  ttl: 1800  # 30 minutes
When authenticated, users see a “Try It” button to test APIs directly from docs!

Admin-Only Documentation

For sensitive admin endpoints with role-based access:
name: admin-docs
type: docs
description: Admin-only API documentation

# Route with role requirements
route:
  path: /docs/admin
  methods: [GET]
  auth:
    requirement: required
    methods: [bearer, apiKey, cookie]
    roles: [admin]  # Only admin users
    onFailure:
      action: page  # Show custom error page
      page: error-403
  priority: 10  # Higher priority route

# UI framework
ui: redoc

# Auto-generate
autoGenerate:
  enabled: true
  include:
    - /api/admin/*

# Caching
cache:
  enabled: true
  ttl: 600  # 10 minutes

UI Frameworks

Modern, feature-rich UI with excellent UX:
config:
  ui: stoplight

  branding:
    logo: /assets/logo.png
    primaryColor: "#667eea"

Redoc

Clean, three-panel layout:
config:
  ui: redoc

  branding:
    primaryColor: "#2196f3"

Swagger UI

Classic Swagger interface:
config:
  ui: swagger

Scalar

Modern, fast, and beautiful:
config:
  ui: scalar

  branding:
    theme: purple

RapiDoc

Highly customizable:
config:
  ui: rapidoc

  branding:
    primaryColor: "#ff5722"

Auto-Generation

Enable Auto-Generation

Let Conductor scan your project:
config:
  autoGenerate:
    enabled: true
    exclude:
      - /examples/*
      - /_*
    include:
      - /api/*

AI-Enhanced Descriptions

Use AI to generate better documentation:
config:
  autoGenerate:
    enabled: true
    useAI: true
    aiMember: docs-writer  # Your AI member for enhancement
The AI will:
  • Generate clear descriptions for endpoints
  • Add example requests/responses
  • Improve parameter documentation
  • Suggest best practices

Branding & Customization

Complete Branding

config:
  branding:
    title: "Acme Corp API"
    description: "Complete API reference for Acme services"
    logo: /assets/logo.png
    favicon: /assets/favicon.ico
    primaryColor: "#667eea"

    customCss: |
      .custom-header {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 2rem;
      }

      .custom-header h1 {
        margin: 0;
        font-size: 2rem;
      }

Custom Styling

Add your own CSS to match your brand:
config:
  branding:
    customCss: |
      /* Override default styles */
      :root {
        --primary-color: #667eea;
        --secondary-color: #764ba2;
      }

      .api-docs-header {
        background: var(--primary-color);
      }

Server Configuration

Multiple Environments

Document different environments:
config:
  servers:
    - url: https://api.example.com
      description: Production

    - url: https://staging-api.example.com
      description: Staging

    - url: http://localhost:8787
      description: Local development

Base Path

Set a base path for all endpoints:
config:
  basePath: /api/v1

Route Authentication (New in v1.1!)

The Docs member now integrates with Conductor’s UnifiedRouter for powerful authentication and routing capabilities.

Public Documentation (No Auth)

route:
  path: /docs
  auth:
    requirement: public
Perfect for:
  • Public API documentation
  • Open-source project docs
  • Marketing/developer portal

Optional Authentication

route:
  path: /docs
  auth:
    requirement: optional
    methods: [bearer, apiKey]
Benefits:
  • Non-authenticated users can browse docs
  • Authenticated users see “Try It” button
  • Great for freemium APIs

Required Authentication

route:
  path: /docs/internal
  auth:
    requirement: required
    methods: [bearer, apiKey, cookie]
Use cases:
  • Internal API documentation
  • Partner API docs
  • Private beta documentation

Role-Based Access

route:
  path: /docs/admin
  auth:
    requirement: required
    methods: [bearer, cookie]
    roles: [admin, developer]  # Multiple roles allowed

Permission-Based Access

route:
  path: /docs/billing
  auth:
    requirement: required
    permissions: [billing:read, api:admin]

Custom Failure Handling

Redirect to login:
route:
  auth:
    requirement: required
    methods: [cookie]
    onFailure:
      action: redirect
      redirectTo: /login
      preserveReturn: true  # Redirect back after login
Show custom error page:
route:
  auth:
    requirement: required
    roles: [admin]
    onFailure:
      action: page
      page: error-403
      context:
        message: "Admin access required"

Rate Limiting

Protect your docs from abuse:
route:
  auth:
    requirement: public
    rateLimit:
      requests: 100  # Max requests
      window: 60     # Per 60 seconds
      keyBy: ip      # Rate limit by IP address
Options for keyBy:
  • ip - Limit by IP address (public routes)
  • user - Limit by authenticated user ID
  • apiKey - Limit by API key

Stealth Mode

Return 404 instead of 401 for hidden endpoints:
route:
  auth:
    requirement: required
    methods: [bearer]
    stealthMode: true  # Returns 404 if unauthorized

Default Route Resolution

Use default to auto-resolve route from file location:
# File: members/api-docs.yaml
route: default  # Auto-resolves to /api-docs

# File: members/docs/internal/api-docs.yaml
route: default  # Auto-resolves to /docs/internal/api-docs

Authentication Methods

Supported methods:
  • bearer - JWT Bearer tokens
  • apiKey - API keys (from KV)
  • cookie - Session cookies (from KV)
  • unkey - Unkey.dev integration
  • custom - Custom validators (webhooks, etc.)
Example with multiple methods:
route:
  auth:
    requirement: required
    methods: [bearer, apiKey, unkey]  # Try each method

Complete Routing Example

name: api-docs
type: docs
description: Complete API documentation with advanced routing

# Route configuration
route:
  path: /docs
  methods: [GET]
  auth:
    requirement: optional  # Browse without auth, test with auth
    methods: [bearer, apiKey, cookie]
    onFailure:
      action: redirect
      redirectTo: /login
      preserveReturn: true
    rateLimit:
      requests: 200
      window: 60
      keyBy: ip
  priority: 70  # Default for docs

# UI and content configuration
ui: stoplight
openApiVersion: '3.1'

# Auto-generation
autoGenerate:
  enabled: true
  useAI: true
  aiMember: docs-writer
  exclude:
    - /internal/*
    - /_*

# Branding
branding:
  title: "My API Documentation"
  primaryColor: "#667eea"

# Caching (stored in KV)
cache:
  enabled: true
  ttl: 3600

Caching

Enable Caching

Speed up docs delivery:
config:
  cache:
    enabled: true
    ttl: 300  # 5 minutes
When to cache:
  • ✅ Production docs (TTL: 3600)
  • ✅ Stable APIs (TTL: 600)
  • ❌ Development (disabled)
  • ❌ Frequently changing APIs (TTL: 60)

Custom OpenAPI Spec

Provide Your Own Spec

Instead of auto-generation:
config:
  autoGenerate:
    enabled: false

  customSpec: |
    openapi: 3.1.0
    info:
      title: My API
      version: 1.0.0
    paths:
      /users:
        get:
          summary: List users
          responses:
            '200':
              description: Success

Load from File

config:
  customSpec: ${readFile('./openapi.yaml')}

Integration

Add to Worker

In your src/index.ts:
import { DocsMember } from '@ensemble-edge/conductor/members/docs';
import apiDocsConfig from '../members/api-docs/member.yaml';

const docsMember = new DocsMember(apiDocsConfig);

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext) {
    const url = new URL(request.url);

    // Serve docs
    if (url.pathname.startsWith('/docs') ||
        url.pathname.startsWith('/openapi')) {
      const result = await docsMember.execute({
        input: { request: { url: request.url, method: request.method, headers: {} } },
        env,
        ctx,
        state: {},
        previousOutputs: {},
        memberName: 'api-docs'
      });

      if (result.success) {
        return new Response(result.output.content, {
          status: result.output.status,
          headers: {
            'content-type': result.output.contentType,
            ...result.output.headers
          }
        });
      }
    }

    // Other routes...
  }
};

Complete Example

A production-ready docs member:
name: api-docs
type: Docs
description: Production API documentation with AI enhancement

config:
  # UI Framework
  ui: stoplight

  # OpenAPI Version
  openApiVersion: "3.1"

  # Paths
  paths:
    docs: /docs
    yaml: /openapi.yaml
    json: /openapi.json

  # Auto-generate with AI
  autoGenerate:
    enabled: true
    useAI: true
    aiMember: docs-writer
    exclude:
      - /examples/*
      - /_*
      - /internal/*
    include:
      - /api/*

  # Branding
  branding:
    title: "Acme Corp API"
    description: "Complete API reference for Acme services"
    logo: https://acme.com/logo.png
    favicon: https://acme.com/favicon.ico
    primaryColor: "#667eea"

    customCss: |
      .docs-header {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        padding: 3rem;
        color: white;
      }

  # Authentication
  auth:
    required: optional
    apiKeyLocations: [header]
    oauthFlows: [authorizationCode]

  # Caching
  cache:
    enabled: true
    ttl: 600  # 10 minutes

  # Servers
  servers:
    - url: https://api.acme.com
      description: Production

    - url: https://staging-api.acme.com
      description: Staging

    - url: http://localhost:8787
      description: Local development

  # Base path
  basePath: /api/v1

# Input (auto-populated by worker)
input:
  request:
    url: https://api.acme.com/docs
    method: GET
    headers:
      accept: text/html

Best Practices

1. Use AI Enhancement for Better Docs

config:
  autoGenerate:
    useAI: true
    aiMember: docs-writer
AI generates human-readable descriptions automatically.

2. Cache Appropriately

config:
  cache:
    enabled: true
    ttl: 600  # 10 minutes for active development

3. Exclude Internal Endpoints

config:
  autoGenerate:
    exclude:
      - /internal/*
      - /_*
      - /admin/*

4. Brand Your Docs

Match your company’s branding:
config:
  branding:
    title: "Your Company API"
    logo: /assets/logo.png
    primaryColor: "#your-brand-color"

5. Document Multiple Environments

config:
  servers:
    - url: https://api.prod.com
      description: Production
    - url: https://api.staging.com
      description: Staging

Configuration Reference

UI Options

  • stoplight - Stoplight Elements (recommended)
  • redoc - Redoc
  • swagger - Swagger UI
  • scalar - Scalar
  • rapidoc - RapiDoc

Paths Config

paths:
  docs: string      # Interactive docs path
  yaml: string      # YAML spec path
  json: string      # JSON spec path

Auto-Generate Config

autoGenerate:
  enabled: boolean
  useAI: boolean
  aiMember: string
  exclude: string[]
  include: string[]

Branding Config

branding:
  title: string
  description: string
  logo: string
  favicon: string
  primaryColor: string
  customCss: string

Auth Config

auth:
  required: 'none' | 'optional' | 'required'
  apiKeyLocations: ('header' | 'query' | 'cookie')[]
  oauthFlows: string[]

Cache Config

cache:
  enabled: boolean
  ttl: number  # seconds