CAPABILITY · ACCOUNTS

Let the person whose account it is sign in, once

Mint a single-use link, your end user completes the sign-in in a hosted browser, and the captured session makes every later run already logged in — with no password anywhere.

POST /api/v1/connect/sessions

Capability

Inside connected accounts & handoff

Some sign-ins should not go through you. The password belongs to your customer, or the site hard-challenges automated logins from datacenter IPs and simply cannot be signed into by an agent. The connect handoff is the answer to both: a single-use link, a real person completing the sign-in — password, 2FA, CAPTCHA — in a hosted browser, and a captured session that later runs restore. It is OAuth-shaped, for sites that offer no OAuth.

The session, never the password

What is captured and stored is the authenticated session. The end user's password is never stored, and never passes through your system.

Several logins per host

An `account` label distinguishes logins on the same site. Pass it on a run and that login plus its own saved session are applied; GET /api/v1/accounts lists the labels you have, with a masked email preview and never a credential.

A local-capture path for popup OAuth

A "Continue with Google" sign-in only completes in a real local browser. POST /api/v1/sessions/import takes cookies captured on the user's own machine and assembles them into the same encrypted session a hosted sign-in would produce.

Minted for you when a run needs it

A run blocked by a wall automation cannot pass returns code: "connect_required" with a READY connectUrl already minted — you hand it over rather than making a second call. Opt out with connect: false and mint your own.

How it works

The mechanism, in execution order

4 stages, in the order the runtime performs them — not a summary of them.

CONNECT HANDOFFRun hits a loginno stored sessionOne-time linkyou send, never storeYour usersigns in themselvesSession capturedthe password is notLater runssessionRestoredthe person who owns the account is the one who types the password
  1. 1MintPOST /api/v1/connect/sessions with a host (and an optional account label and redirectUri). The response carries a single-use url, shown once.
  2. 2Hand it overYour end user opens it and signs in by hand in a hosted browser — password, second factor, CAPTCHA, all of it.
  3. 3CaptureThe resulting session is captured and encrypted against that host and account label.
  4. 4Re-runRun the original task again and it restores the session (sessionRestored: true). No credentials, no 2FA, no link.

In practice

A call you can paste and run

Mint, hand over, check, re-run. The password never touches your code or ours.

connect.shbash
curl -X POST https://twin-browser.com/api/v1/connect/sessions \
  -H "Authorization: Bearer $TWIN_API_KEY" \
  -H "content-type: application/json" \
  -d '{"host":"portal.example.com",
      "account":"acme-ops",
      "redirectUri":"https://your.app/connected"}'
# → 201 { "id":"…", "url":"https://twin-browser.com/connect/…",
#          "host":"portal.example.com", "account":"acme-ops",
#          "expiresAt":"…", "ttlMinutes":30 }

# Did they finish?
curl "https://twin-browser.com/api/v1/connect/sessions" -H "Authorization: Bearer $TWIN_API_KEY"
# → { "sessions":[ { "id":"…", "status":"connected", "connected_at":"…" } ] }

# Then run the task with that account — the session is restored
curl -X POST https://twin-browser.com/api/v1/run \
  -H "Authorization: Bearer $TWIN_API_KEY" \
  -H "content-type: application/json" \
  -d '{"target":"https://portal.example.com","goal":"extract","account":"acme-ops"}'
api.twin-browser.com
  1. Mintdone
  2. Hand it overrunning
  3. Capturequeued
  4. Re-runqueued

What it costs, how to switch it on

Priced from the same rate card the API serves

Every credit figure on this page is read from the rate card behind GET /api/v1/pricing — it is not typed into the copy, so it cannot drift from what you are billed.

Free to mint, list and import

Connect sessions, account listing and session import are control-plane operations and cost nothing. You pay for the runs that use the captured session, at their own price — and a run that restores a session skips the sign-in work it would otherwise have paid for.

Full rate card

Turning it on

  1. 1Mint on demandCall POST /api/v1/connect/sessions with the host, or take the connectUrl a blocked run already minted for you.
  2. 2Label the accountUse the same `account` string on the connect session and on every later run, so the right session is applied.
  3. 3Poll for completionGET /api/v1/connect/sessions reports status per link. Wait for "connected" before you re-run the task.
  4. 4Install the capture path for popup OAuthFor "Continue with Google"-style sign-ins, capture cookies locally and POST them to /api/v1/sessions/import.

At a glance

The contract, in the fewest rows that say it

PropertyTwin Browser
MintPOST /api/v1/connect/sessions → 201
Link TTL~30 minutes, single use, one host
Statuspending · active · connected · failed · expired · cancelled
AccountsGET /api/v1/accounts (masked metadata)
Local capturePOST /api/v1/sessions/import
Run signal`account` selects login + session

Limits

Where it stops, and what it deliberately does not do

A capabilities page with no limits section is a brochure. These are the ceilings, the defaults that will surprise you, and the things this capability is not.

Limits and defaults

  • A connect link is single-use, expires in about 30 minutes, and is scoped to one host.
  • There is a cap on how many connect sessions can be pending at once — the endpoint answers 429 rather than minting unbounded links.
  • A captured session ages out. When a site invalidates it, the next run mints a fresh link rather than silently failing.
  • Session import requires at least one usable cookie; unusable entries are dropped and an empty set is a 400.

What it does not do

  • It does not store the end user's password. Only the session is captured.
  • It does not let you watch the sign-in. The hosted browser is the end user's, not a session you can drive.
  • It does not work without the person. A connect link is by definition a human step; the automated paths are the vault and the HITL resume.
  • It does not import a session for a host you have no run against — the import is keyed by host, under both apex and www forms.

FAQ

Questions about connected accounts & handoff

When do I need a connect link instead of a stored password?
Two cases. The password belongs to your customer and you should not hold it. Or the site hard-challenges automated sign-in from datacenter IPs and cannot be signed into by an agent at all — a real person's sign-in carries trust that no client-side lever reproduces.
What is actually stored afterwards?
The authenticated session, encrypted and scoped to the host and account label. Not the password, and not the second factor.
How do I keep several logins for one site apart?
Give each an `account` label at connect time and pass the same label on every run. GET /api/v1/accounts lists what you have — label, host and a masked email preview, never a credential.
What about "Continue with Google" sign-ins?
Popup OAuth only completes in a real local browser, so the hosted flow cannot drive it. Capture the cookies on the user's own machine and POST them to /api/v1/sessions/import; they are assembled into the same encrypted session a hosted sign-in would have produced.

Put your agent to work. Keep the decision.

Start free. Hand your agent a goal on a site you authorize, set the guardrails, and let the first successful run compile the skill every run after it replays.