Sessions
Sessions keep the same worker (browser) assigned to you across multiple requests, so your cookies, tabs, and login state carry over between calls.
Sessions require a Standard or Pro plan.
Start a Session
Add session.preserve: true to your request. The response includes a sessionId and the workerId — save both for subsequent requests.
{
"actions": [
{ "openNewTab": "https://example.com/login" },
{ "fill": ["input[name=email]", "user@example.com"] },
{ "fill": ["input[name=password]", "password123"] },
{ "click": "button[type=submit]" },
{ "waitForElement": ".dashboard" }
],
"session": { "preserve": true }
}
Response:
{
"success": true,
"data": { "success": true },
"workerId": "-Om8GAObZSvE8trPMPZF",
"sessionId": "sess_a1b2c3d4e5f6",
"duration": 5400
}
Continue a Session
Send the sessionId and workerId from the previous response:
{
"actions": [
{ "click": ".settings-link" },
{ "screenshot": "viewport" }
],
"workerId": "-Om8GAObZSvE8trPMPZF",
"session": { "id": "sess_a1b2c3d4e5f6" }
}
The session timeout is automatically refreshed on each request.
Close a Session
When you're done, close the session to release the worker:
{
"actions": [
{ "screenshot": "viewport" }
],
"workerId": "-Om8GAObZSvE8trPMPZF",
"session": {
"id": "sess_a1b2c3d4e5f6",
"close": true
}
}
Custom Session Timeout
Default session timeout is 5 minutes. Set a custom timeout (60 seconds to 30 minutes):
{
"actions": [...],
"session": {
"preserve": true,
"timeout": 600000
}
}
Override an Existing Session
If a worker is stuck in reserve state (e.g. your previous request crashed before closing the session), use session: { override: true } to force-claim it.
Without workerId — automatically picks any of your reserved workers:
{
"actions": [...],
"session": { "override": true }
}
With workerId — force-claims that specific worker:
{
"actions": [...],
"workerId": "-Om8GAObZSvE8trPMPZF",
"session": { "override": true }
}
Override drops the existing session immediately. Any state from the previous session (tabs, cookies, login) is still in the browser, but the old sessionId is no longer valid.
Session Lifecycle Summary
| Action | Request | Result |
|---|---|---|
| Start | session: { preserve: true } | Worker reserved, sessionId returned |
| Continue | workerId + session: { id: "..." } | Reuses worker, refreshes timeout |
| Close | workerId + session: { id: "...", close: true } | Worker released to online |
| Override | session: { override: true } | Force-claims a reserved worker |
| Custom timeout | session: { preserve: true, timeout: 600000 } | 10-minute session |
Example: Multi-Step Workflow
// Step 1: Login and start session
POST /v1/
{
"actions": [
{ "openNewTab": "https://app.example.com/login" },
{ "fill": ["#email", "user@example.com"] },
{ "fill": ["#password", "pass123"] },
{ "click": "#login-btn" },
{ "waitForElement": ".dashboard" }
],
"session": { "preserve": true }
}
// → Returns sessionId + workerId
// workerId: -Om8GAObZSvE8trPMPZF
// sessionId: sess_a1b2c3d4e5f6
// Step 2: Navigate and extract data
POST /v1/
{
"actions": [
{ "click": ".reports-link" },
{ "waitForElement": ".report-table" },
{ "extractAll": "tr.report-row", "options": {
"fieldMap": { "name": "td:first-child", "value": "td:last-child" },
"save": "reports"
}},
{ "getSavedData": ["reports"] }
],
"workerId": "-Om8GAObZSvE8trPMPZF",
"session": { "id": "sess_a1b2c3d4e5f6" }
}
// Step 3: Close session
POST /v1/
{
"actions": [
{ "screenshot": "fullpage" }
],
"workerId": "-Om8GAObZSvE8trPMPZF",
"session": { "id": "sess_a1b2c3d4e5f6", "close": true }
}