API Documentation

OpenAPI

OpenAPI is a machine-readable description of an HTTP API. One spec can generate documentation, clients, servers and tests — if you keep it accurate.

intermediate14 min readUpdated Sep 15, 2026
openapi.yaml
yaml
# openapi.yaml
openapi: 3.1.0
info:
  title: Posts API
  version: 1.0.0
paths:
  /posts:
    get:
      summary: List posts
      responses:
        "200":
          description: A list of posts
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Post"
components:
  schemas:
    Post:
      type: object
      required: [id, title]
      properties:
        id: { type: string }
        title: { type: string }
Format
JSON or YAML
Current
OpenAPI 3.1
Structure
Paths and operations
Reuse
components and $ref
Docs
Swagger UI, Redoc
Codegen
Clients and servers

Why it matters

Why OpenAPI matters

One source of truth

A single spec describes every endpoint, parameter and response, so docs and clients cannot drift from the contract.

Contract validation

The spec can validate requests and responses in tests and at runtime, catching breaking changes early.

Tooling everywhere

Generators produce typed clients, server stubs, mocks and documentation from the same file.

The big picture

The three parts of a spec

Metadata describes the API, paths describe operations, and components define reusable schemas.

Info and servers

Describe

Title, version, description and the base URLs the API is served from.

Paths

Operate

Each path and method defines parameters, request bodies and responses.

Components

Reuse

Shared schemas, parameters and responses referenced with $ref.

OpenAPI at a glance

The core of a spec

openapi and info

The spec version and metadata about the API.

paths

URLs and the operations available on each.

components

Reusable schemas, parameters, responses and security schemes.

$ref

Reference a component instead of repeating it.

security

Declare authentication schemes such as bearer tokens or OAuth.

Documentation

Swagger UI and Redoc render an interactive reference.

A short history

From Swagger to an industry standard

  1. 2010

    Swagger announced

    A specification and tooling for describing REST APIs is released.

    10
  2. 2015

    Swagger 2.0

    The format becomes widely adopted and tooling matures.

    15
  3. 2017

    OpenAPI Initiative

    The specification is donated to the Linux Foundation and renamed.

    17
  4. 2021

    OpenAPI 3.1

    Full JSON Schema compatibility and webhooks arrive.

    21
  5. Today

    The de facto standard

    Most API tooling consumes or produces OpenAPI.

    Today

The complete guide

OpenAPI: Everything you need to know

What is OpenAPI?

OpenAPI is a machine-readable description of an HTTP API. Written in YAML or JSON, a single document lists every endpoint, its parameters, request bodies, responses and authentication. Because it is structured, tools can consume it: documentation UIs, typed clients, server stubs, mocks and validators.

Swagger was the original name; it now refers to the tooling, especially Swagger UI. The specification itself is OpenAPI, and it has become the de facto standard for describing REST APIs. If you have ever used an interactive API reference with a “Try it out” button, you have used OpenAPI.

The shape of a document

An OpenAPI document has a few top-level sections.

# openapi.yaml
openapi: 3.1.0
info:
  title: Posts API
  version: 1.0.0
servers:
  - url: https://api.example.com/v1
paths:
  /posts:
    get:
      summary: List posts
      responses:
        "200":
          description: A list of posts
  • openapi declares the spec version.
  • info holds the title, version and description.
  • servers lists the base URLs.
  • paths describes each endpoint and its operations.
  • components holds reusable pieces.

Paths and operations

Each path maps to one or more HTTP methods, and each operation describes its inputs and outputs.

# paths.yaml
paths:
  /posts/{id}:
    get:
      summary: Get a post
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: The post
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Post"
        "404":
          description: Not found

Parameters can be in the path, query, header or cookie. Request bodies are declared with a content type and schema, and every response should list its status codes and shapes. Good summaries and descriptions turn the spec into useful documentation on their own.

Components and references

Reuse is what keeps a spec maintainable. Define shapes once and reference them with $ref.

# components.yaml
components:
  schemas:
    Post:
      type: object
      required: [id, title]
      properties:
        id: { type: string }
        title: { type: string }
        publishedAt: { type: string, format: date-time }
  parameters:
    Limit:
      name: limit
      in: query
      schema: { type: integer, minimum: 1, maximum: 100 }
  responses:
    NotFound:
      description: Resource not found

A change to the Post schema updates every operation that references it, which prevents the drift that plagues duplicated definitions.

Security

Authentication is declared once and applied per operation.

# security.yaml
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

security:
  - bearerAuth: []

Tools can then send the right credentials in the documentation UI, and generated clients can accept a token parameter.

Documentation and code generation

The spec drives tooling:

  • Swagger UI renders an interactive reference where users can try requests.
  • Redoc renders a clean, three-panel documentation page.
  • openapi-generator produces clients and server stubs in many languages.
  • openapi-typescript generates TypeScript types from the spec.
  • Spectral lints the spec for consistency and style.
  • Mock servers serve example responses so front-end work can start before the backend is ready.
# docs.sh
npx @redocly/cli preview-docs openapi.yaml
npx openapi-typescript openapi.yaml -o src/api-types.ts

Because everything derives from one file, the documentation, clients and types stay consistent.

Spec-first versus code-first

There are two workflows:

  • Spec-first: design the contract before implementing. Great for public APIs, multiple consumers and parallel front-end and back-end work. The spec is the source of truth.
  • Code-first: annotate routes and types, then generate the spec. Keeps the spec close to the implementation and avoids duplication in typed frameworks.

Both work. The failure mode in either case is maintaining documentation by hand in a separate place, where it silently goes out of date.

Validation and contract testing

An OpenAPI document can be enforced, not just read.

  • Request validation: middleware rejects requests that do not match the spec, so handlers can trust their inputs.
  • Response validation: tests assert that responses match their declared schemas.
  • Contract testing: clients and servers both check against the same spec, catching breaking changes early.

This is where the spec earns its keep: it becomes an executable contract rather than decoration.

Best practices

  • Keep one spec per API and treat it as the source of truth.
  • Reuse schemas, parameters and responses with $ref.
  • Write clear summaries and descriptions; they become the docs.
  • Document every status code an operation can return.
  • Validate requests and responses against the spec.
  • Generate clients, types and docs rather than writing them by hand.
  • Lint the spec and review changes in pull requests.

Common mistakes

  • Hand-maintaining docs separately from the spec.
  • Duplicating schemas inline until they disagree.
  • Missing error responses, so clients cannot handle failures.
  • Using vague names and descriptions that do not help consumers.
  • Letting the spec drift from the implementation.
  • Skipping validation and losing the contract’s main benefit.

Where to go next

OpenAPI turns an API into a contract that tools and people can both use. Build it on solid REST design, evolve it carefully with API Versioning, and align it with the HTTP guide. Then describe one endpoint you already have and generate a client from it.

Reusing schemas

Define a model once and reference it. Duplicating inline schemas guarantees they drift apart.

Prefer
components:
  schemas:
    Post:
      type: object
      properties:
        id: { type: string }

# used by many operations
schema:
  $ref: "#/components/schemas/Post"
Avoid
# the same shape copied
# into every operation,
# slowly drifting apart

Keeping docs accurate

Generate documentation from the spec, or generate the spec from typed code. Hand-written docs always fall behind.

Prefer
# spec is the source of truth
npx @redocly/cli preview-docs openapi.yaml
npx openapi-generator-cli generate \
  -i openapi.yaml -g typescript-fetch
Avoid
# manually maintained docs
# in a wiki, updated by hand,
# usually out of date

Trade-offs

Is the spec worth maintaining?

OpenAPI pays off when the spec is generated or enforced, and becomes a liability when it is a separate document nobody updates.

Strengths

  • One contract for everything

    Docs, clients, mocks and validation all read the same file, so they cannot drift from each other.

  • Better collaboration

    A shared, reviewable spec lets frontend, backend and partners agree on the interface before code is written.

  • Machine-checkable

    Linters and contract tests catch breaking changes and inconsistencies in CI rather than in production.

Trade-offs

  • Another artefact to keep accurate

    A hand-written spec drifts from the implementation. If it is not generated or tested, it quietly becomes wrong.

  • Verbose for simple APIs

    YAML descriptions and $ref indirection add overhead that a small internal API may never earn back.

  • Codegen can be rigid

    Generated clients are convenient until you need custom behaviour, and regenerating can churn large diffs.

FAQ

Frequently asked questions

Keep learning

Related topics from the roadmap.

$ start learning

Ready to start learning OpenAPI / Swagger?

Our interactive tutorial walks you through OpenAPI / Swagger step by step — with quizzes and real code you can run in the browser.