Skip to main content

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 pass agentId:
CredentialagentIdBehavior
Master key (mk_)RequiredSelects which agent the extension connects as.
Agent key (ak_)OmitThe server resolves the agent from the key. Passing another agent’s id is rejected.
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:
Under 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

FieldTypeDescription
agentIdstringThe agent the extension will connect as.
connectUrlstringURL to open in the headless browser. Carries the single-use exc_auto_… code.
expiresAtstring | nullWhen the resulting connection expires. null for a session TTL.
exchangeExpiresAtstringDeadline to redeem connectUrl (single-use handoff window).
policy"session" | "pre_approved"The policy governing the session.

Puppeteer worker recipe

End to end: mint the URL, launch Chrome with the automation bundle loaded, open the URL, and wait for the bridge.
Use the automation bundle, not the plain build. The console connect page only ever messages the published Chrome Web Store extension ID — it never trusts a caller-supplied one. An ordinary unpacked build gets a different, per-path ID, so the relay silently never reaches it. The automation bundle (dist-automation/) injects the Chrome Web Store key into the manifest, pinning the unpacked extension to the production ID the page targets.
A few operational notes:
  • --headless=new is 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.
  • 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_ vs ak_) and the master-key model.