AgentScan logoAgentScan
Guides8 min read

OpenAPI for AI agents: specs that get used

Most OpenAPI files are technically valid but unreadable by agents. Eight rules that turn an OpenAPI document into something an LLM can actually call.

OpenAPI for AI agents: specs that get used

OpenAPI was designed for SDK generators and human developers. AI agents in 2026 read the same files but use them very differently. They scan summaries, weigh examples heavily, and skip endpoints whose description is empty or duplicated. A spec that passes lint can still be unusable by an agent.

This is the practical rewrite checklist for OpenAPI documents that AI assistants actually pick up and call.

What agents look at

In our crawler observation, agents reading OpenAPI prioritize fields in this order:

  1. summary and description on each operation
  2. operationId
  3. Examples in requestBody and responses
  4. tags and the document-level info.description
  5. Parameter-level description
  6. Auth scheme

Most other fields are noise to an LLM. Optimize accordingly.

Eight rules that matter

1. Every operation has a one-sentence summary

The summary field is the agent's hint about whether to even open the operation. Vague summaries get skipped.

# Bad
summary: Customer endpoint

# Good
summary: Get a customer by ID, including subscription status

Aim for 60-90 characters. Verb-first.

2. The description teaches the agent how to use the operation

The description is where you explain context, side effects, idempotency, and rate limits. Agents lean on this for reasoning. Three to six sentences is right. One-liners are wasted.

description: |
image: "/blog/openapi-for-agents.png"
  Returns the customer record matching the provided ID. The response includes
  subscription status, billing address, and the most recent invoice ID.
  Idempotent. Returns 404 if the ID does not exist. Subject to per-account
  rate limit of 600 requests per minute.

3. operationId is stable, snake_case, and unique

Agents use operationId as the identifier when the assistant decides to call your tool. It should not change between releases.

operationId: get_customer_by_id

Avoid auto-generated IDs from frameworks that change with route renames.

4. Required fields are marked

LLMs interpret required: true as a strong signal. If a parameter is required and not marked, agents will guess wrong and fail.

5. Provide an example in every request and response body

Examples are the highest-signal field for agent code-gen. The schema teaches structure; the example teaches plausibility.

requestBody:
  content:
    application/json:
      schema:
        $ref: "#/components/schemas/Customer"
      examples:
        typical:
          summary: A typical signup
          value:
            email: "user@example.com"
            plan: "pro"
            company: "Acme Inc"

Examples should reflect real patterns, not minimum-required-fields scaffolds.

6. Use $ref carefully, but not paranoidly

Heavy use of $ref is fine for code generators and unfriendly for an LLM that has to dereference the schema mentally. The compromise: use $ref for shared types but keep examples inline so the agent does not have to chase references to understand the shape.

7. Use tags to group related endpoints

Tags are how the agent organizes a long spec. Three to seven well-named tags beats forty redundant ones.

tags:
  - name: customers
    description: Customer record management
  - name: subscriptions
    description: Plan changes, cancellations, and invoicing

Each operation should have one to two tags.

8. Document the auth scheme explicitly

LLMs cannot guess your auth flow. Be explicit:

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        API key issued via the dashboard. Send in the Authorization header
        as `Bearer <key>`. Keys do not expire automatically.

security:
  - bearerAuth: []

If you support OAuth, point to the discovery URL:

components:
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://example.com/oauth/authorize
          tokenUrl: https://example.com/oauth/token
          scopes:
            read: Read access
            write: Write access

Document-level fields

The info block is the first thing an agent reads. Treat it like a tool description.

info:
  title: Acme Customer API
  version: "1.2.0"
  description: |
    REST API for managing customers, subscriptions, and invoices in Acme.
    All requests must be authenticated. Responses are JSON. The API is
    versioned via URL path (e.g. /v1, /v2). Breaking changes increment
    the major version.
  contact:
    email: api@acme.com
  license:
    name: Proprietary
servers:
  - url: https://api.acme.com/v1
    description: Production

A short description here tells the agent what the API is, how to authenticate at a high level, and how versioning works. Save the agent from having to infer.

Where to host the spec

Two patterns work well in 2026.

A stable URL at a predictable path

https://api.acme.com/openapi.json
https://api.acme.com/openapi.yaml

Both forms welcome. Pick one as canonical and link the other.

Reference it from /.well-known/api-catalog

This is where the API Catalog Builder and RFC 9727 come in. Each entry in the catalog has a service-desc link pointing at the OpenAPI spec:

{
  "linkset": [
    {
      "anchor": "https://api.acme.com/v1",
      "service-desc": [
        {
          "href": "https://api.acme.com/openapi.json",
          "type": "application/json"
        }
      ]
    }
  ]
}

Agents that fetch your /.well-known/api-catalog will discover the spec without HTML scraping.

Validating

Two tools cover most cases:

  • The official Swagger or Redoc validators for raw spec validity.
  • The Structured Data Validator on AgentScan does not check OpenAPI directly but is useful for the surrounding JSON-LD.

For agent-readability beyond schema validity, paste your spec into a couple of major assistants (Claude, ChatGPT) and ask them to call a representative endpoint. If the assistant asks clarifying questions about field shapes, your descriptions and examples are too thin.

Versioning without breaking agents

When you bump the API, agents that depend on it can break unpredictably. Two practices help.

  1. Path versioning over header versioning. /v1/customers is far easier for agents to call than Accept: application/vnd.acme.v1+json. Most LLMs do not reliably set custom Accept headers.
  2. Keep old versions live. Even if you stop adding features, keep /v1 returning 200 well past the deprecation date. Agents that learned /v1 will keep using it; aggressive sunsets break their workflows.

Common mistakes

  • Auto-generated specs from a framework with empty descriptions. Most modern frameworks (FastAPI, NestJS, etc.) need explicit description arguments. Empty defaults are silent agent killers.
  • Examples that show a single field. An example with one of seventeen fields filled in teaches the agent to omit the other sixteen.
  • Schemas that drift from the runtime. If your spec says a field is required but the runtime treats it as optional, the agent will follow the spec and break. Generate the spec from a single source of truth.
  • Missing 4xx responses. Document at least the common error envelope for each operation. Agents handle errors better when the shape is known.

What good looks like

A 2026 OpenAPI document an agent can comfortably use:

  • Document-level info.description is two paragraphs and covers auth + versioning.
  • Every operation has a 60-90 char summary and a multi-sentence description.
  • Every operation has a stable, snake_case operationId.
  • Every request and response body has at least one realistic example.
  • Auth scheme is explicit with an English description.
  • The spec is hosted at a stable URL and linked from /.well-known/api-catalog.

A document like that gets called. A document missing half of those gets ignored.

Why this matters

OpenAPI is the most leverage you have over how agents call your API in 2026. Most developer-facing API teams already maintain a spec. The marginal investment to make it agent-friendly is small. The result: assistants that can construct correct calls on the first try, instead of guessing and asking the user to debug.