OpenAPI — API Specification
What is OpenAPI?
OpenAPI (originally Swagger) is the dominant specification for describing REST APIs in machine-readable form. An OpenAPI document — typically a JSON or YAML file at /openapi.json or /swagger.json — enumerates every endpoint, the HTTP verb, the parameters each accepts, the response schema, the authentication scheme, and any custom extensions. The 3.x version is maintained by the OpenAPI Initiative, a Linux Foundation project with contributors from Google, Microsoft, IBM, Postman, SmartBear, and others.
For AI agents, OpenAPI is the difference between guessing your API surface and knowing it. An agent that can fetch your OpenAPI document has the same first-class affordance a generated SDK gives a human developer: every endpoint, parameter, type, and example, statically discoverable.
Why OpenAPI matters for agents
Agents calling REST APIs face an iteration cost problem. Without a schema, the loop is: guess the endpoint → call it → parse the error → guess the parameter shape → call it again → parse the next error. Three to five round-trips per endpoint is typical, and the agent burns tokens and clock time on each failed call.
With OpenAPI, the agent can:
- Pick the right endpoint by reading the
summaryanddescriptionfields against the user's intent. - Construct a valid request the first time by reading the parameter schema, including required fields, types, and enums.
- Parse responses correctly by binding to the response schema rather than improvising regex.
- Discover authentication from the
securitySchemesobject — including x402 payment requirements via thex-payment-infoextension AgentGrade looks for.
Agents that find OpenAPI on a site succeed on the first call at a measurably higher rate than agents that have to scrape docs. This is why a published OpenAPI spec is one of the highest-weighted checks AgentGrade runs on API-bearing sites.
How OpenAPI works
OpenAPI is a JSON or YAML document. It opens with metadata (info, servers), then enumerates every path under paths, then declares reusable schemas under components. Tools read it via HTTP fetch — no SDK or parser required beyond standard JSON handling.
A minimal valid OpenAPI 3.0 document:
{
"openapi": "3.0.3",
"info": {
"title": "Catalog API",
"version": "1.0.0",
"description": "Search the product catalog and place orders."
},
"servers": [
{ "url": "https://api.example.com" }
],
"paths": {
"/search": {
"get": {
"summary": "Search the product catalog",
"parameters": [
{
"name": "q",
"in": "query",
"required": true,
"schema": { "type": "string" },
"description": "Search query string"
}
],
"responses": {
"200": {
"description": "Search results",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/Product" }
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Product": {
"type": "object",
"properties": {
"id": { "type": "string" },
"title": { "type": "string" },
"price_usd": { "type": "number" }
}
}
}
}
}
Most web frameworks generate this automatically from route definitions (FastAPI in Python, Hono in TypeScript, Echo in Go, Spring's springdoc-openapi in Java). Hand-authoring is rarely necessary.
OpenAPI vs other agent-readability layers
| Spec | Format | What it answers | Agent uses it for |
|---|---|---|---|
| OpenAPI | JSON/YAML | Endpoints, parameters, types, auth | Constructing valid requests |
| SKILL.md | Markdown + frontmatter | How to use this service in prose | Picking which endpoint to call |
| MCP manifest | JSON-RPC | Tools exposed over persistent connection | Calling the server as a long-lived tool |
| llms.txt | Markdown | What is this site | Triage — is this site relevant? |
ai-plugin.json | JSON | Legacy ChatGPT plugin metadata | Plugin discovery (deprecated) |
OpenAPI is the schema-of-record. The other files refer to it; agents validate against it. A site with SKILL.md + OpenAPI gives an agent both the playbook and the formal contract.
The x-payment-info extension
OpenAPI supports custom extension fields prefixed with x-. AgentGrade looks for an x-payment-info object at the operation level that declares whether an endpoint is paid, the price, the protocol (x402, L402, MPP, SPT), and any payment URL.
{
"paths": {
"/api/order": {
"post": {
"summary": "Place an order",
"x-payment-info": {
"required": true,
"protocol": "x402",
"price_usd": "0.10",
"currency": "USDC",
"network": "base"
}
}
}
}
}
This makes the paid-endpoint signal machine-checkable without the agent needing to issue a probe request and parse a 402 response. AgentGrade verifies the declared payment info matches a live probe — declared-only without live verification scores lower than declared + verified.
Who's using OpenAPI
OpenAPI is genuinely universal. Major API platforms (Stripe, Twilio, GitHub, Cloudflare, AWS via its OpenAPI generator) publish OpenAPI specs as the canonical reference. Major framework adoptions:
- FastAPI (Python) — generates OpenAPI from type hints
- Hono +
zod— runtime-validated TypeScript routes that emit OpenAPI - NestJS (TypeScript) — decorator-driven OpenAPI generation
- Spring Boot + springdoc — annotation-based OpenAPI for Java
- Echo + echo-swagger — Go OpenAPI generation
- Rails + rswag — Ruby OpenAPI generation
For agents, the practical effect is that any modern API built in the last five years either has OpenAPI or can have it added with a single dependency.
How to add OpenAPI to your service
- Pick a generator. If your framework supports automatic OpenAPI generation, use it. Hand-writing is error-prone and goes stale.
- Serve it at a stable path.
/openapi.jsonis the conventional location;/swagger.jsonis accepted by most tools. Serving at the root or under/.well-known/are both fine. - Set CORS. Allow agent fetchers to read the document from a browser context:
Access-Control-Allow-Origin: *on the spec endpoint. - Declare
serverswith the production URL. Without this, agents construct request URLs against the wrong origin. - Add
descriptionfields. Every endpoint, every parameter. Agents read these to pick endpoints and infer semantics. - Declare
x-payment-infoif any endpoint requires payment. Match it against the live response. - Link from llms.txt or SKILL.md. Optional but helps agents discover the spec.
Common errors scanners flag
- Wrong content-type — the spec is served as
text/html(often a Swagger UI page) instead ofapplication/json. Agents that look for the spec at/openapi.jsonget the UI HTML and fail to parse. - Stale spec — the file lists endpoints that no longer exist or omits new ones. Auto-generation prevents this.
- Missing
servers[].url— agents that read this field to construct request URLs default to the same origin as the spec, which is often wrong (e.g., spec ondocs.example.com, API onapi.example.com). - No
descriptionon endpoints — agents can read the path, but without prose descriptions they cannot reliably pick between similar endpoints. - Declared
x-payment-infodoesn't match live probe — claims an endpoint is paid but live request returns 200 without a payment challenge, or claims free but returns 402. - CORS blocks the fetch — the spec is served but a missing
Access-Control-Allow-Originheader prevents browser-context agents from reading it.
FAQ
What's the difference between OpenAPI and Swagger?
"Swagger" was the original name; in 2015 it was renamed to OpenAPI when donated to the Linux Foundation. SmartBear retains the "Swagger" brand for tools (Swagger UI, Swagger Editor). The spec is OpenAPI; the tooling is often still called Swagger.
Do I need OpenAPI if I have SKILL.md?
Ship both if you have an API. SKILL.md is the "playbook" — prose, agent-readable. OpenAPI is the "contract" — formal, machine-validatable. Agents use SKILL.md to decide which endpoint to call and OpenAPI to construct the call correctly.
Should I serve at /openapi.json or /.well-known/openapi.json?
/openapi.json at the root is the dominant convention. Some agents probe /.well-known/openapi.json as a fallback. Serving both is fine.
OpenAPI 3.0 vs 3.1 vs 2.0 — does it matter?
3.1 is current; 3.0 is fine and widely supported. 2.0 (the original "Swagger 2.0" format) is still recognized but you should migrate. Tools handle all three; agents typically don't care about the version line.
Can I serve OpenAPI for a GraphQL API?
OpenAPI describes REST. For GraphQL, agents introspect the schema directly via the GraphQL endpoint. Some sites publish both an OpenAPI shim and the GraphQL endpoint.
Does AgentGrade penalize sites with declared-only payment info?
Sites with OpenAPI declaring x-payment-info but no live verification score positively but below sites where the live probe confirms the declared protocol. Both are better than no signal.
What about x-mcp-server or other extensions?
OpenAPI's x- prefix is open. AgentGrade currently looks for x-payment-info on paid-endpoint declarations. Other agent-relevant extensions may be added as the ecosystem standardizes.
How big can an OpenAPI spec get before agents struggle?
Multi-MB specs are common at large API platforms (Stripe's is ~10MB). Agents generally fetch and parse fine but may not load the full spec into their context — they'll search or chunk. Keep description fields concise; that's where most token weight lands.
Spec maturity
Universal industry standard. OpenAPI 3.x is maintained by the OpenAPI Initiative under the Linux Foundation. Supported by virtually every API tool, code generator, AI coding assistant, and modern web framework.
Learn more
- OpenAPI Specification — official spec and docs
- Swagger Editor — write and validate specs
- SKILL.md — companion prose layer for agents
- x402 — payment protocol that integrates via
x-payment-info - Agent Readiness — how OpenAPI fits into the bigger picture