diff --git a/auth/faq.mdx b/auth/faq.mdx
index 86a8a66..899e00d 100644
--- a/auth/faq.mdx
+++ b/auth/faq.mdx
@@ -23,7 +23,8 @@ Health checks on regular cadences based on your plan:
Check the `can_reauth` field on a connection. This boolean checks the following conditions:
1. **Credential linked** — A credential must be attached to the connection (stored in Kernel or via an external provider like [1Password](/integrations/1password))
-2. **No external action required** — The learned login flow doesn't require human intervention
+2. **Sufficient credentials** — The stored credential must contain all fields required by the login flow (e.g., if the login requires both email and password, both must be stored)
+3. **No external action required** — The learned login flow doesn't require human intervention
Only if all of the above conditions are met will `can_reauth` be `true`. When true, Kernel will attempt to automatically re-authenticate the connection.
@@ -35,26 +36,41 @@ If your login flow requires one of these, you can still automate around it:
- **Switch to TOTP** — If the site supports authenticator apps, add a `totp_secret` to your credential. TOTP codes are generated automatically, so the login flow won't require external action.
- **Trigger manual re-auth** — Start a new login session and route the user through the [Hosted UI](/auth/hosted-ui) or [Programmatic](/auth/programmatic) flow.
+## Can I update an existing connection's settings?
+
+Yes. Use the [update endpoint](/auth/programmatic#updating-connections) to change `login_url`, `credential`, `allowed_domains`, `health_check_interval`, `save_credentials`, or `proxy` on an existing connection without recreating it. Changes take effect on the next login or health check.
+
## Which authentication methods are supported?
-Managed Auth supports username/password authentication and most SSO providers.
+Managed Auth supports username/password authentication, most SSO providers, and TOTP-based 2FA. Kernel automatically handles multi-step login flows including SSO provider selection, organization/account pickers, and CAPTCHA challenges.
-Passkey-based authentication (e.g., Google accounts with passkeys enabled) is not currently supported. If a user's SSO provider requires a passkey, the login will fail.
+Passkey-based authentication (e.g., Google accounts with passkeys enabled) and hardware security keys are not currently supported. If a login requires one of these methods, the flow will fail with the `unsupported_auth_method` error code.
## What happens if login fails?
-If a login attempt fails, Kernel will retry with exponential backoff. After multiple failures, the [login flow](/auth/hosted-ui) will be marked as failed and you'll receive an error. Common failure reasons include:
+If a login attempt fails, Kernel will retry with exponential backoff. After multiple failures, the [login flow](/auth/hosted-ui) will be marked as failed and you'll receive an error with an `error_code`. Common failure reasons include:
+
+- `invalid_credentials` — The credentials were rejected by the site
+- `bot_detected` — Bot detection blocked the login attempt
+- `captcha_unsolved` — A CAPTCHA appeared that couldn't be solved
+- `network_error` — Network connectivity issues during login
+- `unsupported_auth_method` — Login requires passkeys or hardware security keys
+- `awaiting_input_timeout` — Timed out waiting for user input
+- `external_action_timeout` — Timed out waiting for email/SMS verification or push notification
+- `max_steps_exceeded` — Login flow exceeded the maximum step limit
-- Invalid credentials
-- Bot detection blocking the login page
-- CAPTCHAs that couldn't be solved
+See the full [error codes reference](/auth/overview#error-codes) for details.
## Can I use Managed Auth with any website?
Managed Auth works with most websites. Sites with aggressive bot detection may require additional configuration (stealth mode, proxies). Passkeys and hardware security keys are not currently supported.
+## What are sign-in options?
+
+Sign-in options are non-MFA choices that appear during login, such as account pickers ("Which account do you want to use?") or organization selectors. They're different from MFA options, which appear after credentials are accepted. When `sign_in_options` appears in the session state, present the options to the user and submit their choice using `sign_in_option_id`. See [Programmatic Flow](/auth/programmatic#sign-in-options) for details.
+
## How is Managed Auth billed?
Managed Auth is included on all paid plans with no per-connection fees. It uses browser sessions to log in and keep your sessions fresh—these count toward your browser usage like any other browser session.
diff --git a/auth/overview.mdx b/auth/overview.mdx
index 0f6d94b..3bc497f 100644
--- a/auth/overview.mdx
+++ b/auth/overview.mdx
@@ -117,13 +117,29 @@ await page.goto("https://netflix.com")
The most valuable workflows live behind logins. Managed Auth provides:
-- **Works on any website** - Login pages are discovered and handled automatically
-- **SSO/OAuth support** - "Sign in with Google/GitHub/Microsoft" buttons work out-of-the-box via `allowed_domains`
-- **2FA/OTP handling** - TOTP codes automated, SMS/email/push OTP are supported
+- **Works on any website** - Login pages are discovered and handled automatically, with advanced bot detection avoidance for sites with aggressive anti-automation
+- **SSO/OAuth support** - "Sign in with Google/GitHub/Microsoft" buttons work out-of-the-box via `allowed_domains`, including SSO provider selection and organization/account pickers
+- **2FA/OTP handling** - TOTP codes automated, SMS/email/push OTP are supported, with automatic MFA option selection
- **Post-login URL** - Get the URL where login landed (`post_login_url`) so you can start automations from the right page
- **Session monitoring** - Automatic re-authentication when sessions expire with stored credentials
+- **Update connections** - Change `login_url`, `credential`, `allowed_domains`, `health_check_interval`, and more on existing connections without recreating them
- **Secure by default** - Credentials encrypted at rest, never exposed in API responses, or passed to LLMs
+## Error Codes
+
+When a login flow fails, the `error_code` field indicates the reason:
+
+| Error Code | Description |
+|------------|-------------|
+| `invalid_credentials` | The provided credentials were rejected by the site |
+| `bot_detected` | The site's bot detection blocked the login attempt |
+| `captcha_unsolved` | A CAPTCHA appeared that couldn't be solved |
+| `network_error` | Network connectivity issues during login |
+| `unsupported_auth_method` | Login requires an unsupported auth method (passkey, security key) |
+| `awaiting_input_timeout` | Timed out waiting for user input |
+| `external_action_timeout` | Timed out waiting for an external action (email/SMS verification, push notification) |
+| `max_steps_exceeded` | Login flow exceeded the maximum step limit |
+
## Security
| Feature | Description |
diff --git a/auth/programmatic.mdx b/auth/programmatic.mdx
index d3f7696..c466d91 100644
--- a/auth/programmatic.mdx
+++ b/auth/programmatic.mdx
@@ -259,6 +259,78 @@ if state.pending_sso_buttons:
Remember to set `allowed_domains` on the connection to include the OAuth provider's domain (e.g., `accounts.google.com`).
+### SSO Provider Selection
+
+When login requires selecting an SSO provider (e.g., choosing between Google, Microsoft, or GitHub), the `sso_providers` field lists available options. Submit the selected provider using `sso_provider`:
+
+
+```typescript TypeScript
+if (state.sso_providers?.length) {
+ // Show available SSO providers
+ for (const provider of state.sso_providers) {
+ console.log(provider);
+ }
+
+ // Submit the selected SSO provider
+ await kernel.auth.connections.submit(auth.id, {
+ sso_provider: 'google'
+ });
+}
+```
+
+```python Python
+if state.sso_providers:
+ # Show available SSO providers
+ for provider in state.sso_providers:
+ print(provider)
+
+ # Submit the selected SSO provider
+ await kernel.auth.connections.submit(
+ auth.id,
+ sso_provider="google",
+ )
+```
+
+
+
+This is different from SSO buttons. SSO provider selection is used when the login flow presents a choice of identity providers, while SSO buttons are clickable elements on the login page itself.
+
+
+### Sign-In Options
+
+Some login pages present non-MFA sign-in choices, such as account pickers or organization selectors. These appear in `sign_in_options`:
+
+
+```typescript TypeScript
+if (state.sign_in_options?.length) {
+ // Show available sign-in options
+ for (const option of state.sign_in_options) {
+ console.log(`${option.id}: ${option.label} - ${option.description}`);
+ }
+
+ // Submit the selected option
+ await kernel.auth.connections.submit(auth.id, {
+ sign_in_option_id: state.sign_in_options[0].id
+ });
+}
+```
+
+```python Python
+if state.sign_in_options:
+ # Show available sign-in options
+ for option in state.sign_in_options:
+ print(f"{option['id']}: {option['label']} - {option['description']}")
+
+ # Submit the selected option
+ await kernel.auth.connections.submit(
+ auth.id,
+ sign_in_option_id=state.sign_in_options[0]["id"],
+ )
+```
+
+
+Each sign-in option has an `id`, `label`, and optional `description`. These are distinct from MFA options—sign-in options appear during the login phase (e.g., "Which account?" or "Select your organization"), while MFA options appear after credentials are accepted.
+
### MFA Selection
When the site offers multiple MFA methods, they appear in `mfa_options`:
@@ -363,3 +435,39 @@ The stream delivers `managed_auth_state` events with the same fields as polling
Polling is recommended for most integrations. SSE is useful when building real-time UIs that need instant updates without polling delays.
+
+## Updating Connections
+
+Update an existing connection's configuration without recreating it using `PATCH /auth/connections/{id}`:
+
+
+```typescript TypeScript
+await kernel.auth.connections.update(auth.id, {
+ login_url: 'https://example.com/new-login',
+ allowed_domains: ['accounts.google.com', 'google.com'],
+ health_check_interval: 900, // 15 minutes, in seconds
+});
+```
+
+```python Python
+await kernel.auth.connections.update(
+ auth.id,
+ login_url="https://example.com/new-login",
+ allowed_domains=["accounts.google.com", "google.com"],
+ health_check_interval=900, # 15 minutes, in seconds
+)
+```
+
+
+Supported fields:
+
+| Field | Description |
+|-------|-------------|
+| `login_url` | Override the login page URL |
+| `credential` | Link a different credential |
+| `allowed_domains` | Update SSO/OAuth allowed domains |
+| `health_check_interval` | Health check frequency in seconds (300–86400) |
+| `save_credentials` | Enable or disable credential saving |
+| `proxy` | Update the proxy configuration |
+
+Changes take effect on the next login or health check. If a login session is currently in progress, runtime configuration changes (like `allowed_domains`) are applied immediately.