OpenAPI 3.0 in 10 Minutes: Build Your API Spec Visually
OpenAPI (formerly Swagger) is the industry standard for describing REST APIs. A single spec file can generate documentation, client SDKs, server stubs, and mock servers. Yet many teams skip writing one because the syntax feels intimidating. It does not have to be.
What is an OpenAPI spec?
An OpenAPI specification is a YAML or JSON file that describes every endpoint, request body, response, and data model in your API. Here is a minimal example:
openapi: 3.0.3
info:
title: Bookstore API
version: 1.0.0
paths:
/books:
get:
summary: List all books
responses:
'200':
description: A list of books
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Book'
components:
schemas:
Book:
type: object
properties:
id:
type: integer
title:
type: string
author:
type: string
price:
type: number
format: float
required: [id, title, author]
That is a complete, valid spec. It tells any consumer exactly what GET /books returns.
The building blocks
Every OpenAPI spec has four key sections:
1. Info
Metadata about the API — title, version, description, contact, license. This is what appears at the top of generated documentation.
2. Paths
The endpoints. Each path (/books, /books/{id}) contains operations (get, post, put, delete) with parameters, request bodies, and response definitions.
3. Components
Reusable schemas, parameters, headers, and security schemes. Define a Book schema once and reference it everywhere with $ref: '#/components/schemas/Book'.
4. Security
Authentication requirements — API keys, OAuth2 flows, bearer tokens. Defined in components/securitySchemes and applied globally or per-operation.
YAML vs JSON
Both formats are valid. YAML is more readable and commonly used for hand-written specs. JSON works better when the spec is machine-generated.
# YAML — easier to read and write
paths:
/books:
get:
summary: List all books
{
"paths": {
"/books": {
"get": {
"summary": "List all books"
}
}
}
}
Most teams write in YAML and let tooling convert to JSON when needed.
Parameters: path, query, header
OpenAPI distinguishes between parameter locations:
/books/{id}:
get:
parameters:
- name: id
in: path
required: true
schema:
type: integer
- name: fields
in: query
schema:
type: string
description: Comma-separated list of fields to include
- name: X-Request-ID
in: header
schema:
type: string
Path parameters are always required. Query and header parameters are optional by default.
Request bodies
POST and PUT operations typically include a request body:
/books:
post:
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateBook'
responses:
'201':
description: Book created
Separate your "create" schemas from your "response" schemas. The create schema omits id and createdAt because those are server-generated.
What you can generate from a spec
This is where OpenAPI pays for itself:
- Interactive documentation — Swagger UI or Redoc render your spec as a browsable, try-it-out API reference.
- Client SDKs — Tools like openapi-generator-cli produce TypeScript, Python, Go, Java, and 40+ other client libraries.
- Server stubs — Generate route handlers with type-safe request/response objects for Express, FastAPI, Spring Boot, and more.
- Mock servers — Prism or Stoplight mock your API based on the spec, so frontend teams can work without waiting for the backend.
- Test suites — Schemathesis generates property-based tests from your spec to find edge cases you did not think of.
Common mistakes
- Skipping
requiredarrays. If you do not mark fields as required, generators assume everything is optional, producing weak types.
- Using
type: objectwithout properties. This tells consumers nothing. Always define the shape.
- Duplicating schemas. Use
$refaggressively. One source of truth for each data model.
- Ignoring error responses. Document
400,401,404, and500responses with their schemas. Consumers need to handle these too.
- Versioning in the path. Putting
/v1/in every path is fine, but also update theinfo.versionfield so tooling knows which version it is generating for.
Design-first vs code-first
In the design-first approach, you write the spec before any code. Teams review the API contract, agree on shapes, and then implement. This works well for multi-team projects.
In the code-first approach, you write the server code with annotations (decorators, comments) and extract the spec from the code. This works well for fast-moving solo or small-team projects.
Both are valid. The important thing is that a spec exists and stays in sync with the implementation.
Try our OpenAPI Generator to build your API spec visually — right in your browser, no upload required.