Expert · Testing and API documentation · topic 46 of 54 · 25 min
Documenting your API with OpenAPI
Explanation
Why document an API?
An API is only useful if people can call it correctly. The mobile developer, the frontend team, a partner company and you six months from now all need to know: which URL, which method, which fields, which headers, and what can go wrong. Without docs, they guess, ask on chat all day, or read your source code.
OpenAPI: one file that describes the API
OpenAPI is a standard format for describing HTTP APIs. It used to be called Swagger, and many people still use that name. You write (or generate) one file, usually openapi.yaml. It lists every path, the methods on each path, the parameters, the request body and every possible response with its status code.
openapi: 3.1.0
info:
title: Notes API
version: 1.2.0
paths:
/api/notes/{id}:
get:
summary: Get one note by id
parameters:
- name: id
in: path
required: true
schema: { type: integer }
responses:
'200':
description: The note
content:
application/json:
schema: { $ref: '#/components/schemas/Note' }
'404':
description: No note with this id
components:
schemas:
Note:
type: object
required: [id, title]
properties:
id: { type: integer, example: 7 }
title: { type: string, example: Pay electricity bill }YAML is a text format that uses indentation (spaces) to show what belongs inside what. A schema describes the shape of data: which fields, their types, and which are required. $ref points to a schema defined once under components, so you do not repeat it.
Tools that turn the spec into a website
| Tool | What it does |
|---|---|
| Swagger UI | Shows the spec as a web page with a "Try it out" button for each endpoint |
| Redoc | A clean, three-column reading layout, good for public docs |
| Scalar | A modern docs page with a built-in API client and code samples |
| Postman / Bruno | API clients. You can import the spec as a collection of ready requests; Bruno stores collections as plain files in your git repo |
Show examples and document errors
Readers copy examples more than they read field lists. For each endpoint, show one full request and the real response. Then list the errors: which status code, when it happens and what the body looks like. Use the same error shape everywhere, for example { "error": { "code": "NOTE_NOT_FOUND", "message": "..." } }.
curl -X POST https://api.example.com/v1/notes \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"title": "Call Priya"}'
HTTP/1.1 201 Created
{ "id": 12, "title": "Call Priya", "pinned": false }
Errors:
400 VALIDATION_FAILED title is missing or longer than 100 characters
401 UNAUTHORIZED missing or expired token
429 RATE_LIMITED more than 60 requests per minuteVersioning, changelog and deprecation
- Version: put a major version in the URL (/v1/notes) or a header. Adding a new optional field is safe. Removing or renaming a field breaks apps, so it needs a new major version.
- Changelog: a dated list of every change, newest first, for example "2026-10-01: added pinned field to Note".
- Deprecation: when an endpoint will go away, mark it deprecated: true in the spec, announce a date, and send a Deprecation or Sunset header in responses so clients get a warning.
- Keep the old version running for a fair time. Mobile apps on old phones may not update for months.
Watch the lesson
Documenting your API with OpenAPI · 1/6
An API is only useful if others can call it correctly. Docs tell them how.
Prefer a video by a teacher? Find free videos on “openapi swagger tutorial for beginners api documentation” on YouTube ↗
In real life: A payment gateway integration
A small online shop in Jaipur wants to accept UPI payments through a payment gateway. The developer opens the gateway docs: every endpoint has a curl example, the JSON response, a table of error codes (for example "payment failed: insufficient funds"), test keys for a sandbox, and a changelog. The shop goes live in two days without a single support call. Good docs are the reason developers pick one provider over another, and the same is true for your own API inside a company.
Practice (0/3 done)
Write routesToMarkdown(routes) that turns a list like [{ method: "GET", path: "/api/notes", summary: "List notes" }] into a Markdown table. The first line is "| Method | Path | Summary |", the second is "| --- | --- | --- |", then one line per route in the same order. Join the lines with "\n" (a newline).
Write findDocProblems(spec) for an OpenAPI-like object: spec.paths -> path -> method -> { summary, responses }. For every operation, in the order they appear, add "GET /api/notes: missing summary" if there is no summary (or it is empty), and "GET /api/notes: no 2xx response" if none of the response codes starts with "2" (or responses is missing). Write the method in UPPER case. Return the list of problems (an empty list if all is fine).
Write the documentation for one endpoint of a food delivery API: POST /v1/orders. Write it as you would want to read it if you were the mobile developer.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
← Previous: Integration testing: checking parts work together