Make Your OpenAPI Spec Agent-Readable
AI agents construct API calls from your OpenAPI spec. How to publish it, name operations, document errors, and add examples agents can build from.
- Read
- 7 min
- Updated
- 2026-08-06
Your OpenAPI spec is the contract AI agents build API calls from. When a coding agent scaffolds an integration or a tool-using agent constructs a request at runtime, it works from the machine-readable description of your endpoints — paths, parameters, schemas, auth. If that description is missing, unreachable, or thin, the agent does what models do with missing information: it guesses. Guessed parameter names, guessed auth headers, and guessed error handling become failed calls, and the support ticket blames your API, not the agent.
That failure starts earlier than most teams expect. Across the Discry Index corpus, only 54% of scanned APIs pass the OpenAPI spec discovery check — a publicly fetchable, parseable spec at a conventional location or linked from the docs. Nearly half the market asks agents to reconstruct the contract from prose and HTML. This article covers what an agent-readable OpenAPI spec looks like in practice: where to publish it, how to name and describe operations, and how to document examples, errors, and auth so an agent's first constructed call is a working one. It is one piece of the broader agent-readiness picture, and it is usually the highest-leverage one.
Publish the spec where a plain fetch can find it
Before an agent can read your spec, it has to find it — and most agents look with a plain HTTP fetch, no JavaScript execution, no clicking through a docs UI. A spec that only exists inside an interactive API explorer, behind a signup wall, or rendered client-side is invisible to that fetch.
Three publishing rules cover almost every failure we observe:
Serve the raw file at a conventional path. /openapi.json, /openapi.yaml, and /swagger.json on your docs or API domain are where automated discovery looks first. The Discry scanner probes these conventional locations directly — details on the OpenAPI signal page.
Link it from your docs and your llms.txt. A spec that exists but is linked nowhere forces agents to guess URLs. The scanner also follows any OpenAPI or Swagger link it finds in your llms.txt, so one line there — [OpenAPI spec](https://api.example.com/openapi.json) — makes the spec discoverable even at an unconventional path. Keep the pointer live: we have observed llms.txt files advertising a spec URL that returns 404, which is worse than no pointer at all because the agent burns a fetch on a dead end.
Host it on your own domain, officially. Klarna's spec exists as a GitHub gist rather than being hosted on its docs domain — findable if you already know about it, unreliable for automated discovery. Contrast Attio, which publishes a valid OpenAPI 3.1 spec at a stable API URL and links it from the docs, so an agent can ingest the full contract in one fetch. Postmark, meanwhile, has strong human docs but no publicly accessible spec at all — every agent integrating it starts from zero. These are check-level observations from our scans; for where the spec sits among the other fixes, see how to make your API agent-ready.
operationId: the name agents call you by
The spec's operationId field is "a unique string used to identify the operation," and the OpenAPI Specification notes that tools MAY use it to uniquely identify an operation — which is exactly what agent frameworks do. When a spec is converted into a tool catalog for function calling, operationId typically becomes the tool name the model selects and invokes. Omit it, and the tooling has to synthesize a name from the method and path (post_v1_invoices_invoice_id_finalize), which is noise where there should be signal.
Before:
paths:
/v1/invoices/{invoice_id}/finalize:
post:
responses:
'200':
description: OK
After:
paths:
/v1/invoices/{invoice_id}/finalize:
post:
operationId: finalizeInvoice
summary: Finalize a draft invoice so it can be sent
responses:
'200':
description: The finalized invoice, now immutable.
The spec requires each operationId to be unique across the API and treats the value as case-sensitive; it recommends following common programming naming conventions. Verb-noun names that state the task — createInvoice, finalizeInvoice, listPayouts — give a model the same affordance they give a developer skimming an SDK: the name alone tells you what the call does. ClickHouse's public spec is a good live example, with task-oriented operation names like "Create new service" carried through the operation metadata (profile).
Descriptions do the work your docs site can't
Every operation gets two prose fields: summary ("a short summary of what the operation does") and description ("a verbose explanation of the operation behavior," CommonMark allowed). Agents use them at different moments. The summary is what a model sees when it scans the tool catalog deciding which operation fits the task; the description is what it reads when constructing the call — preconditions, side effects, ordering constraints.
Schema-only specs fail here quietly. A spec can be perfectly valid with empty descriptions, and the agent will still construct calls from it — with nothing to tell it that invoices must be finalized before sending, that the endpoint is eventually consistent, or that deleting a customer cascades to subscriptions. Behavior that lives only on your marketing site or in a tutorial the agent never fetched may as well not exist at call-construction time. Write descriptions as if the reader will act on them immediately and alone, because that is precisely an agent's situation.
The same discipline applies to parameters and schema properties. customer_id with no description forces a guess about format; customer_id described as "ID of an existing customer (format: cus_ prefix)" removes it.
Examples turn schemas into working requests
A JSON Schema tells an agent what is permitted; an example shows what is normal. The spec gives you example and examples fields on parameters, media types, and headers, plus reusable Example Objects under components. Use them for every non-trivial request body:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateInvoiceRequest'
examples:
minimal:
summary: Smallest valid request
value:
customer_id: cus_8x4f2
currency: usd
Realistic examples anchor the values models generate — ID formats, enum casing, date formats, currency codes. In our scans, the specs that read best to agents pair schemas with worked examples throughout; MiniMax's llms.txt links directly to publicly reachable specs complete with request schemas and worked examples, so an agent can generate a typed client without touching an HTML page. Response examples matter as much as request examples: they are how an agent learns what "success" looks like before it has ever made a call.
Document errors in the spec itself
The specification is explicit that responses documentation is "not necessarily expected to cover all possible HTTP response codes," but SHOULD cover "the successful operation response and any known errors" — with a default response available for everything else. Known errors belong in the spec because error handling is where agents either recover or spiral: an agent that knows a 422 means "customer_id does not exist" can fix the call; an agent that gets an undocumented 422 retries the same broken request.
responses:
'201':
description: Invoice created in draft state.
'422':
description: Validation failed. The `code` field names the invalid parameter.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited. Retry after the interval in the Retry-After header.
default:
description: Any other error, in the standard Error shape.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Describe the recovery alongside the failure. Our scan of Escape found a valid spec whose typed error responses stop at descriptions like "Not found" — parseable, but with nothing telling an agent what to change. A consistent error response format with a machine-readable code, referenced from every operation via components, is what turns errors from dead ends into branch points.
Security schemes: state how to authenticate, machine-readably
Authentication is the first thing an agent must get right and the least guessable. The spec's components/securitySchemes supports five types — apiKey, http, mutualTLS, oauth2, and openIdConnect — and applying a scheme via security tells every consumer, human or model, exactly what credential goes where:
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: API key sent as a bearer token. Create keys in Dashboard → API.
security:
- bearerAuth: []
A spec without security schemes leaves the agent to infer auth from prose — header name, prefix, key location all guessed. Use the scheme's description field to say where credentials come from; see the API authentication glossary entry for the common patterns.
Version the spec, and keep it moving with the API
A stale spec is a subtler failure than a missing one: everything parses, the calls just target last year's API. Treat the spec as a build artifact, not documentation. Generate it from source or validate it in CI, bump info.version when the contract changes, and keep it consistent with your API versioning story so the spec an agent fetches describes the API version it will actually call. If you maintain specs per major version, serve the current one at the conventional path and link the rest. Discoverability regresses silently — a docs migration that drops /openapi.json breaks agent integrations without breaking a single human page.
What the Discry check verifies
The Discry scanner's OpenAPI check is deliberately mechanical: it probes the conventional spec paths and any spec URL declared in your llms.txt, then validates what it finds — the document must parse as JSON or YAML, declare an openapi (or swagger) version, and contain a paths object, from which it counts your documented endpoints. A spec that is found but fails validation is recorded with the reason. Everything is fetched the way most agents fetch: plain HTTP, no JavaScript. Full semantics on the OpenAPI signal page, and the wider method — discovery signals plus behavioral comprehension testing — on the methodology page.
The spec is where discovery and comprehension meet: one file that makes your API findable to automated discovery and constructable for the model that found it. Publishing it well is the single most direct answer to "make us AI-ready."
What grade does an AI agent give your API? Discry your API — free — 60 seconds, no signup.
See where your API stands.
Drop your docs URL. The scan probes the same signals this guide describes — in about a minute, free.