The Moment
It was 2 AM. I was debugging why Claude couldn’t properly understand my API. I’d just pasted the URL to our Swagger UI documentation and asked:
“Learn this API and tell me how to authenticate.”
The response was frustratingly vague. It hallucinated endpoints. It got authentication wrong. Then I looked at what it was actually reading: 65KB of HTML with navigation chrome, JavaScript, CSS, inline SVGs, and repeated JSON schemas. No wonder the poor model was confused.
I realized then: we’re not documenting APIs for humans anymore. We’re documenting for agents.
The Research
I started digging into how AI models consume API documentation:
Token Analysis
I fed the same Petstore OpenAPI spec through different formats and counted tokens:
| Format | Tokens | Cost (Claude-4) |
|---|---|---|
| Raw OpenAPI JSON | ~18,000 | $0.18 |
| Swagger UI HTML | ~12,000 | $0.12 |
| llms.txt (compact) | ~4,200 | $0.04 |
That’s a 77% reduction in tokens. For APIs with hundreds of endpoints, the savings are even more dramatic.
Format Benchmarks
I tested what AI models actually understand:
- OpenAPI JSON: Accurate but expensive. Models get lost in
$refchains - Swagger/Redoc HTML: Model sees navigation, ads, code blocks it ignores
- Markdown: Good but verbose. Tables take many tokens
- llms.txt: Model reads it like documentation was meant to be read
The llms.txt spec (proposed by the community) defines a compact, line-oriented format that AI models consume efficiently.
The Insight
Here’s what I learned: agents consume more docs than humans ever will.
- A human visits your docs once, reads the endpoint they need, and leaves
- An AI agent reads your entire API spec every time someone prompts it
- With MCP servers and tool-use integrations, your docs are being parsed continuously
So we were optimizing documentation for the wrong user. The solution wasn’t to make docs prettier. It was to make them token-efficient.
The Build
I built SWAGENT to solve this problem. The goal: transform any OpenAPI spec into three outputs:
- llms.txt: Token-optimized, ~75% smaller than the original
- to-humans.md: Full markdown reference for developers
- index.html: Semantic landing page, zero JS
The optimization journey from 65KB to 16KB involved:
- Inline types:
{name*:string, age:integer}instead of verbose schemas - Required field markers:
*suffix instead of separaterequiredarrays - Auth shorthands:
JWT,KEY,OAuth2instead of full security scheme objects - Smart
$refresolution: Deep-expandallOf,oneOf,anyOfinline - ETag support: Agents can cache and avoid re-fetching unchanged docs
The Result
Here’s an end-to-end demo. Given this OpenAPI spec:
{
"openapi": "3.0.2",
"info": { "title": "Pet Store", "version": "1.0.0" },
"paths": {
"/pet": {
"put": {
"summary": "Update a pet",
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Pet" }
}
}
},
"responses": { "200": { "description": "OK" } }
}
}
}
}
SWAGENT generates:
# Pet Store - OpenAPI 3.0 v1.0.0
Base: https://api.petstore.io
## Auth
- JWT: Bearer token in Authorization header
## Conventions
- `*` = required field
- All fields string unless noted
---
## pet
### PUT /pet - Update a pet | JWT
Body: `{id:integer, name*, category:{id:integer, name}, photoUrls*:[string], tags:[{id:integer, name}], status:available|pending|sold}`
200: `{id:integer, name*, category:..., photoUrls*:[string], tags:[...], status:...}`
An AI agent reads this and immediately knows:
- The endpoint path and method
- Required fields (
name*) - Data types (integers, arrays, enums)
- Authentication requirements
No $ref chasing. No schema bloat. No navigation chrome.
Open Source
Today I’m releasing SWAGENT, the tool that makes your API agent-readable.
npm install swagent
It supports:
- Fastify, Express, Hono, Elysia, Koa, h3, NestJS adapters
- CLI for standalone generation
- OpenAPI 2.0 (Swagger) and 3.x
One command, three outputs. Your API docs finally serve both humans and machines.