Profiles
Keep agents logged in across sessions, and import your existing Browser Use Cloud profiles so profileId references keep working unchanged.
A profile is a persistent browser storage jar: cookies plus localStorage and sessionStorage per origin, held on disk in Playwright storage-state format. Attach one to a session and the agent starts already logged in to whatever that profile was logged in to, instead of hitting a sign-in wall on every run.
Profiles are the difference between an agent that can read a public listing and one that can work inside an authenticated application.
Create a profile
curl -X POST https://your-host/v3/profiles \
-H "Authorization: Bearer $OPENBROWSE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "my-profile"}'The response carries the profile id; pass it as profileId when you create a session. A new profile starts with an empty jar, which the first authenticated session fills.
List what exists:
curl https://your-host/v3/profiles \
-H "Authorization: Bearer $OPENBROWSE_API_KEY"Each profile in the response includes its cookieDomains, the domains the jar currently holds cookies for, and lastUsedAt, which updates whenever a session loads the profile. Rename with PATCH /v3/profiles/{id}, delete with DELETE /v3/profiles/{id} (which also removes the jar from disk).
Import from Browser Use Cloud
A cloud profile export is the same storage-state shape, cookies plus per-origin localStorage, so it imports directly. Import one and the local profile id matches the cloud id, so every profileId already in your code keeps working.
From a source checkout, the import script is the shortest route. It creates the profile if it does not exist, normalises the cookies, and backs up any existing jar to .import-bak:
.venv/bin/python -m scripts.import_profiles personal_profile.storage_state.json \
--profile-id <cloud-profile-id> --name "Personal Profile"A bundle (a JSON list of profile entries, or {"profiles": [...]} wrapping one) carries an id per entry, so one command imports many:
.venv/bin/python -m scripts.import_profiles bundle.jsonThat script ships with the repository rather than with the published package, so an installed copy uses the dashboard's Profiles importer or the API below instead. Both do the same work, and the endpoint also creates the profile if the id does not exist yet:
curl -X PUT https://your-host/v3/profiles/<profile-id>/storage-state \
-H "Authorization: Bearer $OPENBROWSE_API_KEY" \
-H "Content-Type: application/json" \
--data @personal_profile.storage_state.jsonVerify with GET /v3/profiles/<id>, or the Profiles page in the dashboard, which lists the imported cookieDomains.
The storage state format
{
"cookies": [
{
"name": "session",
"value": "...",
"domain": "example.com",
"path": "/",
"expires": 1999999999,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
}
],
"origins": []
}origins carries each origin's localStorage and sessionStorage, which the browser restores on load. A session works against a private copy of the profile and merges its changes back when the browser closes, so cookies acquired or refreshed during the run persist without flattening changes another session made meanwhile. The merge and final write are locked per profile, atomic and shielded against shutdown.
These files are live session credentials. Anyone holding one is logged in as you on every site it covers. Never commit them; a source checkout git-ignores data/ for this reason, and an installed copy keeps it out of the repository altogether by writing under ~/.openbrowse instead. Treat a profile export with the same care as a password manager export.
Using a profile
const session = await client.sessions.create({
task: "Open the billing page and return every invoice as structured data.",
model: "claude-sonnet-5",
profileId: "<profile-id>",
outputSchema: mySchema,
});For credentials the agent must type rather than carry as cookies, use sensitiveData alongside the profile; see writing tasks.
Sharing one profile between sessions
Concurrent sessions may use the same profile. Each starts from the profile state available when its private copy is opened, then a three-way merge applies only the keys that session changed on top of whatever the profile holds when the session finishes. Cookies are keyed by name, domain and path; localStorage and sessionStorage are merged per origin and key. Unrelated logins, preferences and cart changes therefore survive sessions closing in either order.
If two sessions change the same key, the session that merges later wins. A stale deletion does not remove a value another session refreshed after the deleting session began. A queued session that starts after an earlier session has finished sees that earlier session's merged state; sessions already running do not receive one another's changes live.
The live feed records a system event with action sharedProfile when a session opens a profile another session is already using. It is informational: both runs continue. Private working copies are removed after merging and any copies orphaned by a crash are discarded at the next startup, rather than being merged long after their session ended.
Listing and organising profiles
GET /v3/profiles returns an envelope rather than a bare array: {items, totalItems, pageNumber, pageSize}, with page and pageSize to walk it and query to search by name. A profile also carries an optional userId, settable on create and on update, which is there to tag whose login a jar represents when one instance serves several people. Nothing in the runtime reads it; it is yours to filter on.
The API reference has the full field list for each endpoint.
Next
Choosing a model covers which model and reasoning effort to pair with the work, and troubleshooting covers what to do when a session fails.
Cost control
What a run costs, how the real-cost engine prices it from actual token usage, and how maxCostUsd and CLOUD_MAX_COST_FACTOR enforce a hard stop-loss.
Solving CAPTCHAs
How OpenBrowse solves CAPTCHAs through CapSolver: which types are solved, which are only recognised, what a solve costs, and why the checkbox never ticks.