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.
1. Add the provider
Section titled “1. Add the provider”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
.jsonor.yamlspec.
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.
A spec split across files
Section titled “A spec split across files”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.
2. Set the poll interval
Section titled “2. Set the poll interval”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.
3. Work with the endpoints
Section titled “3. Work with the endpoints”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
.httpbuffer 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.
Deprecated and internal endpoints
Section titled “Deprecated and internal endpoints”Two facts the document can carry about an operation are surfaced consistently — in the navigator, Overview, Docs, and Spec Changes:
| In the spec | In the app |
|---|---|
deprecated: true | a quiet dep badge. Still listed, still callable — the point is that you can see you are calling one. |
x-internal: true | an 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.
4. Review what changed
Section titled “4. Review what changed”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.
What breaks, and whose work it breaks
Section titled “What breaks, and whose work it breaks”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.
Deprecated and still in use
Section titled “Deprecated and still in use”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.
Copy a subset of the spec
Section titled “Copy a subset of the spec”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.
5. Keep your edits
Section titled “5. Keep your edits”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:
- An overlaid group replaces the generated one wholesale — it is not a field-level merge.
- A group written as
null(or, forquery/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. - URL and method cannot be overlaid; they are the endpoint’s identity.
- 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.
Environments from the spec’s servers
Section titled “Environments from the spec’s servers”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 —
⌘Von 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.