Sessions & HITL
Send a link, let the person sign in themselves
A single-use, host-scoped link your end-user opens to sign in by hand in a hosted browser. The session is captured; the password never is.
connect_account
What it is
The job: Get logged into a site that an agent is not going to be allowed to log into.
Some sites cannot be signed into by an agent. Not “are hard to” — cannot: a datacenter IP plus an automated login plus a device check is a wall that no amount of retrying gets through, and the honest response is to hand the sign-in to a human once. connect_account mints the link that does it.
The link opens a Twin-Browser-hosted browser where your end-user completes the whole thing — password, 2FA, CAPTCHA, whatever the site asks. What gets captured is the resulting session, not the credential. Re-run the original task afterwards and it restores that session; the run reports sessionRestored: true and there is no login step at all.
It is OAuth-shaped, for sites that offer no OAuth. The link is single-use, expires in about thirty minutes, and is scoped to one host. Pass a redirectUri to send the user back into your product when they are done, and an `account` label when you keep several logins per site — it must match the label you pass on runs.
You will often not need to call this at all: a run that hits an unpassable wall already returns code: "connect_required" with a ready connectUrl in the response. This tool is how you mint one deliberately.
The call
Call it exactly like this.
Copied from the tool's registration and the route handler — not paraphrased.
// MCP tool call — server "twin-browser"
{
"tool": "connect_account",
"arguments": {
"host": "example.com",
"account": "work",
"redirectUri": "https://your.app/connected"
}
}curl -X POST https://twin-browser.com/api/v1/connect/sessions \
-H "Authorization: Bearer $TWIN_API_KEY" \
-H "content-type: application/json" \
-d '{"host":"example.com","account":"work","redirectUri":"https://your.app/connected"}'| Parameter | Type | What it does |
|---|---|---|
| host* | string | The site to sign into, e.g. "example.com". A full URL also works. |
| account | string | Label when several logins are kept for this site. Must match the `account` you pass to run_goal / run_skill. |
| redirectUri | string | Absolute https URL to return the user to once connected. |
Returns
HTTP 201
{ "id": "…", "url": "https://twin-browser.com/connect/…", "host": "example.com",
"account": "work", "expiresAt": "…", "ttlMinutes": 30 }
// The url is shown once. Give it to the user; do not log it.What it costs
Free
Minting a connect link costs nothing. What it saves is the run that was going to fail — and, on hosts with repeated score-wall blocks, the platform short-circuits to this response without executing at all and refunds the reserve.
See the full rate cardWhich one
When a different tool is the right call.
The honest answer is often the neighbouring tool. These are the trades.
submit_verificationUse submit_verification when the run only needs a code and your app can supply it. Use connect_account when the whole sign-in has to happen elsewhere — including every case where you should not be holding the person’s password.
submit_verificationcontrol_runcontrol_run lets YOU drive the paused page. connect_account lets THE USER drive their own sign-in, in a browser scoped to that one host. If the blocker is a login, prefer connect.
control_runlist_connectionsMinting the link is half the flow; list_connections is how you find out whether the user actually finished it before you re-run the task.
list_connectionsQuestions
connect_account, answered.
- Do you store the user’s password?
- No. The sign-in happens in a hosted browser and what is captured is the resulting session — cookies and storage state, encrypted at rest. The password is typed by its owner into the site’s own form and is never persisted by Twin Browser.
- How do I know when they have finished?
- Call list_connections. Each link reports pending, active, connected, failed or expired. Re-run the original task once it says connected — or set a redirectUri and let your own product observe the return.
- Should I ever ask the user for their password directly?
- No. If your application already holds a credential for its own reasons, submit_verification takes it as a `secrets` object that goes straight into the parked browser’s vault. If it does not, send the connect link. Asking a user to paste a password into a chat with a model is the one path that is never correct.
Keep going
The rest of the tool set.
list_connectionsStop an agent from re-running a task before the user has actually signed in.
list_accountsAnswer “can I get into this site, and as whom?” before starting a run.
submit_verificationFinish a sign-in that got as far as the second factor.
control_runClear a blocker you can see on the page, when no code and no credential would have helped.