Skip to content
Product · 5 min read · Updated

Why “no spec” can’t mean “no catalog”

Half the APIs that matter have no OpenAPI file. The catalog has to start from code, not from paperwork.

TL;DR
  • Most production APIs have no spec or a stale one: median 11 months old, covering 71% of live routes.
  • The routing table already is a catalog; extract it from code and the spec becomes an output refreshed on every push.
  • Humans add intent, descriptions, and safe values; machines keep the structure current.
Elva TeamThe Elva Team

Because the spec was never the API. The code is the API; a spec is one description of it, and most teams do not have one. Of the first hundred teams we onboarded, 54 had no OpenAPI file at all for their busiest service, and most of the rest had one that was materially out of date. If a catalog requires a spec as the price of admission, it excludes exactly the APIs that need governance most — the ones nobody can currently see. So the catalog has to be derived from code, and the spec becomes an output.

The routing table is already a catalog

Every framework maintains, at runtime, a complete list of your endpoints — it has to, in order to dispatch requests. Your API has always had a perfectly accurate catalog; it just lives in a data structure nobody can read from the outside. Treating "catalog" as a document to be authored, rather than a structure to be extracted, is the category error behind a decade of failed documentation initiatives. Extraction inverts the effort curve. The artifact everyone kept failing to write by hand becomes a build output, refreshed on every push, and human effort moves to the one layer extraction cannot reach: what the endpoint is for, what the field means, which values are safe. That layer was always the valuable one. It was just buried under the transcription work.

The spec-first assumption

Most API tooling quietly assumes an openapi.yaml exists, is complete, and is true. Gateways import it, portals render it, test generators consume it, linters lint it. The whole chain works beautifully in the demo, where the spec was written yesterday. Then it meets a nine-year-old codebase with 214 endpoints, four frameworks, and a spec covering the 60 endpoints that existed when someone last had a documentation sprint. The tooling is not wrong, exactly. It is built for a world where documentation preceded implementation, and that world is a minority of the APIs actually running.

Where specs actually come from

Talk to teams about the specs they do have and a pattern repeats. The file was written once, under duress, for a specific occasion — a gateway migration, a partner's security review, a compliance audit — and it froze the moment the occasion passed. Nobody's job is to update it; no build fails when it lies. Among onboarded repos that had a spec, the median gap since its last meaningful update was 11 months, and the average spec covered 71% of live routes. The incentive structure is the whole story: code that is wrong breaks loudly, while a spec that is wrong breaks someone else, later, quietly.

Start from code, annotate up

Deriving the catalog from the repo flips the economics. Analysis of route handlers, validators, and middleware produces a baseline nobody had to write: every live endpoint, its real parameters, its actual auth, expressed as OpenAPI 3.1 on the way out rather than demanded on the way in. Humans then do the part machines cannot — intent. Descriptions, examples, deprecation plans, and constraints layer on top of the generated truth, and re-syncs preserve them while refreshing the structure underneath. The division of labor is the point: machines maintain the parts that drift, humans maintain the parts that matter, and neither is asked to do the other's job badly.

What changes day to day

The visible change is small and constant. A pull request that adds an endpoint also adds a catalog entry, with no extra step, because the sync runs on push. Review comments start pointing at generated diffs — "this new field is a bare string, tighten it" — instead of asking whether documentation was updated, a question whose answer everyone already knew. New engineers stop asking which endpoints exist; the catalog is the onboarding doc that cannot be out of date. And the quarterly ritual where someone volunteers to "fix the docs" quietly disappears, replaced by nothing at all, which is the correct amount of ceremony for keeping an inventory current.

The objections, answered

Three come up in every evaluation. "Our code is too messy for analysis" — messy code is the argument for extraction, not against it; the mess is precisely what nobody can inventory by hand, and confidence markers make it legible instead of hiding it. "We'll write the spec properly next quarter" — the median existing spec we import is 11 months stale; that quarter has been coming for years, and pricing that honestly is cheaper than another documentation sprint. "Generated docs are low quality" — generated structure is high quality, because it cannot disagree with the code. Quality problems live in descriptions and examples, which remain human work, and which become tractable the moment the structural transcription is free.

What a generated catalog unlocks

Everything downstream stops being blocked on a documentation project that was never going to happen. Scoring runs against real shapes, so "how agent-ready is billing" has an answer the week you connect the repo. Contracts diff against code-derived structure, so breaking changes are caught in services that never had a spec to check. MCP servers generate from cataloged endpoints, so the no-spec team and the spec-perfect team reach a governed agent surface through the same door. The teams that needed paperwork first were stuck at step zero indefinitely. Starting from code, the median time from connecting a repo to a governed, scored, agent-callable catalog is measured in days — and the spec everyone kept meaning to write finally exists, generated, current, and checked.

FAQ

Why do most APIs have no OpenAPI spec?

Specs get written once under duress, for a migration or an audit, and freeze when the occasion passes. Among onboarded repos that had one, the median gap since a meaningful update was 11 months, covering 71% of live routes.

Can you have an API catalog without a spec?

Yes. Every framework already maintains a complete endpoint list in its routing table; the catalog is extracted from code, and the spec becomes an output refreshed on every push.

What do humans still add to a generated catalog?

Intent: what an endpoint is for, what a field means, which values are safe to expose. Machines maintain the parts that drift, humans maintain the parts that matter.

Share: X · LinkedIn ·
READ NEXT

Ship notes, monthly

One email with what shipped and what we learned. Unsubscribe anytime.