Skip to main content

Using Sessions

Sessions keep a browser context alive -- cookies, viewport, and navigation history persist across API calls. Use sessions for multi-step workflows like logging in, filling forms, or interacting with a page over time.

Most endpoints work without a session. Browsr auto-creates a temporary session, runs your request, and cleans up. Create a persistent session only when you need state across multiple calls.

Create a session

curl -X POST https://api.browsr.dev/sessions \
-H "Authorization: Bearer $BROWSR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"headless": true,
"start_url": "https://example.com",
"use_random_user_agent": true
}'
ParameterTypeDefaultDescription
headlessbooleanfalseRun Chrome without UI
requested_namestring--Human-readable session name
start_urlstring--Navigate on creation
cdp_urlstring--Connect to existing Chrome DevTools Protocol endpoint
use_random_user_agentbooleanfalseRandomize user agent
disable_automation_detectionbooleanfalseApply stealth tweaks
user_agentstring--Custom user agent
profile_idstring--UUID of a saved profile to load
{
"status": "ready",
"session_id": "session-abc123",
"frame_token": "eyJhbG...",
"sse_url": "https://api.browsr.dev/stream/sse?session_id=session-abc123"
}

Async provisioning

When workers need to scale, the response returns status: "provisioning" with a provision_id. Poll until ready:

curl -X POST https://api.browsr.dev/sessions/provision/PROVISION_ID \
-H "Authorization: Bearer $BROWSR_API_KEY"

Stages: provisioning > scaling > worker_found > creating > ready

Use a session

Pass session_id to any endpoint. All calls hit the same browser instance, so cookies, localStorage, and page state persist.

# Login
curl -X POST https://api.browsr.dev/commands \
-H "Authorization: Bearer $BROWSR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"session_id": "session-abc123",
"commands": [
{"command": "type_text", "data": {"selector": "#email", "text": "user@example.com", "clear": true}},
{"command": "type_text", "data": {"selector": "#password", "text": "secret", "clear": true}},
{"command": "click", "data": {"selector": "button[type=submit]"}},
{"command": "wait_for_navigation", "data": {"timeout_ms": 5000}}
]
}'

# Scrape the authenticated page (same session, still logged in)
curl -X POST https://api.browsr.dev/v1/scrape \
-H "Authorization: Bearer $BROWSR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/dashboard", "session_id": "session-abc123", "formats": ["markdown"]}'

List sessions

curl https://api.browsr.dev/sessions \
-H "Authorization: Bearer $BROWSR_API_KEY"

Delete a session

curl -X DELETE https://api.browsr.dev/sessions/session-abc123 \
-H "Authorization: Bearer $BROWSR_API_KEY"

Returns 204 No Content. Always delete sessions when done to free resources.

tip

If you omit session_id from a /commands or /v1/scrape request, a session is created automatically and returned in the response.

Streaming

Stream live viewport screenshots from a session via Server-Sent Events:

GET /stream/sse?session_id=SESSION_ID&token=FRAME_TOKEN
ParameterTypeDescription
session_idstringBrowser session ID
tokenstringFrame token (from session creation response)
with_boxesbooleanInclude bounding box overlay
widthnumberScreenshot width
heightnumberScreenshot height
const source = new EventSource(
`https://api.browsr.dev/stream/sse?session_id=session-abc123&token=${frameToken}`
);
source.addEventListener('frame', (e) => {
const data = JSON.parse(e.data);
document.getElementById('viewport').src = `data:image/png;base64,${data.image}`;
});