API integration

Twin Browser + REST API

Twin’s REST API is the universal integration path: HTTPS endpoints under `/api/v1/*`, authenticated with a Bearer key. Any language that can make an HTTP request can drive the browser execution layer — no SDK required, and none is published.

API4-step setupBearer key auth

How Twin plugs into REST API

The REST API is the layer everything else on this page wraps, including the MCP server. `POST /api/v1/run` takes either an ad-hoc goal — `{ url, prompt, success }` — or a named compiled skill — `{ target, goal }` — and returns a structured result. `POST /api/v1/dispatch` routes a re-phrased request through the semantic dispatch cache. `POST /api/v1/skills` compiles, `POST /api/v1/skills/{name}/run` replays deterministically. Auth, usage-based billing and audit logging run on every call, and the target URL you pass is the authorization signal.

Twin is the browser execution layer your stack calls. The first run cold-compiles a skill via skill compilation; every similar request after that is matched from the cache and replayed deterministically, so your marginal cost per run trends toward zero rather than climbing with usage.

app.example.com
  1. Receive goal from REST APIdone
  2. Compile DOM → token-efficient indexed statedone
  3. Match the semantic dispatch cacherunning
  4. Replay compiled skill — 0 LLM callsqueued

Wire it up

Drop Twin into REST API.

Copy, paste, and swap in your Bearer key. The first run compiles a skill; repeats match the semantic dispatch cache and replay deterministically.

curl — run a goal, then dispatch a re-worded onebash
# Ad-hoc goal. "success" is REQUIRED alongside "url" and "prompt" —
# one of statusText | urlIncludes | textVisible | extracted | allOf | anyOf.
curl -X POST https://twin-browser.com/api/v1/run \
  -H "Authorization: Bearer ab_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://app.acme.com/billing", "prompt": "Sign in and download the latest invoice as CSV", "success": { "kind": "textVisible", "value": "Invoice" } }'

# A re-worded request, routed through the semantic dispatch cache.
curl -X POST https://twin-browser.com/api/v1/dispatch \
  -H "Authorization: Bearer ab_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://app.acme.com/billing", "prompt": "Grab this month’s invoice", "success": { "kind": "extracted" } }'

Base URL https://twin-browser.com/api/v1 · auth Authorization: Bearer ab_live_… · over MCP the same engine is run_goal, compile_skill and run_skill — the full tool table.

  1. Create a key

    Generate a Bearer key in the dashboard under Keys & Secrets. It starts with ab_live_.

  2. Call /api/v1/run

    POST { url, prompt, success } for an ad-hoc goal, or { target, goal } to invoke a compiled skill by name.

  3. Dispatch repeats

    POST the same body shape to /api/v1/dispatch so a re-phrased request hits the semantic cache instead of planning again.

  4. Compile and replay

    POST /api/v1/skills to compile, then POST /api/v1/skills/{name}/run for a deterministic replay with no model in the loop.

FAQ

REST API on Twin — common questions

Do I need an SDK to use Twin?
No, and there is no first-party SDK package to install. The REST API is plain HTTPS with Bearer auth, so any HTTP client works — the MCP server and every framework example on this site are thin wrappers over these same endpoints.
Why does /api/v1/run reject { goal, url }?
Those two fields belong to different request shapes. An ad-hoc goal is { url, prompt, success }; a named, already-compiled skill is { target, goal }. Mixing them — a free-text goal in the named shape, or a url without a prompt and success — returns a 400 with a pointed hint rather than burning credits.
How do I authenticate?
Send Authorization: Bearer <your key> on every request. Keys are per-tenant, scoped and revocable from the dashboard, and every call is audit-logged.

Wire up REST API in minutes.

Free to start. Usage-based credits from $29/mo — each call billed the higher of its flat action price or its metered cost.