Skip to content

API Documentation Standards

Status: 🟢 Active  |  Owner: Architecture Team

OpenAPI 3.1 Specification

Every HTTP API must have an OpenAPI 3.1 specification:

  • Stored at /openapi.yaml in the repository root.
  • The spec is the source of truth — generate server stubs and client SDKs from it, not the reverse.
  • The spec must be committed with every API change — failing to update it blocks PR merge.

Required Specification Fields

openapi: "3.1.0"
info:
  title: Order Service API
  description: |
    Manages order lifecycle from placement through fulfillment.
  version: "1.0.0"
  contact:
    name: Order Platform Team
    email: [email protected]
  license:
    name: Internal — Not for public distribution

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

tags:
  - name: Orders
    description: Order management operations

paths:
  /orders:
    post:
      summary: Place a new order
      operationId: placeOrder
      tags: [Orders]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlaceOrderRequest'
      responses:
        '201':
          description: Order created successfully
          headers:
            Location:
              description: URL of the created order
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorised'

Documentation Completeness

All paths must have: - summary — short description (< 80 characters) - operationId — unique, camelCase identifier - tags — for grouping in Swagger UI - All response codes documented (2xx, 4xx, 5xx) - All request/response schemas with descriptions on every field

Publishing

  • Swagger UI is auto-deployed from the OpenAPI spec via CI.
  • Internal API docs are available at https://api-docs.acme.internal/<service-name>.

Last reviewed: 2025-Q4  |  Owner: Architecture Team


Keeping the Spec in Sync with the Implementation

The most common failure mode for API documentation is drift: the code changes, the spec does not. Within a few months the spec describes an API that no longer exists.

Code-First vs Design-First

This organisation uses a design-first approach for new APIs: the OpenAPI spec is written before the implementation. The spec is reviewed in a PR (it is a contract, not an afterthought), and server stubs are generated from it. This ensures the spec is authoritative from day one.

For APIs that already exist without a spec, generate a draft spec from the implementation using Springdoc (Java), FastAPI's built-in generation (Python), or tsoa (TypeScript), then review and clean up the generated spec before treating it as the source of truth.

CI Enforcement

Two CI gates keep the spec and implementation aligned:

# 1. Validate that the spec is valid OpenAPI 3.1
- name: Validate OpenAPI spec
  run: npx @apidevtools/swagger-cli validate openapi.yaml

# 2. Detect breaking changes vs the previously merged spec
- name: Check for breaking API changes
  uses: oasdiff/oasdiff-action@main
  with:
    base: origin/main:openapi.yaml
    revision: openapi.yaml
    fail-on: ERR   # Breaking changes fail the pipeline

Breaking API changes caught by oasdiff require the engineer to either adjust the implementation to remain backward compatible or follow the API versioning and deprecation process.


gRPC Documentation

Services that expose gRPC APIs must maintain .proto files as the source of truth for the API contract:

  • .proto files live in proto/ at the repository root, or in a dedicated proto repository for schemas shared across services.
  • All .proto files must include package-level comments and comments on every RPC method and message field.
  • Use buf for linting and breaking change detection on .proto files.
# Lint proto files
buf lint

# Detect breaking changes in .proto files
buf breaking --against '.git#branch=main'

References


Last reviewed: 2025-Q4  |  Owner: Architecture Team