Skip to content

Importing OpenAPI

For OpenAPI you have two paths, and the cheap one is usually right.

An OpenAPI document describes paths, methods, parameters, bodies, and responses. The direct importer translates all of it:

Terminal window
reqloom import openapi.yaml --out my-api
reqloom lint --project my-api
Terminal window
Imported 11 resources, 105 operations into my-api/reqloom.yaml
LINT OK — 0 actors, 11 resources, 105 operations. No errors.

Note the 0 actors. That’s not a bug in the importer — it’s what a spec is.

Two things, and they’re the two Reqloom is built around:

Actors. securitySchemes says a bearer token is required. It does not say which endpoint issues one, what credentials it takes, or what the response looks like. That’s operational knowledge no spec carries.

Dependency order. A spec lists POST /orders and POST /orders/{id}/pay as peers. Nothing states that the second needs the first, or that the {id} comes from the first’s response body. {id} is just a string parameter.

So the importer’s output is a flat inventory. Turning it into workflows is the work, and it’s where the AI importer helps — or where you do it by hand for the handful of chains you actually care about.

The pragmatic route for a large spec:

  1. Direct import for the mechanical translation — paths, methods, headers, bodies. Deterministic and free.
  2. The AI importer pointed at the same spec, to propose actors and dependency edges. Read the plan it produces; it’s five minutes, and it’s where the guessing is visible.
  3. Hand-wire the chains you’ll test. Usually a handful of depends_on lines and one actor.

That way the LLM never touches the parts a spec states precisely, and only advises on the parts it doesn’t.

Find the login endpoint in the imported output and turn it into an actor:

actors/user.yaml
name: user
auth:
strategy: simple
method: POST
path: /auth/login
body:
email: "{{env.user_email}}"
password: "{{env.user_password}}"
expect_status: 200
extract:
token: $.data.accessToken
inject:
headers:
Authorization: "Bearer {{user.token}}"

Then delete the per-operation Authorization header the importer generated and add actor: user. One edit per operation, and the token is never pasted anywhere.

Imported paths keep literal values from the spec’s examples:

get_order:
method: GET
path: /orders/1 # ← literal from the spec

Replace the literal with a reference, which creates the dependency implicitly:

get_order:
method: GET
path: /orders/{{order.order_id}}
depends_on: [order.create]
CheckWhy
expect_status matches realitySpecs often document 200 where the API returns 201
Required vs optional body fieldsImporters include documented examples, not minimal valid bodies
Literal path IDs/orders/1 should become a reference
Enum valuesA spec’s first enum value isn’t necessarily valid for your data
$ref compositionDeeply composed schemas may flatten in surprising ways

Specs drift from implementations. Treat imported expect_status and bodies as claims to verify on the first real run, not facts.

If the spec is generated but stale — common with hand-maintained OpenAPI — the direct importer will faithfully reproduce its errors. In that case a curl log of real traffic is better input, even though it’s messier. See importing curl logs.