Limits & Billing

Billing model, rate limits, idle timeout, and known limitations

Last updated Jul 6, 2026

Billing

Browser API sessions are billed at 1 credit per 2 minutes, rounded up. A session that lasts 3 minutes costs 2 credits. A session that lasts 4 minutes 1 second also costs 2 credits (you're billed at the start of each 2-minute window).

Rate1 credit / 2 min
First creditCharged on connect (covers minutes 0-2)
Subsequent creditsCharged at the start of each new 2-minute window
RecordingFree — included in the per-minute rate
Geo-targetingFree — no per-country surcharge
Saved-session loadFree — no extra charge for loading cookies
Auto-disconnectWhen your credit balance reaches 0

Limits

ParameterValueNotes
Max session duration2 hoursHard cap; session ends automatically
Idle timeout~2 minutesNo CDP messages from client → disconnect
Max message size50 MBPer CDP frame
Concurrent connectionsper-account plan limitSee pricing
AuthenticationX-API-Key header or ?api_key= query paramHeader preferred; query param needed for clients that can't set custom WS headers

Avoiding the idle timeout

The connection is closed if your script is silent for about 2 minutes. Long workflow pauses (MFA wait, slow API polls, OAuth callbacks) need a keepalive — call any cheap browser API every ~60 seconds:

import asyncio

# during a long wait...
while waiting_for_mfa():
    await page.evaluate("() => 0")  # cheap keepalive
    await asyncio.sleep(60)

Playwright's page.wait_for_function() and page.wait_for_selector() also keep the session alive while they're polling — preferred for any "wait until X appears" loop.

The cleanest practice is browser.close() as soon as you're done — don't leave idle connections open just because you can.


Not supported

  • Selenium / ChromeDriver — only CDP-native clients (Playwright, Puppeteer, chromedp) are supported.

Error responses

Authentication and capacity errors come back as standard HTTP responses before the WebSocket upgrade, so your CDP client receives them as connection failures. Saved-session errors (404 / 409 / 422) are raised after the upgrade and arrive as a WebSocket close frame with code 1008 whose reason is "<status>: <json body>", e.g. 404: {"error": "session not found, not yet saved, or in use", ...} — Playwright surfaces it in the connectOverCDP error message.

StatusErrorCause
401X-API-Key requiredNo API key sent
403auth rejected: invalid_api_keyAPI key not recognised
402insufficient creditsCredit balance is 0
404session not found?session_id / ?session_name doesn't resolve
409session is being automatedThe session you're loading is in use by another job
422session has no stored dataSession was created but never saved
429Rate-limitedToo many active connections for this account
503browser service unavailableTransient — retry with backoff
503session saving not configuredSaved sessions temporarily unavailable (contact support)