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
}'
| Parameter | Type | Default | Description |
|---|---|---|---|
headless | boolean | false | Run Chrome without UI |
requested_name | string | -- | Human-readable session name |
start_url | string | -- | Navigate on creation |
cdp_url | string | -- | Connect to existing Chrome DevTools Protocol endpoint |
use_random_user_agent | boolean | false | Randomize user agent |
disable_automation_detection | boolean | false | Apply stealth tweaks |
user_agent | string | -- | Custom user agent |
profile_id | string | -- | 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.
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
| Parameter | Type | Description |
|---|---|---|
session_id | string | Browser session ID |
token | string | Frame token (from session creation response) |
with_boxes | boolean | Include bounding box overlay |
width | number | Screenshot width |
height | number | Screenshot 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}`;
});