Headless Extension Connect
The Anima browser extension links an agent to a real browser so it can autofill vault credentials and drive logins without any secret entering the model’s context. Normally a person installs the extension and clicks Connect. For automation — a Puppeteer worker, a scheduled scraper, a partner integration — there is no person to click. Headless connect closes that gap: mint a one-time connect URL with the API, open it in the headless browser, and the extension binds its bridge to the agent automatically.The connect response never contains a token or a secret.
connectUrl itself carries a short-lived, single-use exchange code; the extension redeems it out of band. Nothing sensitive passes through the model.The flow
1
Mint a connect URL
Call
POST /v1/extension/connect. The API returns a connectUrl pointing at the console connect page, carrying a single-use exc_auto_… exchange code.2
Open it in the headless browser
Navigate the automation browser (with the Anima extension loaded) to
connectUrl. The exc_auto_ prefix tells the page to relay the code to the extension automatically — no click.3
Wait for the bridge
The page exposes
data-connect-status, which transitions to connected once the extension has bound its bridge to the agent. Wait on [data-connect-status="connected"], then run your automation.Auth model
Who you authenticate as decides whether you passagentId:
Two org policies support headless connect:
session and pre_approved. The prompt_owner policy is not supported — there is no owner to approve an unattended connection, so the API rejects it:
pre_approved, the target agent must be on the org’s pre-approved allowlist (configure it under Settings → Extension in the console), or the request is rejected.
ttl
ttl is optional and shorten-only: "15m" | "1h" | "session". It may only be shorter than — or equal to — the org’s configured maximum. A value longer than the org policy is rejected rather than silently downgraded, so you learn the org forbids that lifetime instead of quietly getting a shorter one. Omit ttl to use the org default. A "session" TTL has no wall-clock expiry, so expiresAt comes back null.
The separate exchangeExpiresAt is the deadline for redeeming the connect URL itself (a single-use handoff window, ~60 seconds) — distinct from expiresAt, the lifetime of the resulting connection.
Mint a connect URL
Response
Puppeteer worker recipe
End to end: mint the URL, launch Chrome with the automation bundle loaded, open the URL, and wait for the bridge.--headless=newis required. Chrome’s old headless mode cannot load extensions at all.- A fresh browser profile connects with no prompt. The
exc_auto_code auto-relays on page load. - Re-connecting a profile that already holds a live bridge requires confirmation. An unattended page must not silently replace an existing connection — the extension asks the owner to approve the re-pair, and denies otherwise. For a clean worker run, start from a fresh profile.
Related
- Vault — Browser Extension — how the extension performs credential autofill without exposing secrets.
- Vault — per-agent encrypted credential storage and the secret boundary.
- Security — key types (
mk_vsak_) and the master-key model.
