For operations and platform teams
Ship the integration the vendor never built.
When a system has no API, no webhook and no export, the fallback is a person clicking through it every day. Twin compiles that click-path once into a named skill, then replays it per record with the values bound at call time — no model in the loop, no coordinate recording to maintain.
The problem
What this costs you today.
The vendor’s answer is always the same: the API is on the roadmap, or it is an enterprise add-on, or it exists but does not cover the one screen you need. So the workflow stays manual. Someone signs in every morning, keys in the same twenty records, exports a CSV that another person re-keys somewhere else. It is not hard work, it is just work that never ends — and it is invisible to every system you actually measure.
- “There is no API. IT quoted eighteen months for a middleware project.”
- “We pay a contractor to re-key the same records between two systems.”
- “We tried an RPA bot. The vendor redesigned the page and it broke that week.”
- “The screen we need is behind a login, so nothing off-the-shelf can reach it.”
- Open the vendor screendone
- Resolve login from the vaultrunning
- Bind params for this recordqueued
- Replay the stored pathqueued
- Verify the success conditionqueued
How Twin solves it
The mechanism, not a promise.
A compiled skill is the integration. Twin plans the flow once against the live UI, minimizes it into a stored action path, and replays that path deterministically — with the parameters, credentials and session bound per call rather than frozen at compile time.
- 1Describe the flow once, in wordsPOST /api/v1/skills with the target and the goal. Twin discovers the path with the planner, then minimizes it into a stored, named skill. This is the one expensive call.
- 2Write the variable parts as tokensA goal can carry `{{param:NAME}}` for call arguments and `{{secret:NAME}}` for vault credentials. Neither is baked into the skill: both are resolved per replay, so one skill drives every record and every login on that host.
- 3Replay it deterministicallyPOST /api/v1/skills/{name}/run executes the stored path with no model in the loop. Pass `params` for the values and `account` to pick which stored login and session to use.
- 4Fail loudly, before it costs anythingA replay whose parameters are unresolved returns 400 with `code:"params_missing"` and the list of missing names — before a run row exists and before a credit is reserved. It never types a literal `{{param:qty}}` onto a live page.
- 5Plans survive a redesignThe planner acts on a numerically-indexed map of the page’s interactive elements rather than CSS selectors or coordinates, so a cosmetic redesign shifts the map rather than snapping a hard-coded path.
In practice
The actual call, and what it returns.
Compile the click-path once, then call it like a function. The values arrive per call, which is what makes one compiled skill an integration rather than a recording of one afternoon.
# 1 — compile the flow ONCE from the live UI.
curl https://twin-browser.com/api/v1/skills \
-H "Authorization: Bearer $TWIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target": "https://erp.vendor.example.com",
"goal": "raise a purchase order for {{param:sku}} quantity {{param:qty}}",
"as": "create-po"
}'
# 2 — replay it per record. No LLM in the loop.
curl https://twin-browser.com/api/v1/skills/create-po/run \
-H "Authorization: Bearer $TWIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target": "https://erp.vendor.example.com",
"account": "erp-service-user",
"params": { "sku": "AX-7741", "qty": "12" }
}'
# → 200 { "success": true, "steps": 8, "runId": "…", "credits_charged": 1 }
# An under-specified call is refused BEFORE anything is charged:
# → 400 { "error": "missing required parameter(s): qty",
# "code": "params_missing", "missing": ["qty"] }What this call does
- `params` binds `{{param:NAME}}` at call time, so one skill covers every record instead of one example.
- `account` selects which stored login and cookie jar to use, so the same skill drives several logins on the same host.
- Vault secrets referenced as `{{secret:NAME}}` are resolved server-side for this tenant, host and account — the value never appears in a request or a response.
- The stored success condition is re-bound with the same params, so a skill that verifies by reading back what it typed still verifies correctly.
What it costs
Priced per action, not per seat.
One expensive call, then a flat cheap one per record. That shape is the whole economic argument for compiling instead of re-reasoning.
| Action | Credits | What you get |
|---|---|---|
| POST /skills — compile the flow | 50 / skill | Paid once per flow. A planning pass plus minimization into a stored path. |
| POST /skills/{name}/run — replay | 1 / record | Deterministic execution of the stored path. No model call. |
| POST /run — an ad-hoc run | 10 / run | For the one-off variant that does not justify a skill. |
How the unit works
- $1 buys 1,000 credits; the smallest pack is $5.
- A paid action bills the higher of its flat floor and what it actually spent on model, compute and egress — so a cheap run stays cheap.
- “Metered” means the action has no published flat floor on this page: GET /api/v1/pricing serves the live card.
- Compiling is worth it as soon as you will run the flow more times than the compile costs in saved runs — the exact number is computed on the pricing page from these same figures.
Be sure this fits
What this does not do.
Every one of these will come up in your evaluation. Here they are first, from us.
It is not a supported integration, and cannot pretend to be
You are driving a UI the vendor may change without telling you. Skills plan over an indexed element map rather than selectors, which absorbs cosmetic churn — but a flow that is genuinely restructured needs a recompile, and you should expect that a few times a year on an actively developed product.
It does not give you an API’s throughput
Every replay drives a real browser: think seconds per record, not milliseconds, and bounded concurrency. For tens of thousands of records a night, a real API — even a paid one — is the right answer and we will tell you so.
It does not create authorization you do not have
Twin runs against accounts you are entitled to use, on targets you supply. It does not bypass a licence, a rate limit you agreed to, or a vendor’s terms of service.
Under the hood
The primitives this runs on.
Nothing here is specific to this problem — the same mechanisms carry every solution on the site.
Deterministic replay
A successful run is minimized into a named, versioned skill — an ordered action path with its variable parts lifted out — and replaying it is a program, not a prompt.
Read the mechanism — Deterministic replaySkill library & catalog
Every compiled skill is stored per tenant with a version and a run contract — the params it takes, the secrets it fills, and whether your stored auth is ready for its host.
Read the mechanism — Skill library & catalogCredential vault
A write-only per-tenant vault: a stored secret is referenced in a goal as {{secret:NAME}}, resolved inside the browser at fill time, and redacted from every step, frame and log.
Read the mechanism — Credential vaultToken-efficient DOM state
The live page is serialized into a numerically-indexed list of its interactive elements under a token budget, so the planner reasons over signal instead of markup.
Read the mechanism — Token-efficient DOM stateOver MCP, the same work is these tools
compile_skillDiscover a goal once with the planner, then minimize it into a reusable, deterministic skill.
run_skillBlind-replay a compiled skill with no LLM in the loop — the cheap, deterministic path.
list_catalogThe runnable-skill catalog: each compiled skill plus its run contract — the params to pass, the secrets it fills, and your auth readiness on the host (mode + ready + missing). Plan a run before spending a credit.
list_skillsList the compiled skills available for replay.
FAQ
Systems with no API — common questions.
What happens when the vendor redesigns the screen?
Where do the credentials live?
How is this different from RPA?
Can a person approve a step before it commits?
Related
Other problems this layer solves.
Onboarding and migration data entry
Implementation, onboarding and professional-services teams who move customer data into systems by hand.
Supplier and customer portals
Procurement, accounts-payable and supply-chain teams whose data is spread across dozens of external portals.
Browser infrastructure for AI products
Founders and engineering leads whose AI product has to act on the live web for every customer.
Try it on your hardest screen.
Start free, point a run at the system that is blocking you, and watch it happen live. If it does not work, the run tells you why — and what to do instead.