By hand
engineer + editor- Time to first draft
- Weeks, usually next quarter
- Source of truth
- Memory, tickets, old docs
- How it goes wrong
- Incomplete, and stale on day one
- Verifiable
- By another reviewer
- Coverage
- Whatever got written
Redocly CLIexperimental command
generate-spec reads recorded HTTP traffic and writes an OpenAPI 3.2 description in under a second, with no model involved.
$ redocly generate-spec ./cafe.har -o openapi.yaml--with-ai$ # request GET /menu?category=dessert host: api.cafe.redocly.com # response 200 · application/json { "items": [{ "id": "prd_01jb…", "name": "tiramisu", "price": 650, "category": "dessert", "calories": 420, "createdAt": "2026-08-02T09:14:31Z" }] } # 4 more exchanges GET /menu?category=beverage · 200 POST /menu · 201 GET /menu-item-images/img_01jc… · 200 GET /menu-item-images/img_01jd… · 200
2 operations · 0.4sno AI needed
openapi: 3.2.0servers: - url: https://api.cafe.redocly.compaths: /menu: get: operationId: get-menu summary: List menu items parameters: - name: category in: query description: Filter by menu section. schema: { type: string } /menu-item-images/{menu-item-imageId}: …components: schemas: MenuItem: properties: price: type: integer minimum: 0 description: Price in cents. createdAt: type: string format: date-time
The problem
An OpenAPI description is the contract SDK generators, docs, and AI agents read to learn how to call your API. Writing it by hand is slow. Asking an AI to derive it from a large codebase gives you a convincing description that is impossible to verify. Traffic is the one source that cannot lie about what the API does.
How it works
Recording and inference are enough for a usable description. Refinement is opt-in, and every AI answer passes through the same gate before it is merged.
Put redocly proxy in front of the API and point any client at it – a test suite, a browser, a curl script. Or skip this step: HAR exports, Kong, Nginx, and Apache JSON logs, and NDJSON are read directly, as a file or a folder.
$ redocly proxy --target https://api.example.com --har ./capture.harcapture.harPath parameters, merged schemas, components, formats, and enums – all derived from the recorded exchanges with fixed rules. Finishes in under a second, and nothing leaves your machine. Use --server to scope a capture with several hosts or a gateway base path.
$ redocly generate-spec ./capture.har --title "Example API" -o openapi.yamlopenapi.yaml · baselineWith --with-ai, each operation is sent to the AI CLI already on your machine – claude, codex, or cursor – together with a small, shape-diverse sample of its own recorded exchanges. Operations run in parallel; tune it with --ai-concurrency.
$ redocly generate-spec ./capture.har --with-ai --ai-provider claude -o openapi.yamlopenapi.yaml · refinedA refined operation is merged only if it keeps its path and method, keeps every observed status code, keeps an operationId, does not redefine components it does not own, and passes the spec ruleset. Anything else falls back to the baseline, with the reason reported.
The acceptance lint is pinned to the built-in ruleset on purpose, so lint the result with your own redocly.yaml afterward. Then replay traffic against it with redocly drift on every test run, so the description never goes stale again.
$ redocly lint openapi.yaml && redocly drift ./capture.har --api openapi.yamlexit code 0Anatomy
The baseline is built without any model. Every line traces back to a rule and an observation – here is the Cafe API after five requests, and what each inference did.
The description knows only what the traffic showed. price is an integer because every observed price was whole. Endpoints nobody called are missing, and names like {menu-item-imageId} are mechanical. More traffic makes the hypothesis stronger – record an e2e run and feed it in.
AI refinement
POST /menu accepts multipart/form-data, and every value in a multipart form travels as a string. The baseline can only write down what it saw. With --with-ai, the same request body came back with correct types, constraints, descriptions, and a shape the Cafe team had designed by hand.
--with-aiprice and volume became integers with minimum: 0, containsCaffeine a boolean. The samples showed numbers; the model read them as numbers.
Beverages and desserts carry different fields, so the union is explicit: a oneOf over two allOf compositions, selected by a category discriminator. The handwritten Cafe description models it exactly the same way.
Descriptions and examples on nearly every property, constraints inferred from what a field means rather than from how often a value repeated.
Small prompts, strict checks. --with-ai adds meaning to the description without letting a model rewrite what the traffic proved.
1
operation per prompt, however large the capture
5
gates every AI answer must pass before it is merged
0
headers sent – tokens and cookies stay on your machine
100%
fallback to the deterministic baseline, with the reason reported
How much does --with-ai add? We recorded one full session on Redocly Cafe – errors included – generated the description twice, and scored both against the handwritten original.
--ai-concurrency. A rerun at concurrency 6 finished in under a minute.| Metric | Deterministic | --with-ai | Change |
|---|---|---|---|
| Response schemas | |||
| Properties recovered | Deterministic97.5% | --with-ai98.3% | +0.8 |
| Correct required lists | Deterministic69.2% | --with-ai72.2% | +3 |
| Documented formats recovered | Deterministic53.1% | --with-ai62.5% | +9.4 |
| Properties carrying a description | Deterministic0% | --with-ai97.5% | +97.5 |
| Request bodies | |||
| Properties recovered | Deterministic55.9% | --with-ai61.8% | +5.9 |
| Correct types | Deterministic78.9% | --with-ai100% | +21.1 |
| Correct required lists | Deterministic81.8% | --with-ai100% | +18.2 |
| Properties carrying a description | Deterministic0% | --with-ai85.7% | +85.7 |
Interoperability
Traffic parsing is shared with redocly drift, so any log that works there works here. AI refinement runs through the coding CLI already installed on your machine.
Traffic in
a file or a whole folder, auto-detected
Description out
to stdout or a file with -o
--with-ai providers
your local CLI, your subscription, nothing else to set up
Experimental: flags, output, and behavior may change – including breaking changes – while we shape the command with your feedback.
--server picks the host or base path to describe--ai-model and --ai-concurrency (default 4)Three commands from a recorded session to a description you can lint, publish, and hand to an agent. Add --with-ai when you want the explanations.
$ npm i -g @redocly/cli@latestRedocly CLI install guide$ redocly proxy --target http://localhost:9000 --har capture.harProxy command docs$ redocly generate-spec capture.har -o openapi.yamlGenerate-spec command docs