Skip to main content

API Documentation: OpenAPI vs AsyncAPI 2026

·APIScout Team
Share:

API Documentation: OpenAPI vs AsyncAPI 2026

Great API documentation is the difference between a 5-minute integration and a 5-hour one. The two dominant standards — OpenAPI for REST APIs and AsyncAPI for event-driven APIs — provide machine-readable specifications that power code generation, testing, and interactive documentation.

TL;DR

  • Every REST API should have an OpenAPI 3.1 spec — it's the source of truth for contracts, SDK generation, and interactive docs
  • AsyncAPI covers what OpenAPI can't: WebSockets, Kafka, MQTT, SSE streams, and webhook schemas
  • TypeSpec (from Microsoft) is the emerging alternative for large API teams who want to generate OpenAPI from code instead of writing YAML
  • Spectral linting + Redocly bundling + Scalar UI is the modern open-source documentation stack
  • "Docs as code" — spec in Git, CI validation, auto-deploy — is table stakes for any API team shipping continuously
  • Breaking change detection with oasdiff in CI prevents accidental contract violations before they reach production

OpenAPI 3.1

What: The standard specification for describing REST APIs. Previously called Swagger.

Format: YAML or JSON file describing endpoints, request/response schemas, authentication, and examples.

What it covers:

  • Endpoints (paths, methods)
  • Request/response schemas (JSON Schema)
  • Authentication methods
  • Parameters (query, path, header, cookie)
  • Request bodies
  • Response codes and shapes
  • Examples

Tools powered by OpenAPI:

  • Swagger UI / Redoc — interactive documentation
  • openapi-generator — SDK generation in 50+ languages
  • Postman — import spec, auto-create collection
  • Prism — mock server from spec
  • Spectral — lint/validate specs

OpenAPI 3.1 improvements (over 3.0):

  • Full JSON Schema compatibility
  • webhooks section for webhook definitions
  • pathItems for reusable path definitions
  • Better oneOf/anyOf/allOf support

When to Use OpenAPI

Always. Every REST API should have an OpenAPI spec. It's the source of truth for your API contract and powers the entire tooling ecosystem.

AsyncAPI

What: The standard specification for describing event-driven APIs — WebSockets, MQTT, Kafka, AMQP, SSE, webhooks.

Format: YAML or JSON file describing channels, messages, schemas, and protocols.

What it covers:

  • Channels (topics, queues, WebSocket endpoints)
  • Messages (publish/subscribe)
  • Message schemas
  • Protocol bindings (Kafka, MQTT, WebSocket, HTTP)
  • Servers (brokers, endpoints)

Tools powered by AsyncAPI:

  • AsyncAPI Studio — visual editor
  • AsyncAPI Generator — code generation
  • AsyncAPI Bundler — combine specs
  • Documentation generators — HTML docs from spec

When to Use AsyncAPI

When your API uses event-driven patterns: WebSocket APIs, message brokers (Kafka, RabbitMQ), webhook definitions, or SSE streams.

Comparison

FeatureOpenAPI 3.1AsyncAPI 3.0
API typeREST (request-response)Event-driven (pub/sub, streaming)
ProtocolsHTTP/HTTPSWebSocket, Kafka, MQTT, AMQP, HTTP
DirectionClient → Server → ClientBidirectional, async
MaturityVery matureGrowing
ToolingExtensiveGrowing
AdoptionIndustry standardEmerging standard

They complement each other. If your API has REST endpoints AND WebSocket channels, use both specs.

Documentation Best Practices

1. Start With a Quick Start

The first thing developers see should be a working example in 5 lines:

## Quick Start

Install the SDK:
npm install your-api

Make your first request:

Three steps: install, authenticate, make a call. Nothing else on the quick start page.

2. Show Real Examples, Not Schemas

Developers copy code, not read schemas. Every endpoint needs a complete, runnable example with a real response.

3. Interactive "Try It" Console

Let developers make API calls from the documentation page. Swagger UI, Redoc, and ReadMe all support this. Seeing a real response builds confidence faster than reading a schema.

4. Error Documentation

Document every error code your API can return, with:

  • The error code
  • When it occurs
  • How to fix it
  • An example response

5. Changelog

Maintain a changelog of API changes. Developers need to know when fields are added, deprecated, or removed.

6. SDKs and Code Examples in Multiple Languages

Show code examples in at least: cURL, JavaScript, Python. Ideally also: Go, Ruby, Java.

7. Authentication Guide

A dedicated page explaining:

  • How to get API keys
  • Where to find them in the dashboard
  • How to include them in requests
  • Common authentication errors

Documentation Platforms

PlatformBest ForPricing
ReadMeInteractive docs with "Try It"Free (1 project)
RedoclyBeautiful OpenAPI docsFree (basic)
MintlifyModern, developer-focused$150/mo
Swagger UISelf-hosted, freeFree (open source)
GitBookMarkdown-based docsFree (personal)
StoplightAPI design + docsFree (basic)

Writing an OpenAPI Spec: A Practical Example

Most developers have seen basic OpenAPI snippets but never a complete spec that covers the realistic patterns. Here's an annotated example for a simple user management endpoint:

openapi: 3.1.0
info:
  title: User Management API
  version: 1.0.0
  description: Manage users and their profiles.

servers:
  - url: https://api.example.com/v1
    description: Production
  - url: https://sandbox.api.example.com/v1
    description: Sandbox

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

  schemas:
    User:
      type: object
      required: [id, name, email, createdAt]
      properties:
        id:
          type: string
          format: uuid
          example: "usr_abc123"
          readOnly: true
        name:
          type: string
          minLength: 1
          maxLength: 100
          example: "Alice Chen"
        email:
          type: string
          format: email
          example: "alice@example.com"
        createdAt:
          type: string
          format: date-time
          readOnly: true

    CreateUserRequest:
      type: object
      required: [name, email]
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 100
        email:
          type: string
          format: email

    Error:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          example: "validation_error"
        message:
          type: string
          example: "Email address is already in use"
        details:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string

    PaginatedUsers:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/User'
        pagination:
          type: object
          properties:
            cursor:
              type: string
              nullable: true
            hasMore:
              type: boolean

security:
  - BearerAuth: []

paths:
  /users:
    get:
      operationId: listUsers
      summary: List users
      tags: [Users]
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
          description: Pagination cursor from previous response
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: Paginated list of users
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedUsers'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      operationId: createUser
      summary: Create a user
      tags: [Users]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserRequest'
            example:
              name: "Alice Chen"
              email: "alice@example.com"
      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'
        '409':
          description: Email already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

Key patterns to notice: readOnly: true on computed fields (id, createdAt), separate CreateUserRequest schema from User response schema, operationId on every operation (required for code generation), and examples at both the schema level and request body level.

OpenAPI Toolchain

Spectral: Linting Your Spec

Spectral validates OpenAPI specs against a set of rules. The built-in ruleset catches common mistakes; custom rules enforce your API style guide:

# .spectral.yaml
extends: ["spectral:oas"]
rules:
  # Require operationId on all operations
  operation-operationId: error

  # Require examples on all response schemas
  response-examples:
    given: $.paths[*][*].responses[*].content[*].schema
    then:
      field: example
      function: defined
    severity: warn

  # Require descriptions on all properties
  property-description:
    given: $.components.schemas[*].properties[*]
    then:
      field: description
      function: defined
    severity: warn

Run Spectral in CI to catch spec violations before merge:

npx @stoplight/spectral-cli lint api.yaml --ruleset .spectral.yaml

Redocly: Multi-File Spec Management

Real API specs grow large — hundreds of paths, dozens of schemas. Redocly bundles multi-file specs into a single deployable file:

# redocly.yaml
apis:
  main:
    root: openapi/main.yaml

# openapi/main.yaml can $ref to:
# openapi/paths/users.yaml
# openapi/schemas/user.yaml
# etc.

Split your spec into manageable files organized by resource. redocly bundle produces a single file for tools that require it; redocly lint validates across the split files.

Scalar: The Modern Documentation UI

Scalar is the best free alternative to Swagger UI in 2026. It's faster, more attractive, and supports modern OpenAPI features that Swagger UI struggles with. Drop-in replacement for most setups:

<!DOCTYPE html>
<html>
  <head>
    <title>API Reference</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <script
      id="api-reference"
      data-url="/openapi.yaml"
    ></script>
    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
  </body>
</html>

Scalar supports the "Try It" console, authentication, multiple spec files, and dark mode. It's actively maintained with frequent releases.

TypeSpec: Microsoft's API Description Language

TypeSpec is Microsoft's answer to the "writing OpenAPI YAML by hand is painful" problem. It's a TypeScript-like language that compiles to OpenAPI (and other formats). Azure's entire API surface is defined in TypeSpec.

import "@typespec/http";
using TypeSpec.Http;

@service({ title: "User API" })
@server("https://api.example.com/v1", "Production")
namespace UserAPI;

model User {
  @key id: string;
  name: string;
  @format("email") email: string;
  @visibility("read") createdAt: utcDateTime;
}

@route("/users")
interface Users {
  @get list(): User[];
  @post create(@body user: OmitProperties<User, "id" | "createdAt">): User;
  @get read(@path id: string): User | NotFoundResponse;
  @patch update(@path id: string, @body patch: UpdateableProperties<User>): User;
  @delete remove(@path id: string): void;
}

TypeSpec generates a valid OpenAPI 3.0/3.1 spec from this definition. The advantages:

  • No writing YAML by hand — TypeSpec is type-checked
  • Reusable model definitions with TypeScript-style generics (OmitProperties<User, ...>)
  • Single source generates OpenAPI, JSON Schema, and potentially gRPC proto files
  • Better diff and merge behavior than YAML (TypeScript-style syntax is more conflict-friendly)

TypeSpec is currently most useful for large API teams managing complex surfaces. The tooling is mature but the learning curve is steeper than writing OpenAPI directly. Watch this space — it's likely to become the standard for enterprise API teams in 2026-2027.

Developer Portal Strategy

docs.company.com Setup

Your developer documentation should live on a memorable, stable subdomain. docs.yourapi.com or developers.yourcompany.com are standard. Avoid paths like yourcompany.com/api/docs — hard to bookmark, mixed with marketing content.

ReadMe vs Mintlify vs Self-Hosted

ReadMe is the most feature-rich commercial platform. It includes a "Try It" console, versioned documentation, API metrics (which endpoints developers test), and a changelog. The developer experience for consumers is excellent. Cost: from $99/month.

Mintlify targets modern developer tools companies with a cleaner aesthetic and MDX-based content. The navigation, search, and code blocks are polished. Cost: $150/month. Mintlify's template system means your docs look professional without design work.

Self-hosted with Redocly or Scalar: Free, full control, works as a static site. Deploy to Vercel or Netlify. Best choice for teams that want to own their docs infrastructure and integrate tightly with their CI pipeline.

Versioned Documentation

When you release API v2, you need to maintain documentation for both v1 and v2. Most platforms support versioned docs with a version selector. Key decisions:

  • Keep v1 docs available but clearly mark them as legacy
  • Redirect new users to the latest version by default
  • Include migration guides when breaking changes require action

For API version management strategy, see how to version REST APIs and API breaking changes without breaking clients.

Docs as Code

Treating documentation as code — spec in Git, CI validation, automated deployment — is how serious API teams prevent documentation drift.

OpenAPI Spec in Git

Keep your OpenAPI spec in the same repository as your API code. When a developer changes an endpoint, they update the spec in the same PR. Code review catches spec changes that don't match implementation.

Structure that works:

api/
  openapi/
    main.yaml        # Entry point
    paths/
      users.yaml
      orders.yaml
    schemas/
      user.yaml
      order.yaml

CI Validation with Spectral

Every PR that changes the spec runs Spectral validation:

# .github/workflows/api-spec.yml
name: Validate API Spec
on:
  pull_request:
    paths:
      - 'api/openapi/**'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install -g @stoplight/spectral-cli
      - run: spectral lint api/openapi/main.yaml

Breaking Change Detection with oasdiff

oasdiff compares two OpenAPI specs and reports breaking changes. Run it in CI to catch regressions before they ship:

# Install
brew install oasdiff  # or go install github.com/tufin/oasdiff@latest

# Compare current spec against main branch
oasdiff breaking api/openapi/main.yaml https://raw.githubusercontent.com/org/repo/main/api/openapi/main.yaml

Breaking changes detected by oasdiff:

  • Removed endpoints
  • Removed required request parameters
  • Added required request parameters (breaks existing callers)
  • Changed response field types
  • Removed response fields that were previously present

Make oasdiff failures block merges. A non-zero exit code means a breaking change was introduced — either document it properly or rethink the approach.

Auto-Deploy Docs on Spec Change

When the spec file changes, deploy updated documentation automatically:

- name: Deploy docs
  if: github.ref == 'refs/heads/main'
  run: |
    redocly bundle api/openapi/main.yaml --output dist/openapi.yaml
    # Deploy dist/openapi.yaml to your docs platform

This keeps documentation permanently in sync with the spec. Manual doc deploys that lag behind API releases are a common source of developer frustration.

For SDK generation from your spec, see how to build an API SDK. For testing your API against the spec, see API testing strategies.

Conclusion

Good API documentation is an engineering practice, not a writing exercise. OpenAPI 3.1 specs in Git, validated by Spectral, deployed via CI, and rendered in Scalar or Mintlify — this pipeline treats documentation with the same rigor as code. The payoff is concrete: developers integrate faster, support tickets decrease, and SDK generation stays in sync. For event-driven APIs, add AsyncAPI alongside your OpenAPI spec. For large API teams generating specs programmatically, TypeSpec is worth evaluating. The common thread: machine-readable specs that power everything else are the foundation worth investing in.

The API Integration Checklist (Free PDF)

Step-by-step checklist: auth setup, rate limit handling, error codes, SDK evaluation, and pricing comparison for 50+ APIs. Used by 200+ developers.

Join 200+ developers. Unsubscribe in one click.