OpenAPI for AI Agents: Write Specs Agents Can Use
When an API is used by an AI agent, the OpenAPI specification becomes more than a contract for developers and API tooling. It also provides the information an agent uses to understand the operations it can perform. An agent framework can turn those operations into callable tools, then ask the model to choose among them, build arguments, and continue the task. This tutorial starts from the problem of thin or ambiguous specs, explains how to write OpenAPI fields for model consumption, and closes with how that work shows up when you publish on WSO2 API Platform.
Why thin OpenAPI specs fail AI agents?
Consider an API that provides these operations:
POST /createReservation
GET /getReservation
PUT /updateReservation
A user asks:
"Check whether my reservation is still active."
The agent has to determine which operation can answer that request. It needs to understand what each operation does, what inputs it requires, and when it should be used. If the specification only says getReservation "returns a reservation," the model has less context for making that decision.
A human developer can often fill in missing information from surrounding documentation, previous experience with the API, or knowledge of how similar APIs work. An agent does not have that same context. If the specification does not clearly describe an operation's purpose, inputs, outputs, or limitations, the model may have to infer them.
That can lead to incorrect tool selection or even invented API calls. For example, if an agent needs to cancel a reservation but the API provides no cancellation operation, an ambiguous specification may cause the model to assume that DELETE /reservations/{id} or a cancelReservation operation exists. Explicitly documenting what an operation does and, where useful, what it does not do gives the model a clearer boundary around the API's actual capabilities.
The questions an agent needs to answer map closely to the information in your OpenAPI document:
| What the agent needs to know | Where to describe it |
|---|---|
| What operation is available? | operationId, summary |
| When should I use it? | description |
| When should I not use it? | description |
| What arguments does it require? | parameters, requestBody |
| What values are valid? | Schema constraints, enum, format |
| What will it return? | responses, schemas |
| What does a realistic call look like? | example, examples |
| What happened if the call fails? | Structured error responses |
| Can I safely retry or perform the action? | x-* agent metadata |
| What order should operations be called in? | Supporting documentation and workflows |
This does not mean OpenAPI itself has changed into an agent specification. It means that when an agent consumes an API through an OpenAPI-based tool integration, information that may once have been treated as documentation quality now becomes part of the model's operating context.
Why your OpenAPI spec is now an AI interface?
Agent frameworks can consume OpenAPI operations and expose them as tools. The exact mapping depends on the framework. For example, in Google ADK, OpenAPIToolset creates a RestApiTool for each operation. The tool name is derived from operationId, while the operation's summary or description provides its description.
The important point is not that every framework maps OpenAPI fields in exactly the same way. It is that the OpenAPI document provides the structured and semantic information an agent integration can use to construct its tools. That makes the specification part of the interface between your API and the model.
If the specification is vague, the model has to infer intent. If the schema is incomplete, it has to infer inputs and constraints. If the available operations do not clearly establish their boundaries, the model may select the wrong operation or assume a capability that the API does not provide. Writing an OpenAPI specification for agents therefore means making those capabilities, boundaries, inputs, outputs, and constraints explicit.
How to write an OpenAPI spec agents can use
The rest of this article is the field-level guidance: what to put in descriptions, identifiers, schemas, errors, and extensions so a model can select and call operations accurately.
Write descriptions for the model, not a human skimming docs
Human readers skim headings, then expand details. Models weigh the text you give them as evidence for tool choice. Write API-level and operation-level descriptions as instructions to a colleague who will call the API without a sidebar of tribal knowledge.
API-level info.description should answer: what domain this API covers, what kinds of operations it offers (read, write, or both), and constraints that affect every call (auth style, rate limits, sandbox vs production). Agents often see this description first in a catalog index before they open a single operation. If two APIs in the catalog sound alike, this paragraph is what separates “orders for checkout” from “orders for warehouse replenishment.”
Operation-level summary and description should answer: when to use this operation, when not to use it, what it changes, and what success looks like. Prefer verbs and outcomes (createOrder, “Creates a paid order after stock is reserved”) over restating the path (POST /orders). Put prerequisites in the description when they are not obvious from the schema alone; for example, “Requires a valid reservationId from createReservation issued within the last 15 minutes.”
Clear descriptions that name supported outcomes and explicitly rule out unsupported ones give the model less room to invent calls such as a fabricated cancelReservation often before any code on the agent side needs to change.
# Thin leaves the model to invent intent
paths:
/reservations/{reservationId}:
get:
operationId: getReservation
summary: Get reservation
description: Returns a reservation.
# Stronger tells the model when to call and what it cannot do
paths:
/reservations/{reservationId}:
get:
operationId: getReservation
summary: Get a stock reservation by ID
description: >
Returns the reservation status, SKU, and held quantity.
Use this to confirm a hold before creating an order.
This operation is read-only. It does not cancel or release
a reservation; no cancel endpoint exists in this API.
Give every operation a clear, unique operationId
operationId is the stable handle frameworks turn into a tool name. Without it, generated names from method and path collide easily and drift when you rename paths. Collisions are especially painful when several similar CRUDs land in the same tool list and the model must pick among near-identical names.
Rules that hold up in practice:
- One unique
operationIdper operation in the document. - Verb-first and outcome-oriented:
listProducts,createOrder,refundPayment. - Stable across versions when the semantic meaning is unchanged.
- Avoid path noise: prefer
getOrderovergetV1OrdersId.
In Google ADK, listPets becomes the tool list_pets. Other frameworks may map fields differently, but a clear, unique operationId remains the safest default. If you omit it, some toolsets synthesize a name from path and method usable in demos, fragile in a large catalog.
Document parameters, request bodies, and responses completely
Agents construct arguments from JSON Schema derived from your parameters, requestBody, and responses. Missing required, vague types, or “object with no properties” invite invalid calls.
For each operation, cover:
- Path, query, header, and cookie
parameterswithtype,description, andrequiredwhere applicable. requestBodycontent schemas with property descriptions and required fields.- Response schemas for success and expected error statuses not only
"200": { "description": "OK" }. - Where helpful, realistic
exampleorexamplesvalues that match production shapes. Prefer concise descriptions first; examples support the schema, they do not replace it.
parameters:
- name: reservationId
in: path
required: true
description: Identifier returned by createReservation.
schema:
type: string
example: res-8f3a2c1b
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [customerId]
properties:
customerId:
type: string
description: Customer placing the order.
example: cust-10042
responses:
"201":
description: Order created.
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
"409":
description: Reservation expired or already consumed.
content:
application/json:
schema:
$ref: "#/components/schemas/ProblemDetails"
If a field is an enum in practice, declare enum. If a string is a date, use format. Models cannot infer constraints you leave in a wiki.
Treat $ref components the same way: shared schemas still need property descriptions. An agent that only sees "$ref": "#/components/schemas/Order" with an empty component schema learns nothing about lineItems or currency. Put the detail where the schema lives, and keep operation descriptions focused on when to call.
Pagination, filtering, and field selection deserve explicit parameter docs. Agents often over-fetch when limit, cursor, or fields are undocumented optional query params. One sentence per parameter “Maximum page size is 100; default is 20” prevents a burst of oversized list calls that look like abuse to your gateway.
Prefer machine-readable error codes
Keep error design short here, but do not leave agents matching free-text message strings. Structured errors with stable codes let tools branch without scraping prose. RFC 9457 Problem Details is a solid baseline: the five standard members are type, title, status, detail, and instance, plus an application-specific code when you need one.
Document those schemas under responses the same way you document success bodies. An agent that receives 409 with code: reservation_expired can choose a recovery path; an agent that receives only "Something went wrong" may retry or attempt to infer a path forward. For deeper API error design patterns, treat this as a pointer, not a full error-catalog tutorial.
Extend OpenAPI with agent metadata (x-*)
OpenAPI allows vendor extensions (x-*) for metadata that the core specification does not define. For agent-oriented APIs, you can use these extensions to describe properties such as side effects, retry safety, confirmation requirements, and data sensitivity. These extensions are organization-defined rather than universally standardized, so use a consistent structure and document how your tooling should interpret them. Agent frameworks do not automatically understand a given x-* shape unless you wire that support in.
One practical pattern:
x-ai-metadata:
sideEffects: true # changes durable state
retrySafe: false # caller must not blindly retry
requiresConfirmation: true # high-impact write
sensitivity: customer-pii # classification label for policy
Attach extensions at the operation level (and on schemas when needed). Your gateways, MCP generators, or lint rules can read them when you teach those tools the contract. Keep extensions additive: they annotate intent; they do not replace a clear description.
A simple rule: if a runbook would warn “do not retry,” “ask the customer first,” or “contains PII,” put that in the description, in x-ai-metadata, or both. Prose helps the model; structured extensions help the automation you build around the spec.
Guides and workflows the spec cannot carry alone
OpenAPI excels at structure. Some guidance still belongs in supporting documents and published workflows without restating the extension section above.
Use attached docs for getting-started paths, authentication walkthroughs, environment differences, known limitations, and changelogs. Agents that can fetch Markdown or HTML docs alongside the spec make fewer wrong assumptions about auth headers and sandbox versus production behavior.
Use multi-step workflows when call order is mandatory. If creating an order always requires reserve-then-create, encode that sequence as a workflow artifact (for example Arazzo) rather than hoping the model reconstructs it from low-level operations. That topic is complementary to writing better operation prose: good descriptions help tool choice; workflows remove unsafe improvisation for known tasks.
What a well-specified operation looks like
Put the guidance above side by side. The left column is a thin operation that leaves the model to guess. The right column is the same capability written so an agent can select and call it with less improvisation:
Thin operation Well-specified operation
───────────────── ──────────────────────────
operationId: missing operationId: createOrder
summary: "Create" summary: "Create order from reservation"
description: "Creates order" description: when to call, prerequisites,
what it mutates, what it does not do
parameters: id (string) parameters: typed, required, examples
requestBody: object requestBody: required fields + examples
responses: 200 OK responses: 201 schema + 409 problem+json
extensions: none x-ai-metadata: sideEffects, retrySafe, …
The left column produces a tool the model must guess how to use. The right column produces a tool whose name, prose, schema, and safety hints align with how agents actually select and call APIs.
Pre-publish checklist
Use this as a final pass before you publish the OpenAPI document or before you expose the API to agents. It is a short review of the field-level decisions covered above, not a separate process.
- API-level description states domain, operation kinds, and global constraints.
- Every operation has a unique, verb-first
operationId. - Every operation has a model-oriented
summaryanddescription(including what not to use it for). - Parameters,
requestBody, and success/errorresponseshave complete schemas. - Critical inputs and outputs have clear descriptions; add realistic examples where they help clarify shape.
- Errors use stable, machine-readable codes or Problem Details, not only free text.
- Side effects, retry safety, and sensitivity are documented in prose and/or
x-*extensions. - Supporting docs cover auth, limits, and edge cases the schema cannot express.
- Multi-step sequences that must not be improvised are published as workflows where appropriate.
- You have validated the document (OpenAPI syntax + your style rules) before publish.
How this looks in practice on WSO2 API Platform
Once your specification follows the guidance above, the platform’s role is to expose and control your API, not to rewrite your documentation.
On WSO2 API Platform, Publishing an API to the API Portal makes it available through agent-facing discovery surfaces when agent visibility is enabled. These surfaces include portal’s llms.txt index, catalog Markdown (apis.md), per-API Markdown documentation, and the raw OpenAPI specification download. Your API-level description is often among the first pieces of content an agent reads when discovering your API.

Publishers can set agent visibility so an API stays in the human portal but is omitted from those machine-readable endpoints when it should not be agent-callable. For ordered tasks, portal API Workflows (Arazzo-based) give agents a vetted call sequence instead of leaving order to inference.
In short: write the OpenAPI fields for the model; the API Portal then exposes description, spec, and docs to agents through llms.txt and Markdown endpoints once you publish.
You can also govern these APIs at the organization level. WSO2 API Platform provides governance rulesets and policies that let you validate API definitions across the organization, including newly created API proxies. This allows you to enforce the same API design requirements consistently, such as unique operationId values, meaningful operation descriptions, and documented parameters and responses instead of relying on authors to apply these guidelines manually. See Governance rulesets and policies for an overview, and Govern an API proxy for instructions on creating and applying a ruleset and policy.
For the broader shift from human-centric APIs to agent consumers, see APIs Weren’t Built for AI, Now What?. For the publisher checklist on discovery and visibility, see Make an API AI-Ready.
Frequently asked questions
Does every agent framework use operationId as the tool name? Many do, including Google ADK. Others may prefer summary or generate names from the path. A clear, unique operationId remains the safest default across stacks.
Is x-ai-metadata an official OpenAPI field? No. It is an example of an x-* vendor extension pattern. Standardize the shape inside your organization and document it for producers and consumers.
Should I expose every operation to agents? No. Prefer outcome-oriented operations, hide or omit unsafe internals, and use workflows for mandatory sequences. Spec quality and surface-area design work together.
Conclusion
Agent frameworks turn OpenAPI operations into tools. That makes operationId, summary, description, schemas, examples, and clear error models part of the runtime interface, not optional docs. Write those fields for a model that must choose and call without tribal knowledge, annotate safety with consistent metadata, and put multi-step order in workflows when improvisation is unsafe. Do that work in the spec first; discovery platforms can only expose what you actually wrote.