OpenAPI 3.1 Spec Guide
OpenAPI 3.1 is the industry standard for describing REST APIs. This guide walks through every section of a production-quality spec — from info and paths to authentication, schema reuse, and automated validation in CI.
Spec Skeleton (OpenAPI 3.1)
openapi: "3.1.0"
info:
title: Acme API
version: "1.0.0"
description: |
Public REST API for Acme services.
Rate limits: 100 req/min (standard), 1000 req/min (pro).
contact:
name: Acme Engineering
email: [email protected]
license:
name: MIT
identifier: MIT # SPDX identifier (new in 3.1)
servers:
- url: https://api.acme.example/v1
description: Production
- url: https://staging-api.acme.example/v1
description: Staging
tags:
- name: users
description: User management
- name: orders
description: Order operations
paths:
/users:
get:
operationId: listUsers
tags: [users]
summary: List all users
parameters:
- $ref: '#/components/parameters/LimitParam'
- $ref: '#/components/parameters/CursorParam'
responses:
'200':
description: Paginated user list
content:
application/json:
schema:
$ref: '#/components/schemas/UserListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
security:
- BearerAuth: []
post:
operationId: createUser
tags: [users]
summary: Create a new user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
example:
email: [email protected]
name: Jane Doe
responses:
'201':
description: User created
headers:
Location:
description: URL of the created user
schema:
type: string
format: uri
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'422':
$ref: '#/components/responses/ValidationError'
security:
- BearerAuth: [] Components: Schemas, Parameters & Responses
components:
# --- Reusable schemas ---
schemas:
User:
type: object
required: [id, email, created_at]
properties:
id:
type: string
format: uuid
readOnly: true
example: "550e8400-e29b-41d4-a716-446655440000"
email:
type: string
format: email
example: "[email protected]"
name:
type: ["string", "null"] # nullable in OAS 3.1 (not nullable: true)
example: "Jane Doe"
roles:
type: array
items:
type: string
enum: [admin, editor, viewer]
default: [viewer]
created_at:
type: string
format: date-time
readOnly: true
CreateUserRequest:
type: object
required: [email]
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
UserListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
meta:
type: object
properties:
next_cursor:
type: ["string", "null"]
has_more:
type: boolean
ErrorResponse:
type: object
required: [error]
properties:
error:
type: object
required: [code, message]
properties:
code:
type: string
example: VALIDATION_FAILED
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
issue:
type: string
trace_id:
type: string
# --- Reusable parameters ---
parameters:
LimitParam:
name: limit
in: query
description: Number of results per page (max 100)
schema:
type: integer
minimum: 1
maximum: 100
default: 20
CursorParam:
name: cursor
in: query
description: Pagination cursor from previous response
schema:
type: string
# --- Reusable responses ---
responses:
Unauthorized:
description: Missing or invalid authentication token
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
ValidationError:
description: Request validation failed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
# --- Security schemes ---
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://auth.acme.example/oauth/authorize
tokenUrl: https://auth.acme.example/oauth/token
scopes:
read:users: Read user data
write:users: Create and update users Validation with Spectral (CI)
# Install Spectral CLI
npm install -g @stoplight/spectral-cli
# Lint against built-in OAS ruleset
spectral lint openapi.yaml
# Custom ruleset (.spectral.yaml)
extends: ["spectral:oas"]
rules:
operation-tag-defined: error # all operations must have tags
operation-success-response: error # must have 2xx response
no-$ref-siblings: off # relax for OAS 3.1
info-contact: warn
oas3-api-servers: error
# GitHub Actions integration
# .github/workflows/api-lint.yml
name: Lint OpenAPI Spec
on: [pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g @stoplight/spectral-cli
- run: spectral lint openapi.yaml --fail-severity=warn Generating Swagger UI & Redoc
// Express + swagger-ui-express
import express from 'express';
import swaggerUi from 'swagger-ui-express';
import yaml from 'js-yaml';
import fs from 'fs';
const app = express();
const spec = yaml.load(fs.readFileSync('./openapi.yaml', 'utf8'));
app.use('/docs', swaggerUi.serve, swaggerUi.setup(spec, {
customCss: '.swagger-ui .topbar { display: none }',
swaggerOptions: { persistAuthorization: true },
}));
// Serve raw spec for SDK generators
app.get('/openapi.json', (req, res) => res.json(spec)); # Generate static Redoc HTML (zero runtime deps) npx @redocly/cli build-docs openapi.yaml -o docs/api.html # Bundle multi-file spec into single file npx @redocly/cli bundle openapi.yaml -o dist/openapi.yaml # Generate TypeScript client SDK npx @openapitools/openapi-generator-cli generate \ -i openapi.yaml \ -g typescript-fetch \ -o src/api-client
Tooling Quick Reference
| Tool | Purpose | Command |
|---|---|---|
| Spectral | Lint & custom rules | spectral lint openapi.yaml |
| Redocly CLI | Lint, bundle, build docs | redocly lint / bundle / build-docs |
| vacuum | Fast Go-based linter | vacuum lint openapi.yaml |
| openapi-generator | Generate client SDKs | openapi-generator-cli generate |
| swagger-ui-express | Serve interactive docs | npm i swagger-ui-express |
| Prism | Mock server from spec | prism mock openapi.yaml |
Frequently Asked Questions
What is the difference between OpenAPI 3.0 and 3.1?▼
OpenAPI 3.1 (released 2021) aligns fully with JSON Schema Draft 2020-12, whereas 3.0 used a subset of JSON Schema Draft 4. Key improvements in 3.1: webhooks are a first-class concept (separate from paths), the info.license object now supports SPDX expressions, $ref can now appear alongside other properties (3.0 forbade sibling keywords), the nullable: true hack is replaced by type: ['string', 'null'] following JSON Schema conventions, and $vocabulary support enables custom validation keywords. Use 3.1 for all new APIs — tooling support caught up in 2022-2023.
How do I define authentication in an OpenAPI spec?▼
Authentication is defined in two places. First, declare security schemes under components.securitySchemes: for Bearer JWT use type: http, scheme: bearer, bearerFormat: JWT. For API keys use type: apiKey with in: header or in: query and the name field. For OAuth2 use type: oauth2 with flows describing authorization, implicit, clientCredentials, or password flows. Second, apply them: global security array sets defaults for all operations, individual operations can override with their own security array, or opt out with security: [] for public endpoints.
What tools validate an OpenAPI spec?▼
Spectral by Stoplight is the most powerful validator — it has built-in OAS3 ruleset and you can write custom rules as JS/YAML rulesets. Install with npm i -g @stoplight/spectral-cli then run spectral lint openapi.yaml. Other options: swagger-parser (programmatic validation in Node.js), vacuum (Go-based, extremely fast, CI-friendly), redocly CLI (redocly lint, also has its own ruleset), and the official swagger-editor online validator at editor.swagger.io. For CI, run Spectral or redocly in your GitHub Actions workflow to block PRs with invalid specs.
Should I write OpenAPI by hand or generate it from code?▼
Code-first generation (annotations or decorators on route handlers) keeps the spec in sync automatically but produces verbose, hard-to-read specs and couples your API contract to implementation details. Spec-first (design the YAML manually, then generate server stubs and client SDKs) enforces deliberate API design and makes contract changes explicit and reviewable. Best practice: write the spec first as a design artifact, review it with stakeholders, then generate server stubs (openapi-generator, oapi-codegen for Go, FastAPI with Pydantic models). This makes breaking changes visible in diffs.
How do I generate a Swagger UI from my OpenAPI spec?▼
The simplest way is the swagger-ui-express package: npm i swagger-ui-express js-yaml, then app.use('/docs', swaggerUi.serve, swaggerUi.setup(yaml.load(fs.readFileSync('./openapi.yaml')))). For static hosting, run npx @redocly/cli build-docs openapi.yaml -o docs/index.html to produce a zero-dependency HTML file. Redoc produces cleaner documentation than default Swagger UI and handles complex schemas better. For Next.js or Astro projects, serve the raw openapi.yaml and initialize swagger-ui-dist client-side.
What is the best way to handle $ref and schema reuse?▼
Define all reusable schemas under components.schemas, parameters under components.parameters, and responses under components.responses. Use $ref: '#/components/schemas/User' to reference them. For request/response bodies, define them inline for simple one-off cases and in components for any schema used more than once. For large APIs, split into multiple files and use $ref: './schemas/user.yaml'. Tools like Redocly and swagger-parser handle multi-file specs with bundle commands that merge everything into a single file for distribution.
Related Products
on GumroadDeveloper Productivity Bundle
Stop rebuilding the same setup every project. 51 VSCode snippets, 40 Git aliases, 5 Docker Compose stacks, 5 GitHub Actions workflows, 5 README templates, and a dotfiles kit. Set up a professional dev environment in under an hour.
Buy on Gumroad →AI Prompt Engineering Toolkit
58 structured prompt templates for Claude, ChatGPT, and Gemini — organized by use case. Code Review, Debugging, Documentation, Architecture, and 10 model-specific tips. Stop writing prompts from scratch.
Buy on Gumroad →Developer Cheat Sheet Bundle
10 print-ready cheat sheets for the tools developers use every day: Git, Docker, Linux CLI, SQL, Regex, HTTP Status codes, VS Code shortcuts, Bash scripting, jq/JSON, and Markdown.
Buy on Gumroad →You Might Also Need
OpenAPI Validator
Paste your OpenAPI 3.x spec (YAML or JSON) to validate structure, find missing required fields, detect duplicate paths, check for missing operationIds, and get errors and warnings with path references.
Open free tool →
OpenAPI Schema Validator
Paste OpenAPI 3.x YAML or JSON and get instant validation errors and warnings. Checks required fields, paths, operations, response codes, and components. Runs entirely in your browser.
Open free tool →
OpenAPI Mock Generator
Paste an OpenAPI spec and get mock response data for testing. Generates realistic sample JSON from your API schema definitions.
Open free tool →
More Free Tools
Related Articles
curl 深度使用手冊:API 測試從入門到進階
curl 是每位開發者必備的 CLI 工具。本文涵蓋 GET/POST/PUT/DELETE 請求、認證、header 設定、檔案上傳、除錯技巧,以及 REST API 測試的完整實戰範例。
GraphQL Federation vs REST Microservices: Which Architecture in 2026?
Compare GraphQL Federation vs REST microservices — Apollo Federation, schema stitching, performance, team scaling, migration paths, and when to choose each in 2026.
OpenAPI 3.1 vs Swagger 2.0: The Complete API-First Development Guide for 2026
Everything you need to know about OpenAPI 3.1 vs Swagger 2.0: key differences, API-first development methodology, tooling ecosystem, code generation, contract testing, migration guide, and best practices for 2026.
tRPC vs GraphQL vs REST: Type-Safe APIs in 2026
Compare tRPC, GraphQL, and REST for building type-safe APIs in 2026. Covers DX, performance, bundle size, schema management, and when to use each approach.
Best API Documentation Tools for Developers in 2025 (Swagger, Redoc, Scalar, and More)
A practical comparison of API documentation tools in 2025 — Swagger UI, Redoc, Scalar, Stoplight, and Mintlify — covering OpenAPI support, customization, hosting options, and developer experience.
Enjoying this tool? Get more like it.
Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.
Unlock AI-Powered Dev Tools
- ⚡ AI Code Review, Doc Generator & SQL Builder
- ⚡ All premium templates & early access
- ⚡ Member discounts on Gumroad products
$9/mo after trial · Cancel anytime
Want the full toolkit?
Get DevPlaybook Pro
Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.
MIT licensed · Instant download · No subscription
See what's included → Browse all deals →