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:

FormatTokensCost (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 $ref chains
  • 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:

  1. llms.txt: Token-optimized, ~75% smaller than the original
  2. to-humans.md: Full markdown reference for developers
  3. 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 separate required arrays
  • Auth shorthands: JWT, KEY, OAuth2 instead of full security scheme objects
  • Smart $ref resolution: Deep-expand allOf, oneOf, anyOf inline
  • 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.

GitHub →