Browser Sessions
Browser Sessions
Create and configure on-demand browser sessions with configurable weights, egress profiles, stealth, recording, and proxy support.
A browser session is a Chromium instance running on a remote machine, accessible through the Chrome DevTools Protocol (CDP). You create one with a single API call and connect to it from any CDP-compatible client.
Creating a Session
curl -X POST "https://api.boxes.banata.dev/v1/browsers" \
-H "Authorization: Bearer br_live_..." \
-H "Content-Type: application/json" \
-d '{
"weight": "light",
"stealth": true
}'Response:
{
"id": "j57f40gk2nm535kdj49n8e051s81wt6y",
"status": "queued",
"cdpUrl": null,
"weight": "light",
"isolation": "shared",
"egressProfile": "shared-dc"
}The session is created immediately and placed in a scheduling queue. Poll GET /v1/browsers?id=... until status becomes "ready", at which point cdpUrl contains the WebSocket URL you connect to.
An empty request body {} creates a session with all defaults: light weight, shared isolation, shared-dc egress, stealth off, recording off, captcha off.
Session Options
weight
Type: "light" | "medium" | "heavy"
Default: "light"
Controls how much memory is reserved for your session and how many pages it can handle:
| Weight | Memory | Max Pages | Best For | Required Plan |
|---|---|---|---|---|
light | 256 MB | 3 | Static sites, simple data extraction, single-page tasks | All plans |
medium | 512 MB | 5 | JavaScript-heavy sites, SPAs, form filling | All plans |
heavy | 1024 MB | 10 | Complex applications, multi-tab workflows, video | Pro and above |
If you request heavy on a Free or Builder plan, the API returns a 403 error with code PLAN_FEATURE_UNAVAILABLE.
Choose the lightest weight that fits your workload. Lighter sessions are more likely to be scheduled immediately on an available machine.
isolation
Type: "shared" | "dedicated"
Default: "shared"
Controls whether the session shares a machine with other sessions:
| Mode | Description | Required Plan |
|---|---|---|
shared | Session runs alongside others on the same machine. Most cost-efficient. | All plans |
dedicated | Session gets an entire machine to itself. Required for non-shared egress profiles. | Pro and above |
egressProfile
Type: "shared-dc" | "dedicated-dc" | "rotating-residential" | "static-residential" | "byo-proxy"
Default: "shared-dc" (or "dedicated-dc" if isolation is "dedicated", or "byo-proxy" if proxy is provided)
Controls the outbound IP profile for browser network traffic:
| Profile | Description | Required Plan |
|---|---|---|
shared-dc | Shared datacenter IPs. Default for shared isolation. | All plans |
dedicated-dc | Dedicated datacenter IPs. Requires dedicated isolation. | Pro and above |
rotating-residential | Rotating residential IP pool. Requires dedicated isolation. | Scale only |
static-residential | Reserved static residential IPs. Requires dedicated isolation. | Scale only |
byo-proxy | Bring your own proxy. Must include proxy config. | All plans (with proxy) |
Rules:
- If
egressProfileis anything other thanshared-dc, you must setisolationto"dedicated". - If you provide a
proxyobject,egressProfilemust be"byo-proxy"(or it defaults to"byo-proxy"automatically). - If
egressProfileis"byo-proxy", you must provide aproxyobject.
stealth
Type: boolean
Default: false
Enables the full anti-detection stack: fingerprint generation, navigator/WebGL/Chrome object spoofing, CDP-level user agent overrides, and runtime refresh patching.
| Plan | Stealth Available? |
|---|---|
| Free | No |
| Builder | Yes |
| Pro | Yes |
| Scale | Yes |
See Stealth & Anti-Detection for details on what is covered.
recording
Type: boolean
Default: false
When enabled, the session captures an MP4 video of the browser viewport at 5 frames per second. The recording is uploaded to cloud storage when the session ends and is available through the artifacts field in the session response.
| Plan | Recording Available? |
|---|---|
| Free | No |
| Builder | No |
| Pro | Yes |
| Scale | Yes |
captcha
Type: boolean
Default: false
Enables automatic solving of reCAPTCHA, hCaptcha, and Cloudflare Turnstile challenges encountered during navigation. Available on all plans.
proxy
Type: object (optional)
Routes all browser network traffic through your own proxy server. When you provide a proxy object, egressProfile is automatically set to "byo-proxy".
{
"proxy": {
"protocol": "http",
"host": "proxy.example.com",
"port": 8080,
"username": "user",
"password": "pass"
}
}| Field | Type | Required | Description |
|---|---|---|---|
protocol | "http" | "https" | "socks5" | Yes | Proxy protocol |
host | string | Yes | Proxy hostname or IP |
port | number | Yes | Proxy port |
username | string | No | Authentication username |
password | string | No | Authentication password |
profileKey
Type: string (optional)
A storage key pointing to a saved browser profile. Profiles contain serialized browser state — cookies, localStorage, sessionStorage, and other persistent data.
If the key points to an existing profile, it is loaded into the session before the CDP URL becomes available. When the session ends, the updated profile is saved back to the same key.
This enables workflows like:
- Session persistence — Log in once, save the profile, and reuse it in future sessions.
- Cookie management — Maintain authentication state across multiple automation runs.
maxDurationMs
Type: number (milliseconds, optional)
Default: Your plan's maximum session duration
Sets a per-session time limit. When the session reaches this duration, it is automatically ended and cleaned up.
The value cannot exceed your plan's limit:
| Plan | Maximum Duration |
|---|---|
| Free | 300,000 ms (5 minutes) |
| Builder | 900,000 ms (15 minutes) |
| Pro | 1,800,000 ms (30 minutes) |
| Scale | 3,600,000 ms (60 minutes) |
If you specify a value higher than your plan allows, the API returns a 403 error with code PLAN_LIMIT_EXCEEDED.
region
Type: string (optional)
A 3-letter region code (e.g., iad, lhr, cdg) indicating your preferred region for the machine running this session. Must match the pattern /^[a-z]{3}$/.
If omitted, the platform selects the best available region. If no machine is available in the preferred region, a nearby region may be used.
Full Request Example
{
"weight": "medium",
"isolation": "dedicated",
"egressProfile": "dedicated-dc",
"stealth": true,
"recording": true,
"captcha": false,
"maxDurationMs": 600000,
"region": "iad",
"profileKey": "profiles/org_123/shopping-session.json"
}Reading Session Status
Single session
curl "https://api.boxes.banata.dev/v1/browsers?id=SESSION_ID" \
-H "Authorization: Bearer br_live_..."Response:
{
"id": "j57f40gk2nm535kdj49n8e051s81wt6y",
"status": "ready",
"cdpUrl": "wss://browsers.banata.dev/ws?token=eyJ...&session=j57f...",
"weight": "light",
"isolation": "shared",
"egressProfile": "shared-dc",
"artifacts": null,
"duration": null,
"createdAt": 1772078705353
}After the session ends, artifacts will contain any recorded outputs:
{
"artifacts": {
"screenshots": [],
"har": null,
"recording": "recordings/org123/j57f40gk.mp4"
},
"duration": 34
}List active sessions
Omit the id parameter to list all active sessions for your organization:
curl "https://api.boxes.banata.dev/v1/browsers" \
-H "Authorization: Bearer br_live_..."Response:
{
"data": [
{
"id": "j57f40gk2nm535kdj49n8e051s81wt6y",
"status": "ready",
"cdpUrl": "wss://...",
"weight": "light",
"egressProfile": "shared-dc",
"createdAt": 1772078705353,
"startedAt": 1772078708000
}
]
}You can pass limit (1–100, default 25) to control how many sessions are returned:
curl "https://api.boxes.banata.dev/v1/browsers?limit=50" \
-H "Authorization: Bearer br_live_..."Ending a Session
curl -X DELETE "https://api.boxes.banata.dev/v1/browsers?id=SESSION_ID" \
-H "Authorization: Bearer br_live_..."Response: { "ok": true }
This triggers cleanup: the browser context is destroyed, recordings are uploaded, profiles are saved, and machine resources are freed. The session transitions through ending to ended.
Error Responses
| Status | Body | Cause |
|---|---|---|
| 400 | Invalid weight: 'ultra'. Must be one of: light, medium, heavy | Invalid enum value |
| 400 | Invalid maxDurationMs: must be a positive number | Invalid duration |
| 400 | If proxy is provided, egressProfile must be byo-proxy | Proxy/egress mismatch |
| 400 | Non-shared egress requires dedicated isolation | Egress without dedicated |
| 401 | Invalid or missing API key | Missing or invalid API key |
| 403 | Stealth mode is not available on the Free plan... | Feature requires upgrade |
| 403 | Session recording is not available on your current plan... | Feature requires upgrade |
| 403 | Heavy-weight sessions are not available on your current plan... | Feature requires upgrade |
| 403 | Code PLAN_LIMIT_EXCEEDED | maxDurationMs exceeds plan limit |
| 404 | Session not found | Invalid session ID on GET/DELETE |
| 429 | Rate limit exceeded. Please try again later. | Rate limit (60 creates/min) |
| 429 | Concurrent browser session limit reached | At plan's concurrent limit |
| 429 | Monthly browser hours limit reached | Monthly quota exhausted |
Next Steps
- Session Lifecycle — Understand the full state machine
- CDP Connection — Connect with Puppeteer, Playwright, or raw WebSocket
- Stealth & Anti-Detection — How anti-detection works
- Billing & Plans — Plan limits and feature availability