Local-first · Spec-driven · Multi-protocol

Every endpoint, already there.

Point Tinspec at a running service's OpenAPI URL — endpoints materialize, documented and runnable. Send HTTP, gRPC, GraphQL, and WebSocket, wire requests into visual chains, let auth providers handle every token, and keep it all in files you can commit.

macOS · Linux — free, no account

orders-api — tinspec
order-by-id.http checkout-flow
### Order by id
GET {{baseUrl}}/api/orders/4271
Authorization: Bearer {{token}}
Accept: application/json

▶ send  ·  ⌘⏎

200 OK · 38 ms · 412 B

{
  "id": 4271,
  "status": "shipped",
  "total": 184.50,
  "currency": "EUR"
}

HTTP

requests, uploads, cURL round-trip

gRPC

unary + client/server/bidi streaming

GraphQL

query · variables · headers

WebSocket

connect, send, watch live

SSE

event streams render live

One engine, one request abstraction — every protocol gets the same auth, variables, and history.

Three steps, no setup

From a spec URL to a passing chain.

01

Point it at a spec

Paste a live OpenAPI URL or pick a file. Endpoints appear as files in the navigator, documented and runnable — and they refresh when the API does.

https://api.internal/v3/api-docs · live

02

Send, then chain

Hit ⌘⏎ in the Form or the runnable .http editor. Click a value in the response to extract it, and wire the next request on the chain canvas — auth providers keep the tokens flowing.

POST /auth/login → {{token}}GET /orders

03

Commit it with the code

Requests, chains, auth providers, and gateways are plain YAML in the project folder. Review them in a pull request; secrets never leave the OS keychain.

orders.yaml · .tinspec/chains/checkout-flow.yaml

In the app today

Built around the spec, not the request list.

Spec-first, just-in-time

Point Tinspec at a live OpenAPI URL — a springdoc /v3/api-docs, a file, anything. Endpoints materialize instantly and stay bound to the spec: refresh re-resolves, so you test the API as it is now — not a stale snapshot you authored by hand. Goes offline? The last fetched spec keeps working.

https://api.internal/v3/api-docs live · 4s ago

GET /api/orders — List orders

GET /api/orders/{id} — Order by id

POST /api/orders — Create order

DEL /api/orders/{id} + just appeared in the spec

chain · checkout-flow

POST /auth/login

token

POST /api/orders

Bearer {{token}}

orderId

GET /orders/{{orderId}}

✓ 200 · 41ms

nodes: condition loop script assert generator

Visual request chains

Wire requests on a canvas. Extract a value from one response — click a field in the JSON and it becomes a variable the next step uses. Branch on conditions, loop, transform data, run JavaScript, assert what came back. Watch every event live as the run flows across the graph. Saved as a file, runnable whole or node-by-node.

Stop pasting JWTs

Define an auth provider once — a login script, or a first-class integration (Keycloak, Clerk, Auth0, …). Tinspec fetches the token, caches it, refreshes on expiry, and injects it into every request and chain. Switch the user you send as without touching a header — and when you do need the raw JWT, it's one click to copy.

auth provider · clerk-dev

kind integration · clerk

send as alex@acme.io (acme tenant)

→ injects Authorization: Bearer …

✓ token cached · refreshed on expiry · copy in one click

ai assist · ask

“What does POST /api/orders expect?”

A JSON body with items[] (productId, qty) and an optional couponCode. Auth is a bearer token — the clerk-dev provider covers it…

context sent: OpenAPI subset · 3 endpoints — previewed before anything leaves · never response bodies, never secrets

AI on your side of the wire

Bring your own Anthropic key and ask questions about the API you're staring at, or have a request drafted from the spec. Off by default, and scoped hard: you preview the exact OpenAPI subset that leaves the machine — response bodies and secrets never do.

An editor, not a wall of forms

A Zed-style shell — file-tree navigator, tabs, command palette. Endpoints open as runnable .http buffers in Monaco with spec-aware completion for params, headers, and body fields.

Reference docs, built in

Every endpoint gets a Stripe-style reference: typed parameters, request-body fields with nested attributes, response codes — plus a cURL sample and inline “Try it”.

Gateway-aware URLs

Import a Kong, Nginx, or Envoy config and Tinspec rewrites each request to its gateway-facing URL — including gRPC→REST transcoding for annotated methods.

Edits that survive the spec

Tweak a generated endpoint — body, params, auth — and the edit persists as an overlay. A spec refresh never silently clobbers it: you choose keep or reset.

A cookie jar that just works

Session cookies flow across requests and chains automatically — login then call, zero setup. Per-request opt-out, cleared when you close the project.

Uploads that round-trip

Build multipart bodies from fields and native file picks, or send a file raw. Pasting curl -F imports it faithfully; Copy as cURL emits the same flags back.

Spec insight

Browse an API as a graph, diff what changed between spec versions, and map each endpoint to the auth it needs — so a moving spec never surprises you.

Yours to theme

Author and save custom editor/UI themes into your project. Light or dark, the whole app follows — including this site.

plain YAML you can commit secrets stay in the OS keychain fully usable offline no account required

On the way — Tinspec Cloud

Optional cloud, when you want teammates in.

A paid tier being readied for launch: workspace sync with honest conflict handling, a web console with request-history metrics, and dev tunnels that expose your localhost at a real URL. The desktop app stays local-first, free, and fully usable offline — cloud is additive, never required.

See pricing →

tunnel · api-provider

local :8080

https://orders-x7k2.t.tinspec.dev

HTTP · WebSocket · gRPC pass through

Point it at your spec.

Free, and it runs entirely on your machine — no account, no cloud, nothing proxied.