OpenAPI Specification

Artifact

A machine-readable file describing what each endpoint of an API accepts and returns, from which reference pages, client code, and validation tools are generated.

Why it exists

Open a counter that programs agree to talk through and the agreement has to be written down somewhere. For a long time that somewhere was a document a person wrote. Someone made a table on the internal wiki listing addresses, the values to send, and the values that come back, and whoever was integrating built against that table.

A table and the code it describes drift apart unless they're maintained in one place. Add a field to a response and updating the wiki is a separate thing to remember, which usually means it doesn't happen.

So the same conversation kept repeating. "The docs say the username comes back, but it isn't there." "Oh, we dropped that last month." Once the document can't be trusted, the integrating side just fires one request, reads whatever came back, and codes against that. There's a written agreement and everyone checks the physical object anyway.

The OpenAPI Specification is the proposal to write that agreement in a format a machine reads rather than a person. With a fixed format, one file produces the human-readable reference pages, the code the integrating side uses, and the tooling that checks whether real responses match what's written. Updating the document stops being a separate thing to remember and attaches itself to updating the code. Through version 2.0 the format was called Swagger; it took its current name at 3.0, and both names are still in use for the same thing.

What goes in it

A single file holds six blocks. It's written in YAML or JSON, both plain text formats a person can read directly, so it opens in any editor.

  1. Basic information — the version of the format, the name and description of the API, and the real addresses. Production and test addresses usually sit side by side.
  2. Paths — the list of open counters. An address like /documents is written out, with an entry underneath it for each HTTP method. Reading and creating are separate entries even at the same address.
  3. Requests — what each entry accepts. Values baked into the address, values after the question mark, values arriving as headers, and values in the body are listed by position, each with its shape and whether it's required.
  4. Responses — what comes back, written separately per status code, because the body shape for a 200 and the body shape for a 404 are not the same thing.
  5. Schemas — shapes of data that repeat in several places, defined once and referenced by name. Describe the fields of a single document here and the list response and the detail response both point at that one definition.
  6. Security — how the caller is identified. Which header carries the token, and which counters require which method.

For a counter that creates one document, the pieces come together like this. Path /documents, method create, request body of two fields with the title required. The response is the id of the new document on a 201, and which field was wrong on a 400.

Who writes it and who reads it

The author is a developer on the side opening the counter, and the first readers are tools rather than people. There are two ways to write it: put the file first and implement against it, or annotate the code and generate the file from those annotations. The first lets the integrating side start without waiting for an implementation; the second keeps the file from drifting away from the code.

Tools do four things with the file.

  1. Reference pages — the list of counters and their inputs and outputs, rendered for a browser. You can usually fill in values and send a real request from the page.
  2. Client code — a function per counter, so the integrating side never types an address as a string.
  3. Mock servers — a server that returns fake responses in the documented shape before any implementation exists, so screen work doesn't queue behind server work.
  4. Validation — an automatic check that real requests and responses match the file. Drift between documentation and behavior gets caught here.

Human readers come after that. A developer wiring up a screen checks what to send, an outside developer decides whether their system can integrate, and a product manager compares the screen behavior promised in a specification against what the counters can actually do. A specification describes screens and behavior in enough detail to build them, so when it calls for an author name on a list screen, this file is where you check whether that value is in the response.

How it sounds at work

"Post the spec first and we'll run a mock server and start on the screens."

An offer to begin without waiting for the implementation, working from the file alone.

"There's a field in the response that isn't in the spec. Which one is correct?"

The file and the behavior have diverged, and somebody has to decide which one gets fixed.

"The change is in the spec. One more required field, so we need to warn the teams integrating with us."

The diff on the file is the same thing as the impact on everyone connected to it.

Pagedeck keeps a counter open so other tools can pull documents out of it. Theo keeps the spec file next to the code and has attached a step to every deploy that checks real responses against the file. If they disagree, the deploy stops.

Mia opens this file first when she designs a feature. She checks whether the values a screen needs already come back from an existing counter, and if they don't, she and Theo settle on what to add right there.

What people get wrong

The most common mistake is treating the file as a manual for people. The reference pages are so familiar that the pages themselves end up being called OpenAPI, when the pages are output from the file and the file is a format built for machines. Confuse the two and time goes into polishing the pages while nobody checks whether the file still matches the code.

The expectation that having a file makes documentation and code agree by itself also breaks down often. Hearing that one file produces several outputs makes it feel like there's nowhere left to drift. But either way of writing it leaves at least one step where a person updates something by hand, and that's where the gap reopens. Without a validation step wired into deploys, a breaking change that removed a field from a response stays in the file untouched, and the code that trusted the file stops instead.

Where to go next

  • API

    start with what this file documents in the first place

  • REST

    see the design style the paths and methods in the file come from

  • Specification

    compare how the product side writes down the same feature

Last updated 2026-09-16