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

# Agent profiles

> What a profile holds — credentials, cookies, proxy settings, browser state — and how pools rotate them.

An **agent profile** holds everything a workflow needs to sign in and act as one identity.

A profile carries:

* credentials in a vault
* two-factor secrets
* cookies
* browser cache and session state
* proxy and captcha settings
* an email inbox

A profile is reusable. Many workflows can share one profile, and one workflow can run with a different profile on every execution.

## Attaching a profile to an execution

An [execution](/concepts/executions) uses at most one profile. You pick it when you start the execution.

```bash theme={null}
curl -X POST https://odyssey.asteroid.ai/agents/v2/agents/YOUR_AGENT_ID/execute \
  -H "X-Asteroid-Agents-Api-Key: $ASTEROID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": { "account": "acme" },
    "agentProfileId": "YOUR_AGENT_PROFILE_ID"
  }'
```

Pass `agentProfilePoolId` instead to let Asteroid choose a profile from a [pool](#profile-pools).

<Warning>
  `agentProfileId` and `agentProfilePoolId` are mutually exclusive. Pass one or the other, never both.
</Warning>

On the platform, choose the profile or the pool in the dropdown next to **Run**.

See [Call a workflow from your code](/integrate/call-an-agent) for the full execute call.

## Profile configuration

<AccordionGroup>
  <Accordion title="Proxy settings">
    * **Proxy country code** — the country the proxy routes through. One of `us`, `uk`, `fr`, `it`, `jp`, `au`, `de`, `fi`, `ca`.
    * **Proxy type** — the managed proxy connection to use. `basic`.
    * **Persistent IP** — keep the same IP address across requests.

    <Warning>
      Persistent IP locks the profile to a `basic` proxy in the `us`. The country and type selectors are fixed while it is on. It works with a platform-managed proxy only. Custom and gateway proxy modes reject it.
    </Warning>
  </Accordion>

  <Accordion title="Captcha solver">
    Turn automatic captcha solving on or off for the profile.
  </Accordion>

  <Accordion title="Cache persistence">
    Cache persistence controls whether browser cache and cookies survive between runs.

    * **On** — the profile keeps session state, cookies and cached data across runs.
    * **Off** (the default) — every execution starts with a fresh browser state.

    Clear the stored cache at any time with **Clear Cache** on the profile.
  </Accordion>

  <Accordion title="Inbox email prefix">
    Every profile gets an inbox at `{prefix}@agentmail.asteroid.ai`. The default prefix is the profile's UUID. Set a prefix to get a readable address. See [Workflow emails](/concepts/emails).
  </Accordion>
</AccordionGroup>

Create and manage profiles on the platform, through the API, or through the SDKs. See the [API reference](/api-reference/overview).

<Warning>
  Deleting a profile affects every workflow that references it. Check that no live automation depends on it first.
</Warning>

## Credentials

Store credentials in the profile's **Vault**. Each entry has a name and a value.

The platform mirrors each vault name into a placeholder token of the form `##CREDENTIAL_NAME##`. The name is uppercased, with underscores, to match how substitution normalises it.

Use the placeholder in:

* **Agent node instructions**
* **Browser automation scripts** — the runtime injects the decrypted value into browser inputs only, not into shell or file tools

This injection path is separate from the `args` a scripted Agent node receives. Those come from the node's declared inputs. See [Nodes](/concepts/nodes).

<Warning>
  Never paste a real secret into instructions or scripts as plain text. Use a vault placeholder.
</Warning>

Read [Security](/support-security/security) for how Asteroid stores and encrypts these values.

## Two-factor codes

A profile can hold a TOTP secret, so the workflow generates its own authenticator codes. Asteroid supports every standard TOTP provider, including Google Authenticator, Microsoft Authenticator, Authy and 1Password.

<Steps>
  <Step title="Get the TOTP secret key">
    Ask the target service for the manual setup key rather than the QR code. Most sites offer it behind a **Can't scan it?**, **manual entry** or **setup key** link.

    The key is a Base32 string of 16–32 characters.
  </Step>

  <Step title="Store it in the vault">
    Create a credential on the profile and paste the key as the value.

    The credential name must start with `TOTP_` or `2FA_`. The rest of the name is yours to choose.
  </Step>

  <Step title="Run the workflow">
    Nothing needs enabling on the node. Agent nodes can always generate TOTP codes. The tool works as soon as the profile holds a TOTP credential.
  </Step>
</Steps>

Codes expire after 30 seconds, so tell the workflow to generate one immediately before it submits.

For codes that arrive by email instead, see [Workflow emails](/concepts/emails).

## Cookies

A profile can store site cookies, so an authenticated session survives between runs. Add cookies when you create the profile, or manage them later through the API.

A cookie has these fields:

| Field       | Type                        | Notes                         |
| ----------- | --------------------------- | ----------------------------- |
| `id`        | string                      | Present on an existing cookie |
| `name`      | string                      | Display name                  |
| `key`       | string                      | Cookie name                   |
| `value`     | string                      | Cookie value                  |
| `domain`    | string                      | For example `.example.com`    |
| `secure`    | boolean                     |                               |
| `httpOnly`  | boolean                     |                               |
| `sameSite`  | `Strict` \| `Lax` \| `None` |                               |
| `expiry`    | string                      | ISO 8601                      |
| `createdAt` | string                      | ISO 8601                      |

## Profile pools

A **profile pool** groups profiles together. You point a run at the pool, and Asteroid picks a profile from it.

Pools solve four problems:

* **Credential conflicts** — stop two executions using one account at the same time.
* **Rate limits** — spread requests across several accounts.
* **Availability** — fall back to another profile when one is busy.
* **Manual selection** — remove the choice from every execute call.

### Selection strategies

A pool uses one of two strategies.

| Strategy                          | Behaviour                            | Use it for                            |
| --------------------------------- | ------------------------------------ | ------------------------------------- |
| **Least recently used** (default) | Picks the profile idle for longest   | Spreading load evenly across accounts |
| **Most recently used**            | Picks the profile used most recently | Keeping one session warm and cached   |

Least recently used rotates fairly. With profiles A, B and C, an execution after B picks whichever of A or C idled longest.

Most recently used concentrates work on fewer profiles. It keeps browser state and authenticated sessions warm.

### Concurrent use

`allowConcurrentUse` decides whether a busy profile can be picked again.

| Value             | Behaviour                                                            |
| ----------------- | -------------------------------------------------------------------- |
| `false` (default) | Skip any profile tied to an active run. Strict credential isolation. |
| `true`            | Pick any profile, busy or not. Maximum availability.                 |

<Warning>
  With `allowConcurrentUse: false`, a request fails immediately when every profile in the pool is busy. The error says no profile is available. Add more profiles, or allow concurrent use.
</Warning>

### Pool constraints

<AccordionGroup>
  <Accordion title="Mutual exclusivity">
    An execute call takes `agentProfileId` or `agentProfilePoolId`, never both.

    ```json theme={null}
    { "agentProfilePoolId": "pool-456" }
    ```
  </Accordion>

  <Accordion title="Organization scope">
    * Every profile in a pool belongs to the same organization.
    * A pool name is unique within an organization.
    * A profile from another organization cannot join the pool.
  </Accordion>

  <Accordion title="Availability">
    * A pool needs at least one profile before an execution can use it.
    * Remove the last profile and no new execution can use the pool.
  </Accordion>

  <Accordion title="Pool size">
    Match the pool size to your parallelism. Five simultaneous runs need at least five profiles. Add one or two spare profiles for peak load.
  </Accordion>
</AccordionGroup>

A pool works with every profile feature — credentials, cookies, TOTP secrets, inbox and cache persistence. The selected profile's configuration applies exactly as if you had named it yourself.

<CardGroup cols={2}>
  <Card title="Call a workflow" icon="code" href="/integrate/call-an-agent">Pass a profile or a pool on the execute call</Card>
  <Card title="Workflow emails" icon="mail" href="/concepts/emails">The inbox each profile owns</Card>
  <Card title="Workflow settings" icon="settings" href="/concepts/workflow-settings">What the workflow owns instead of the profile</Card>
  <Card title="Security" icon="shield" href="/support-security/security">How Asteroid protects stored credentials</Card>
</CardGroup>
