Skip to content

Expert · Testing and API documentation · topic 46 of 54 · 25 min

Documenting your API with OpenAPI

Explanation

API documentation tells other developers what each endpoint does, what to send and what comes back, including errors. The common standard is OpenAPI (formerly called Swagger): one YAML or JSON file that tools like Swagger UI, Redoc and Scalar turn into a readable, clickable website. Good docs also have example requests, a changelog and clear deprecation notices.

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.

Think of it like this: API docs are like a good restaurant menu. It lists every dish (endpoint), what is inside (request fields), what you get on the plate (response), the price (rate limits, auth needed), and notes like "not available after 10 pm" (errors). A menu with no prices or a dish that is no longer served causes arguments at the table.

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.

output
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 }
A small openapi.yaml. paths -> method -> responses is the core shape; components holds reusable schemas.

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

ToolWhat it does
Swagger UIShows the spec as a web page with a "Try it out" button for each endpoint
RedocA clean, three-column reading layout, good for public docs
ScalarA modern docs page with a built-in API client and code samples
Postman / BrunoAPI clients. You can import the spec as a collection of ready requests; Bruno stores collections as plain files in your git repo
Tip: Generate the spec from your code where you can. FastAPI in Python creates it automatically. In Node.js, libraries can build it from your validation schemas (for example Zod). Then the docs cannot drift away from the code.

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": "..." } }.

output
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 minute
An example request with curl, the response, and the error table for the same endpoint.

Versioning, 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.
Careful: Wrong docs are worse than no docs. People trust them, build on them and lose hours. Update the spec in the same pull request as the code change, and check it in CI.

Watch the lesson

Documenting your API with OpenAPI · 1/6

API documentation

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)

Task 1 · Code · Javascript

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).

Task 2 · Code · Javascript

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).

Task 3 · Practice

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

Question 1

1.What was OpenAPI called before?

Question 2

2.In an OpenAPI file, what is under paths -> /api/notes -> get?

Question 3

3.Which change can break existing mobile apps and needs a new major version?

Question 4

4.What is the best way to keep docs and code in sync?

Question 5

5.An endpoint will be removed in six months. What should you do now?

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