Skip to main content
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.

Browser Context Profiles overview

Learn when to use Browser Context Profile state

Vault Credentials

Add stale-session repair

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.
1

Create or list profiles

Create a named Browser Context Profile with /v1/profiles, or list existing profiles and choose one.
2

Start setup

Call POST /v1/profiles/{profileId}/setup-session and keep the returned session_id, cdp_url, base_url, timeout_seconds, and expires_at.
3

Connect and log in

Connect your browser automation framework to cdp_url, then log in manually or programmatically.
4

Save or discard

Save with POST /v1/profiles/{profileId}/save and { "session_id": "..." }. Cancelling setup or letting it time out discards unsaved setup state.
5

Run with saved state

Pass use_profile: true, or pass both use_profile: true and profile_id for a specific profile.

Create a profile

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"
  }'
{
  "id": "prof_abc123def4567890",
  "name": "Salesforce Production",
  "proxy_country_code": "US",
  "fingerprint_seed": "12345678",
  "created_at": "2026-06-04T18:00:00.000Z"
}
Create fieldTypeNotes
namestringRequired. 1–100 characters.
set_as_defaultbooleanOptional. Makes this the default profile for use_profile: true.
proxy_country_codestring | nullOptional. Supported country code, or null for no profile proxy.

Set up a profile

Start a setup browser:
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
  }'
{
  "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:
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.
After login, save the setup session:
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" }'
{
  "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:
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:
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:
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"
  }'
FieldTypeRequiredNotes
use_profilebooleanNoUse Browser Context Profile state. Without profile_id, TinyFish uses your default Browser Context Profile.
profile_idstringNoSelects a specific profile. Requires use_profile: true.
If use_profile: true is set and no default profile exists, the run returns 400. Create a profile and set it as default first.

Pair with Vault

For authenticated workflows, pair Browser Context Profiles with Vault so stale sessions can be repaired:
{
  "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

curl https://agent.tinyfish.ai/v1/profiles \
  -H "X-API-Key: $TINYFISH_API_KEY"

Inspect and update

# 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.
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.
LimitValue
Upload payload5 MB
Cookies per upload3,000
Domains per profile100

Common errors

StatusMeaningFix
400Invalid body, missing default profile, or profile_id without use_profile: trueFix the request or create a default profile
401Missing or invalid API keySet X-API-Key
404Profile or saved domain not foundCheck the profile ID or domain
409Setup/save/delete cleanup needs a retry, or the setup browser is no longer runningRetry the operation or start a new setup session

Profile endpoints

All requests require X-API-Key.
EndpointMethodPurpose
/v1/profilesGETList profiles
/v1/profilesPOSTCreate a profile
/v1/profiles/{profileId}GETGet profile details and saved domains
/v1/profiles/{profileId}PATCHRename a profile, set default, or update proxy location
/v1/profiles/{profileId}DELETEDelete a profile
/v1/profiles/{profileId}/setup-sessionPOSTStart an interactive setup browser
/v1/profiles/{profileId}/setup-session/cancelPOSTCancel a setup browser session without saving
/v1/profiles/{profileId}/savePOSTSave a setup browser session
/v1/profiles/{profileId}/uploadPOSTUpload cookies and storage manually
/v1/profiles/{profileId}/domains/{domain}DELETEDelete stored state for one domain

Next steps

Browser Context Profiles overview

Learn when to use Browser Context Profile state

Vault Credentials

Add stale-session repair