Skip to content

Bind an OpenAPI source

This is the task page for working with a bound spec day to day. For what “live binding” means conceptually, see Spec source.

Add a source from the navigator’s API providers section. Give it either:

  • a URL — http://localhost:8080/v3/api-docs, https://api.example.com/openapi.json, anything that serves the document; or
  • a file path to a .json or .yaml spec.

If you do not know the path, give Tinspec the service’s base URL and let it discover the spec: it probes well-known documentation locations only, never resource paths.

Endpoints appear in the navigator grouped by OpenAPI tag.

Large specs are rarely one document. openapi.yaml references ./schemas/user.yaml#/User, which references ./common/address.yaml, and a generator will happily emit fifty of them.

Tinspec bundles the document before generating anything: every external $ref — a relative file path or an http(s) URL — is fetched, inlined, and rewritten to a local pointer, repeatedly, until the document is self-contained. Nesting works, because each inlined subtree’s own refs are resolved against the file it came from. The walk is bounded (16 rounds of nesting, 256 documents) so a cyclic or hostile ref graph terminates.

A ref that cannot be loaded is reported, not skipped. The provider’s Overview tab shows “N references in this spec could not be resolved” and lists them, because the alternative — what happened before — was an endpoint that quietly arrived with no parameters and an empty body, with nothing on screen saying why.

The bundled document is also what gets cached for offline use and what the OpenAPI-subset export copies, so both stay resolvable with the referenced files out of reach.

Each provider has its own refresh interval, or falls back to the global default. Choose it by how fast the spec actually moves:

  • A spec generated by the service you are running locally changes on every rebuild — a short interval keeps up.
  • A stable third-party spec does not need to be fetched every minute.

When the document is unreachable, the last successful fetch is served from the cache and your endpoints keep working.

A file-backed spec is watched, not just polled

Section titled “A file-backed spec is watched, not just polled”

A local openapi.yaml is not re-fetched on a tick — it is stamped. Each tick takes the modification time and size of the root document and of every local file it $refs, joins them, and compares. Only a changed stamp triggers a re-resolve, so watching a spec split across a hundred schema files costs a hundred stat calls, not a hundred reads.

The practical effect: editing schemas/user.yaml beside the app runs the whole Spec Changes flow, the same as editing the root. When a spec spans more than one file, the provider’s Overview tab says how many are being watched — the only way to tell the walk found the referenced files and not just the root.

One limit, stated where it is implemented: a remote $ref inside a local document is a real part of the spec and is not watched — nothing on this machine can watch it. It follows the ordinary poll interval instead.

Open an endpoint and use whichever view fits:

  • Docs for reading — typed parameters, body fields, documented response codes, a cURL snippet, and inline Try it.
  • Form for building — Params / Headers / Body / Auth / Tests / Scripts / Chain / Settings / Gateway tabs.
  • Editor for a runnable .http buffer with spec-aware completion.

Bodies are pre-filled from the request schema. Where you have sent that endpoint successfully before, Tinspec can also fill from a real send: 2xx request bodies from your own history, ranked by recency and whether their tests passed, with secrets scrubbed out and replaced by {{placeholders}}. It is offered in the Body autofill menu and as Send with last successful in Docs view.

Two facts the document can carry about an operation are surfaced consistently — in the navigator, Overview, Docs, and Spec Changes:

In the specIn the app
deprecated: truea quiet dep badge. Still listed, still callable — the point is that you can see you are calling one.
x-internal: truean int badge, and the endpoint is hidden from listings by default.

x-internal is the de-facto “do not publish this” extension, and hiding those endpoints is what you usually want. But a count that quietly lies is worse than a long list, so every surface that filters them says so: “3 internal hidden”, and clicking it turns them on. The switch is Settings → Endpoints → Show internal endpoints.

Nothing else is filtered. An internal endpoint opened directly stays reachable.

Open Spec Changes after a deploy. It lists endpoints added, removed, and modified since you last acknowledged, and expands a modified one to show the change field by field. A removed endpoint keeps its last-known shape so you can still see what it was. The endpoint’s declared security requirement is compared too, so an operation that quietly stopped requiring a scope reads as a change rather than as nothing.

Mark things seen explicitly — per row, per provider, or all. Opening an endpoint does not acknowledge it.

Above the change list sits a Breaking changes block, and the split of labour behind it is worth knowing because it is the reason the block is short enough to read.

The engine decides what is breaking. Every poll is projected into one protocol-agnostic shape and diffed against the previous one, and each difference is classified by a rule, direction-aware: tightening an input breaks callers, loosening an output breaks consumers. So requiredInputAdded, inputRemoved, outputRemoved, typeChanged and shapeChanged are breaking; outputAdded and operationDeprecated are not. A diff where everything is flagged is a diff nobody reads.

Tinspec decides who it breaks, because only your machine holds your saved requests, your chains and your overlays. Each row says “hits 2 of your chains and 1 saved request”, expands to the individual steps and files, and opens them. Rows are ordered impact first, then breaking first. Every change line also carries its stable rule id — that is the vocabulary a CI allow-list is written against, not the prose sentence beside it.

Two honest edges the view keeps:

  • “No breaking changes” and “nothing was checked” never look the same. A source polled for the first time seeds a baseline instead of reporting every operation as added, and a .proto-backed gRPC provider has no live description to compare against. The block says how many sources were not classified.
  • A removed operation cannot be attributed. Impact is resolved against the endpoints that currently exist, so a row for an operation the spec deleted says “nothing of yours calls it” even when a chain still does. Removal is still reported and still flagged breaking — but check the callers yourself.

A separate amber block lists deprecated operations your workspace still calls, most-used first, with the chains and saved requests that call them. A badge is a note; this is the thing that will cost you an afternoon the day the API owner finishes the job.

Tick endpoints (or a whole tag group) and copy a minimal, valid OpenAPI document containing just those operations, their path-level parameters, every transitively referenced schema, and the security schemes. Choose YAML or JSON.

This is the right thing to paste into a ticket, attach to a review, or hand to an agent — far better than a 40,000-line document or a screenshot.

Edit a generated endpoint and Tinspec records an overlay: the field groups that differ from the generated request, stored as YAML in .tinspec/overlays/<provider-id>.yaml and re-applied on every refresh. The editor shows an Edited chip and a Reset to spec action.

Nine groups can be overlaid — body, query, headers, auth, grpc, graphql, prerunChain, routeMatcher and settings — so a per-endpoint timeout survives the next poll the same way an edited body does.

Four things to know:

  1. An overlaid group replaces the generated one wholesale — it is not a field-level merge.
  2. A group written as null (or, for query/headers, as an empty map) means you deleted the generated value, which is a different thing from absent, meaning you never touched it. Without that distinction, deleting a generated header would not survive the next poll.
  3. URL and method cannot be overlaid; they are the endpoint’s identity.
  4. If the spec changes underneath your edit, you get an amber banner: Keep edits or Reset to spec. Nothing merges silently.

scripts is not one of the nine, so a pre/post hook written on a generated endpoint is not preserved across a refresh. If you need one, keep it on a saved request instead.

The same file also holds responses you save as examples for that endpoint. Those are records of what the API returned, not edits to what gets sent, so Reset to spec leaves them alone — deleting them is its own action.

Overlays are committable, so a teammate who pulls your project gets your endpoint tweaks. They need a project folder; a folderless project keeps them for the session only.

An OpenAPI document usually declares several servers — production, staging, sandbox. Tinspec builds endpoint URLs from the first one, and the rest would otherwise be invisible: the document knows about three environments and the app would show none of them.

The provider’s Overview tab lists every declared server, marks the one endpoint URLs were built from, and offers Create environments from this spec’s servers. Each becomes a project environment holding baseUrl plus any variables the server declares, named after the server’s description (or its host when it has none). Names that already exist are skipped, never overwritten — so running it twice creates nothing.

What it does not do, and the dialog says so before you press it: if the spec declares absolute server URLs, the generated endpoints are absolute too, {{baseUrl}} appears nowhere in them, and selecting one of these environments does not redirect them. What the environments are good for is supplying {{baseUrl}} to requests you author or fork, to chain steps, and to the gateway base URL field — which is the supported way to point this provider’s endpoints at another host.

The exception is a document with no absolute server URL at all. There the engine falls back to {{baseUrl}}/path, and the environment really does decide where the request goes. The dialog tells you which case you are in.

Auth providers from the spec’s securitySchemes

Section titled “Auth providers from the spec’s securitySchemes”

The document you are already polling states, in machine-readable form, how the API expects to be authenticated: the grant, the token URL, the authorization URL, the scopes. Retyping that into a form is work the document has already done.

Add auth provider offers From your API spec first when a bound document contains anything usable, pre-filled from components.securitySchemes. You confirm, then supply the one thing the document cannot carry — the client secret, which goes to the keychain as a reference, never into the file.

Schemes that are real but are not providers are listed too, with a reason and somewhere to go instead: a bearer token or an API key is a credential, not a way to obtain one, so it belongs on the request as inline auth; the implicit and password grants and mutual TLS are named as things Tinspec will not automate. Nothing is silently dropped from the list.

The other half of the same question is the Auth Map, which draws how credentials wire to your API providers. Its header carries a count of endpoints whose document declares a security requirement that no binding satisfies — “N declare auth with nothing bound”. Those will send unauthenticated. An explicit security: [] and an alternative of {} mean “no credential required” and are never counted.

See Auth providers for what to do with a provider once it exists.

Turning an endpoint into a request you own

Section titled “Turning an endpoint into a request you own”

A spec endpoint is a live view, not a file. It has no Save button: a saved copy of something the next poll is about to regenerate raises the question of which one wins, and that question already has two clearer answers.

  • Want your change to follow the endpoint as it evolves? Edit it. The overlay is re-applied on every refresh, and the spec changing underneath it is surfaced rather than merged.
  • Want a stable copy that stops tracking the spec? Right-click the endpoint → Copy as cURL, then bring it back in as a request — ⌘V on the welcome pane, or the curl box in the Import stage of the add-source dialog — and save it into a collection. The copy is yours: no overlay applies to it and no poll touches it. That is the right shape for a reproduction case you need to stay exactly as it is.

Either way, the endpoint stays in the navigator and keeps following the document.