> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anchorbrowser.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Anchor Browser provides cloud browsers for AI agents and automation: stealth browsing with residential proxies, managed authentication into third-party web apps, and browser sessions that run reliably at scale. AI agents that need Anchor credentials should start with https://docs.anchorbrowser.io/quickstart/agent-access. This flow lets agents obtain an API key programmatically without creating a dashboard account. Read that page before attempting authentication or API access.

# Identities

> Create and manage identities, then attach them to browser sessions for automatic sign-in.

An **identity** is a specific account on an [application](/essentials/applications) — for example "John's LinkedIn" or "Acme Corp Salesforce admin." When you attach an identity to a session or task, Anchor signs in on your behalf before automation runs.

## What an identity contains

An identity is more than a username and password. After a successful login, Anchor persists everything needed to stay signed in:

| Component           | What it stores                                                                                                               | Enables                                                      |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| **Credentials**     | Username/password, TOTP secrets, 1Password refs, email MFA mailbox, custom fields — depending on the application's auth flow | Full re-login when the saved session expires                 |
| **Browser profile** | Cookies, local storage, and session state from the last successful sign-in                                                   | Fast startup when the site still considers the session valid |
| **Auth flow**       | Which login methods this identity uses (linked from the application)                                                         | Consistent login behavior across re-authentication           |
| **Status**          | Whether the identity is ready to use (`active`, `validated`) or needs attention (`failed`, `agent_failed`)                   | Knowing if automation can proceed without intervention       |

What Anchor can do on the next run depends on what was saved. An identity with **credentials and a valid browser profile** starts signed in immediately. An identity with **only a browser profile** (for example after manual login) works until the site expires the session — then someone must sign in again.

## Quick start: create an identity

Create an identity with credentials for the target application. If the application uses a preset auth flow, pass `authOptionId` with the flow ID.

<CodeGroup>
  ```javascript node.js theme={null}
  import { client, Identities } from 'anchorbrowser';

  client.setConfig({ auth: () => process.env.ANCHORBROWSER_API_KEY });

  const identity = await Identities.createIdentity({
    body: {
      source: 'https://linkedin.com',
      name: 'John Doe',
      credentials: [{
        type: 'username_password',
        username: 'john@example.com',
        password: 'secret',
      }],
    },
  });

  console.log(identity.id);
  ```

  ```python python theme={null}
  from anchorbrowser import Anchorbrowser

  anchor_client = Anchorbrowser()

  identity = anchor_client.identities.create_identity(
      source="https://linkedin.com",
      name="John Doe",
      credentials=[{
          "type": "username_password",
          "username": "john@example.com",
          "password": "secret",
      }],
  )

  print(identity.id)
  ```
</CodeGroup>

<Tip>
  For end-user self-service authentication in your app, use [Embedding End-User Authentication UI](/essentials/omniconnect).
</Tip>

## Use an identity in browser sessions

Pass the identity ID in the `identities` array when [creating a session](/api-reference/browser-sessions/start-browser-session). Anchor authenticates before your agent or automation starts.

<CodeGroup>
  ```javascript node.js theme={null}
  const session = await Sessions.createSession({
    body: {
      session: {
        proxy: { active: true },
      },
      browser: {
        captcha_solver: { active: true },
        extra_stealth: { active: true },
      },
      identities: [{ id: identityId }],
    },
  });
  ```

  ```python python theme={null}
  session = anchor_client.sessions.create_session(
      session={"proxy": {"active": True}},
      browser={
          "captcha_solver": {"active": True},
          "extra_stealth": {"active": True},
      },
      identities=[{"id": identity_id}],
  )
  ```
</CodeGroup>

Optional session flags:

| Flag                       | Effect                                                                                                                                          |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `identity_skip_validation` | Defaults to `true`: reuse the saved profile for active identities. Set `false` to validate the profile and re-authenticate only if it is stale. |
| `identity_async_auth`      | Run authentication in the background and return the session immediately                                                                         |

## Use an identity in tasks

Pass `identity_id` when [running an Automation Task](/tasks/run-a-task). Anchor creates a browser session, authenticates with the identity, then executes the task.

<CodeGroup>
  ```javascript node.js theme={null}
  const run = await Tasks.runTask({
    path: { taskId },
    body: {
      input_params: { report_name: 'Monthly Invoice' },
      identity_id: identityId,
    },
  });
  ```

  ```python python theme={null}
  import os
  from anchorbrowser import Anchorbrowser

  anchor_client = Anchorbrowser(api_key=os.getenv('ANCHOR_API_KEY'))

  run = anchor_client.post(
      f'/v2/tasks/{task_id}/run',
      body={
          'input_params': {'report_name': 'Monthly Invoice'},
          'identity_id': identity_id,
      },
  )
  ```
</CodeGroup>

You can also pass `session_id` to run a task inside an existing authenticated session. By default (`identity_skip_validation: true`), active identities reuse their saved profile. Pass `identity_skip_validation: false`, or call `POST /v1/identities/{identityId}/reauthenticate`, to validate the profile and re-authenticate if it is stale.

## When Anchor re-authenticates

Each time a session or task starts with an identity attached, Anchor decides whether a full login is needed:

1. **Browser profile is still valid** — Anchor loads the saved profile and the session starts signed in. No login steps run.
2. **Browser profile expired / re-auth requested, credentials available** — Anchor runs the application's auth flow using stored credentials (including MFA methods like email OTP or authenticator). The profile is refreshed for next time.
3. **Browser profile expired, no credentials** — Common for manual-login identities. Anchor cannot re-authenticate automatically. Sign in again via the dashboard or generate a re-authenticate link (see below).

<Note>
  Re-authentication requires the identity to have the credentials or auth flow needed for the site's login steps. If the site adds a new MFA requirement that wasn't saved on the identity, update the identity or re-authenticate manually.
</Note>

## Generate re-authenticate links

When an identity needs a fresh login, create a token or ready-to-share URL:

| Endpoint                                                 | Returns                        |
| -------------------------------------------------------- | ------------------------------ |
| `POST /v1/identities/{identityId}/re-authenticate-token` | JWT token (build your own URL) |
| `POST /v1/identities/{identityId}/reauth-links`          | `reauth_url` + `expires_at`    |

Both accept an optional request body:

| Field         | Description                                                    |
| ------------- | -------------------------------------------------------------- |
| `callbackUrl` | HTTPS redirect after the user finishes                         |
| `authMethod`  | `profile` (manual login, default), `dynauth`, or `credentials` |

Send the user to `https://app.anchorbrowser.io/identity/re-authenticate?token={token}` (or use `reauth_url` from `reauth-links`).

<CodeGroup>
  ```javascript node.js theme={null}
  const { reauth_url } = await client.post(
    `/v1/identities/${identityId}/reauth-links`,
    { body: { authMethod: 'dynauth', callbackUrl: 'https://your-app.com/reauth-done' } },
  );
  window.location.href = reauth_url;
  ```

  ```python python theme={null}
  response = anchor_client.post(
      f"/v1/identities/{identity_id}/reauth-links",
      body={
          "authMethod": "dynauth",
          "callbackUrl": "https://your-app.com/reauth-done",
      },
  )
  reauth_url = response["reauth_url"]
  # Redirect the user to reauth_url from your frontend
  ```
</CodeGroup>

## Identity metadata

Add custom metadata to identities for filtering and organization. Metadata is a flexible key-value store.

### Creating an identity with metadata

<CodeGroup>
  ```javascript node.js theme={null}
  const identity = await Identities.createIdentity({
    body: {
      source: 'https://linkedin.com',
      name: 'John Doe',
      metadata: {
        department: 'Engineering',
        role: 'admin',
      },
      credentials: [{
        type: 'username_password',
        username: 'john@example.com',
        password: 'secret',
      }],
    },
  });
  ```

  ```python python theme={null}
  identity = anchor_client.identities.create_identity(
      source="https://linkedin.com",
      name="John Doe",
      metadata={
          "department": "Engineering",
          "role": "admin",
      },
      credentials=[{
          "type": "username_password",
          "username": "john@example.com",
          "password": "secret",
      }],
  )
  ```
</CodeGroup>

### Filtering identities by metadata

<CodeGroup>
  ```javascript node.js theme={null}
  const identities = await Applications.listApplicationIdentities({
    path: { applicationId: app.id },
    query: { metadata: JSON.stringify({ department: 'Engineering' }) },
  });
  ```

  ```python python theme={null}
  import json

  identities = anchor_client.applications.list_application_identities(
      application_id=app.id,
      metadata=json.dumps({"department": "Engineering"}),
  )
  ```
</CodeGroup>

## Related

<CardGroup cols={3}>
  <Card title="Managed Authentication Overview" icon="shield-check" href="/essentials/managed-authentication">
    Profiles vs identities and how everything connects
  </Card>

  <Card title="Applications" icon="grid-2" href="/essentials/applications">
    Configure target sites and auth flows
  </Card>

  <Card title="Run a Task" icon="play" href="/tasks/run-a-task">
    Execute automation tasks with an identity
  </Card>

  <Card title="Embedding End-User Auth UI" icon="window" href="/essentials/omniconnect">
    Let end users connect accounts from your product
  </Card>

  <Card title="Email MFA" icon="paper-plane" href="/advanced/email-otp">
    Email OTP via forwarded inbox
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/identities/create-identity">
    Identity endpoints
  </Card>
</CardGroup>
