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

# Browser Context Profiles API

> Create, set up, and use Browser Context Profiles from the Agent API

Use the Browser Context Profiles API to create persistent browser state, set it up once, and reuse it in future
Agent API runs. The happy path is simple: create a profile, save a logged-in setup session, then pass
`use_profile: true` when you run automation.

<CardGroup cols={2}>
  <Card title="Browser Context Profiles overview" icon="window" href="/key-concepts/browser-context-profiles">
    Learn when to use Browser Context Profile state
  </Card>

  <Card title="Vault Credentials" icon="vault" href="/key-concepts/credentials">
    Add stale-session repair
  </Card>
</CardGroup>

## API setup lifecycle

Browser Context Profiles are API-controlled saved state. The hosted setup UI is a manual helper; API
users should bring their own Playwright, Puppeteer, or CDP controller and connect to the setup session's
`cdp_url`. Use `base_url` only for TinyFish HTTP session endpoints such as `/pages`; do not pass
`base_url` to Playwright.

<Steps>
  <Step title="Create or list profiles">
    Create a named Browser Context Profile with `/v1/profiles`, or list existing profiles and choose one.
  </Step>

  <Step title="Start setup">
    Call `POST /v1/profiles/{profileId}/setup-session` and keep the returned `session_id`,
    `cdp_url`, `base_url`, `timeout_seconds`, and `expires_at`.
  </Step>

  <Step title="Connect and log in">
    Connect your browser automation framework to `cdp_url`, then log in manually or programmatically.
  </Step>

  <Step title="Save or discard">
    Save with `POST /v1/profiles/{profileId}/save` and `{ "session_id": "..." }`. Cancelling
    setup or letting it time out discards unsaved setup state.
  </Step>

  <Step title="Run with saved state">
    Pass `use_profile: true`, or pass both `use_profile: true` and `profile_id` for a specific
    profile.
  </Step>
</Steps>

## Create a profile

```bash theme={null}
curl -X POST https://agent.tinyfish.ai/v1/profiles \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Salesforce Production",
    "set_as_default": true,
    "proxy_country_code": "US"
  }'
```

```json theme={null}
{
  "id": "prof_abc123def4567890",
  "name": "Salesforce Production",
  "proxy_country_code": "US",
  "fingerprint_seed": "12345678",
  "created_at": "2026-06-04T18:00:00.000Z"
}
```

| Create field         | Type             | Notes                                                             |
| -------------------- | ---------------- | ----------------------------------------------------------------- |
| `name`               | `string`         | Required. 1–100 characters.                                       |
| `set_as_default`     | `boolean`        | Optional. Makes this the default profile for `use_profile: true`. |
| `proxy_country_code` | `string \| null` | Optional. Supported country code, or `null` for no profile proxy. |

## Set up a profile

Start a setup browser:

```bash theme={null}
curl -X POST https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890/setup-session \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.example.com/login",
    "timeout_seconds": 900
  }'
```

```json theme={null}
{
  "session_id": "sess_123",
  "cdp_url": "wss://...",
  "base_url": "https://...",
  "timeout_seconds": 900,
  "expires_at": "2026-06-04T18:15:00.000Z"
}
```

Connect to `cdp_url` with Playwright, Puppeteer, Selenium, or another CDP client. For example,
with Playwright:

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { chromium } from "playwright";

  const CDP_URL = "<cdp_url from setup-session response>";
  const browser = await chromium.connectOverCDP(CDP_URL);
  const page = browser.contexts()[0].pages()[0];
  await page.goto("https://app.example.com/login");
  // Automate the login form here, or use your own CDP tooling to complete login.
  ```

  ```python Python theme={null}
  import asyncio
  from playwright.async_api import async_playwright

  CDP_URL = "<cdp_url from setup-session response>"

  async def main():
      async with async_playwright() as p:
          browser = await p.chromium.connect_over_cdp(CDP_URL)
          page = browser.contexts[0].pages[0]
          await page.goto("https://app.example.com/login")
          # Automate the login form here, or use your own CDP tooling to complete login.

  asyncio.run(main())
  ```
</CodeGroup>

After login, save the setup session:

```bash theme={null}
curl -X POST https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890/save \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "session_id": "sess_123" }'
```

```json theme={null}
{
  "domains_updated": ["example.com"],
  "domains_failed": [],
  "cookie_count": 12,
  "pages_captured": 1,
  "target_reads_skipped": 0,
  "domains_skipped": {
    "cookies_skipped": [],
    "local_storage_skipped": [],
    "session_storage_skipped": [],
    "blob_too_large": []
  }
}
```

## Save, cancel, or time out

The setup browser is temporary. If you do not save it before `expires_at`, or if you cancel it, TinyFish
discards the unsaved setup state. Cancel explicitly when you know you do not want to save:

```bash theme={null}
curl -X POST https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890/setup-session/cancel \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "session_id": "sess_123" }'
```

## Run with a Browser Context Profile

Use your default Browser Context Profile:

```bash theme={null}
curl -X POST https://agent.tinyfish.ai/v1/automation/run \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.example.com/dashboard",
    "goal": "Summarize the account health dashboard",
    "use_profile": true
  }'
```

Use a specific Browser Context Profile:

```bash theme={null}
curl -X POST https://agent.tinyfish.ai/v1/automation/run-sse \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.example.com/dashboard",
    "goal": "Download the latest invoice",
    "use_profile": true,
    "profile_id": "prof_abc123def4567890"
  }'
```

| Field         | Type      | Required | Notes                                                                                                        |
| ------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| `use_profile` | `boolean` | No       | Use Browser Context Profile state. Without `profile_id`, TinyFish uses your default Browser Context Profile. |
| `profile_id`  | `string`  | No       | Selects a specific profile. Requires `use_profile: true`.                                                    |

<Note>
  If `use_profile: true` is set and no default profile exists, the run returns `400`. Create a
  profile and set it as default first.
</Note>

## Pair with Vault

For authenticated workflows, pair Browser Context Profiles with Vault so stale sessions can be repaired:

```json theme={null}
{
  "url": "https://app.example.com/dashboard",
  "goal": "Check the dashboard and summarize anything urgent",
  "use_profile": true,
  "use_vault": true
}
```

The Browser Context Profile starts the run with saved logged-in state. If the session expires and a matching
Vault credential is available, TinyFish can use the credential to sign in again and repair the saved
state for future runs.

## List profiles

```bash theme={null}
curl https://agent.tinyfish.ai/v1/profiles \
  -H "X-API-Key: $TINYFISH_API_KEY"
```

## Inspect and update

```bash theme={null}
# Inspect saved domains
curl https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890 \
  -H "X-API-Key: $TINYFISH_API_KEY"

# Rename, make default, or update proxy location
curl -X PATCH https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890 \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Salesforce", "set_as_default": true, "proxy_country_code": "US" }'

# Delete one stored domain
curl -X DELETE https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890/domains/example.com \
  -H "X-API-Key: $TINYFISH_API_KEY"

# Delete the profile
curl -X DELETE https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890 \
  -H "X-API-Key: $TINYFISH_API_KEY"
```

## Upload cookies manually

Use manual upload when you already have exported browser state and do not need to open a setup
browser.

```bash theme={null}
curl -X POST https://agent.tinyfish.ai/v1/profiles/prof_abc123def4567890/upload \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cookies": [
      { "name": "session", "value": "...", "domain": "example.com" }
    ]
  }'
```

Manual upload supports cookies plus local and session storage.

| Limit               | Value |
| ------------------- | ----- |
| Upload payload      | 5 MB  |
| Cookies per upload  | 3,000 |
| Domains per profile | 100   |

## Common errors

| Status | Meaning                                                                            | Fix                                              |
| ------ | ---------------------------------------------------------------------------------- | ------------------------------------------------ |
| `400`  | Invalid body, missing default profile, or `profile_id` without `use_profile: true` | Fix the request or create a default profile      |
| `401`  | Missing or invalid API key                                                         | Set `X-API-Key`                                  |
| `404`  | Profile or saved domain not found                                                  | Check the profile ID or domain                   |
| `409`  | Setup/save/delete cleanup needs a retry, or the setup browser is no longer running | Retry the operation or start a new setup session |

## Profile endpoints

All requests require `X-API-Key`.

| Endpoint                                        | Method   | Purpose                                                 |
| ----------------------------------------------- | -------- | ------------------------------------------------------- |
| `/v1/profiles`                                  | `GET`    | List profiles                                           |
| `/v1/profiles`                                  | `POST`   | Create a profile                                        |
| `/v1/profiles/{profileId}`                      | `GET`    | Get profile details and saved domains                   |
| `/v1/profiles/{profileId}`                      | `PATCH`  | Rename a profile, set default, or update proxy location |
| `/v1/profiles/{profileId}`                      | `DELETE` | Delete a profile                                        |
| `/v1/profiles/{profileId}/setup-session`        | `POST`   | Start an interactive setup browser                      |
| `/v1/profiles/{profileId}/setup-session/cancel` | `POST`   | Cancel a setup browser session without saving           |
| `/v1/profiles/{profileId}/save`                 | `POST`   | Save a setup browser session                            |
| `/v1/profiles/{profileId}/upload`               | `POST`   | Upload cookies and storage manually                     |
| `/v1/profiles/{profileId}/domains/{domain}`     | `DELETE` | Delete stored state for one domain                      |

## Next steps

<CardGroup cols={2}>
  <Card title="Browser Context Profiles overview" icon="window" href="/key-concepts/browser-context-profiles">
    Learn when to use Browser Context Profile state
  </Card>

  <Card title="Vault Credentials" icon="vault" href="/key-concepts/credentials">
    Add stale-session repair
  </Card>
</CardGroup>
