Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Account re-login over HTTP — `POST /accounts/login-capture`

The HTTP twin of the account panel's general Log In button: how an agent starts an Anthropic account re-login through Omniscio's local control server, polls until the flow finishes, and confirms which account was captured. Covers the two routes, the full headless sequence, every error status, and the credential-safety gates wrapped around it.

What it is

How an agent completes an Anthropic account re-login end to end over the CLI control server, without a human driving the desktop UI. This is the HTTP twin of the account panel's general "Log In" button.

Where to find it

The thing being driven here is the account panel's general "Log In" action, which sits in the footer of the account indicator — the small account strip in the app's chrome — and not the per-account orange re-auth buttons beside it. Everything else on this page is addressed to an agent working over HTTP rather than to someone clicking in the desktop UI.

How it behaves

What the "Log In" button actually does (and which browser it signs into)

The account panel's general "Log In" action — the account-agnostic one in the AccountIndicator footer, NOT the per-account orange re-auth buttons — starts a PKCE OAuth flow via authService.login():

  • It opens the system default browser (through shell.openExternal) to Anthropic's authorize URL, and starts a loopback HTTP server to catch the OAuth redirect.
  • It is account-agnostic: whichever Anthropic account finishes the sign-in is the one captured — Omniscio identifies the account from the tokens the callback returns.
  • It signs into the system default browser — not a managed login window, and not the Real Chrome bridge / the user's real Chrome over CDP. So step 2's magic link must be opened in that same system-default-browser OAuth flow.
  • It imports a completed OAuth callback, never browser cookies. There is no "paste cookies to sign in" path.

That last point is why the endpoint below must be started before the magic link is opened — the OAuth callback can only complete a flow that is already running.

For agents

The endpoint

POST /accounts/login-capture

  • Auth: bearer, global amc-cli token only (cliTokenOnly). A scoped agent-session token is refused 401 — this route mutates credentials.
  • Body: { "loginHint"?: "<email>" } — an optional email prefilled into the OAuth page. The route captures whichever account actually signs in, regardless of the hint.
  • Behaviour: invokes the same authService.login() capture the button uses, then the same post-login side-effects (other windows refreshed, CLI caches cleared, refresh cooldown reset, usage primed, rate-limited sessions auto-restored).
  • NON-BLOCKING (fire-and-forget): it starts the OAuth flow and returns immediately — it does NOT wait for the callback. Start it before opening the sign-in / magic link, then poll for the result.
  • Response 202: { ok: true, data: { started: true } } — that is the WHOLE body. There is no accountId, account, health, or accountSwitched here; the OAuth outcome is written only to the app log.

The poll target

GET /accounts/login-capture/status

  • Auth: bearer (read preamble).
  • Response 200: { ok: true, data: { inProgress, activeAccount } }
    • inProgress — true while a sign-in is still in flight; it flips to false when the flow finishes (captured, timed out, or cancelled).
    • activeAccount — { id, email } of the app-wide active account, or null. After a successful capture this is the account that was captured, which is how you confirm which account landed.
  • It reports liveness + the active account, not success: inProgress: false alone does not mean the login worked. Confirm with GET /accounts (below).

The full headless re-login sequence

  1. Start the capture — POST /accounts/login-capture (optionally { "loginHint": "<email>" }). This opens the system browser to the OAuth page and returns 202 { started: true } right away. Do NOT hold the connection open, and do NOT try to read an account off this response.
  2. User enters their email in the login browser (human step — may include a CAPTCHA).
  3. Agent opens the magic link from the account's Gmail so that same browser/flow completes the OAuth redirect → the loopback callback fires.
  4. Poll GET /accounts/login-capture/status until data.inProgress is false. The OAuth flow allows up to ~5 minutes, so poll on that budget and treat exhausting it as a failure.
  5. Confirm: GET /accounts shows the expected account at health: "ok". This is the authoritative check — inProgress: false only means the flow ended, not that it succeeded. Cross-check data.activeAccount.email from step 4 to see WHICH account was captured.

Errors

Status Meaning
202 Success — the capture STARTED (not "completed"). Body is { started: true }; poll /accounts/login-capture/status.
403 Managed pathway unavailable on this install (F038 fail-closed owner gate). On a public build with no managed accounts, no tier floor and no dev override, the route refuses before opening any browser. Not retryable — add your own Anthropic API key, or use your own claude login, instead.
409 A login is already in progress, or the user cancelled it — a caller-state conflict (humanized message), not a server fault.
400 Malformed body.
401 Missing/invalid token, or an in-app session token (this route is global-token-only).
5xx Token-exchange / network failure — humanized for the caller, raw logged server-side.

Safety notes

  • Desktop-only capability surfaced over loopback HTTP; because it mutates credentials it requires the global amc-cli token, never a spawned agent's scoped token.
  • The route returns no account data at all — the 202 body is just { started: true }, so no credential can leak through it. The stripped account view is served by GET /accounts.
  • Fail-closed managed-pathway gate (F038). Before anything else the route checks isManagedPathwayAvailableForSpawn(); when the managed pathway is unavailable it answers 403 and never opens a browser. This mirrors the ACCOUNT_ADD_LOGIN IPC handler and exists because this route is reachable with a bearer token that lives on the customer's own disk — without the gate, a public build could bootstrap the managed account pool. Owner / dev installs are unaffected. See auth-pathways-contract.md.
  • The capture path is identical to the desktop button's, so a CLI capture and a button login leave the app in the same state.

Related

The wider account and sign-in picture — the account indicator, switching accounts, and what the orange per-account re-auth buttons do — is on the account indicator and account re-login pages. How a session's credential actually gets chosen, and what the managed-versus-own-key gate means, is on the auth pathways page. For driving Omniscio over HTTP in general, rather than this one route, start from CLI control.

Last verified 2026-09-23