Session management
A session keeps running after your CDP connection drops, whether you created it
with GET /connect, with POST /api/browser/create or from the dashboard.
Three things end one: you close it, its lifetime runs out, or the browser dies.
Disconnecting is not on that list.
A script that crashes without closing its browser leaves it running for the
rest of maxLifetime, which defaults to 7,200 seconds, and every second of that
is billed against your 48 hours.
Keep the session id
Section titled “Keep the session id”It comes back on the create:
curl -i -G "https://browser.rayobyte.com/connect" \ --data-urlencode "os=windows" \ --data-urlencode "vnc=true" \ -H "x-api-key: rb_live_YOUR_KEY"x-session-id: br_3f8a1c9d2e4b5a60x-vnc-url: https://sb-02.browser.rayobyte.com/vnc/vnc.html?path=ws%3Ftoken%3Dbr_5d4d8610784e2a91&autoconnect=true&resize=scale
wss://sb-02.browser.rayobyte.com/cdp/br_5d4d8610784e2a91br_ plus 16 hex characters. Reconnecting needs it.
The CDP URL and the live-view URL carry a second br_ id,
br_5d4d8610784e2a91 above. Close and status accept either id. Reconnect takes
only the x-session-id value and answers 404 Session not found to the other.
Reconnect
Section titled “Reconnect”curl "https://browser.rayobyte.com/connect?sessionId=br_3f8a1c9d2e4b5a60" \ -H "x-api-key: rb_live_YOUR_KEY"You get the CDP URL of the browser you already have, with its cookies, its storage and its open tabs. No new browser is created, no concurrency slot is taken, and the concurrency and rate limits do not apply.
Reconnecting to a session that has ended answers 410 Session is CLOSED, or
DEAD, or EXPIRED. An unknown id answers 404 Session not found.
from rayobrowse import Rayobrowsefrom playwright.sync_api import sync_playwright
client = Rayobrowse(endpoint="https://browser.rayobyte.com", api_key="rb_live_YOUR_KEY")ws_url = client.connect_url(os="windows", proxy=PROXY, vnc=True)session_id = client.last_session_id
try: with sync_playwright() as p: browser = p.chromium.connect_over_cdp(ws_url) context = browser.contexts[0] page = context.pages[0] if context.pages else context.new_page() page.goto("https://quotes.toscrape.com/") browser.close() # detaches; the browser keeps running
# Pick the same browser back up, tabs and cookies intact: browser = p.chromium.connect_over_cdp(client.reconnect_url(session_id)) print(browser.contexts[0].pages[0].url)finally: client.close(session_id)// Save as reconnect.mjs and run: node reconnect.mjsimport { Rayobrowse } from 'rayobrowse';import { chromium } from 'playwright';
const client = new Rayobrowse({ endpoint: 'https://browser.rayobyte.com', apiKey: 'rb_live_YOUR_KEY',});
const wsUrl = await client.connectUrl({ os: 'windows', proxy: PROXY, vnc: true });const sessionId = client.sessionId;
try { let browser = await chromium.connectOverCDP(wsUrl); await browser.contexts()[0].pages()[0].goto('https://quotes.toscrape.com/'); await browser.close(); // detaches; the browser keeps running
// Pick the same browser back up, tabs and cookies intact: browser = await chromium.connectOverCDP(await client.reconnectUrl(sessionId)); console.log(browser.contexts()[0].pages()[0].url()); await browser.close();} finally { await client.close(sessionId);}curl -X POST https://browser.rayobyte.com/api/browser/close \ -H "x-api-key: rb_live_YOUR_KEY" \ -H "content-type: application/json" \ -d '{"browserId": "br_3f8a1c9d2e4b5a60"}'{ "browserId": "br_3f8a1c9d2e4b5a60", "status": "CLOSED" }The field is browserId, not sessionId, and it takes either id. Sending
sessionId returns 400 browserId is required.
Closing a session that has already ended returns 200 with its final status,
so the call is safe to repeat. A session that belongs to another account
returns 404 Session not found. A 502 means the backend refused, the session
deliberately stays ACTIVE, and you should call again.
List your sessions
Section titled “List your sessions”curl "https://browser.rayobyte.com/user/api/sessions?status=ACTIVE&limit=50" \ -H "x-api-key: rb_live_YOUR_KEY"Newest first, 50 per page, with page, limit, status, since and until
as filters. limit is capped at 100, status takes ACTIVE, CLOSED, DEAD
or EXPIRED, and since and until take ISO 8601 dates. A malformed value is
a 400 naming the parameter:
{ "error": "status must be one of ACTIVE, CLOSED, DEAD, EXPIRED" }Rows that are still ACTIVE carry a live vnc_url. duration_ms is null
until the session ends, so summing that column over a page that includes running
sessions undercounts.
One session on its own:
curl "https://browser.rayobyte.com/api/browser/br_3f8a1c9d2e4b5a60/status" \ -H "x-api-key: rb_live_YOUR_KEY"The four states
Section titled “The four states”| State | Reached when | Final |
|---|---|---|
ACTIVE |
The browser started. Every session begins here | No |
CLOSED |
You closed it, or an operator did | Yes |
EXPIRED |
The lifetime ran out and the browser was removed | Yes |
DEAD |
The browser went away without being asked to | Yes |
Nothing leaves a final state. Entering one frees the concurrency slot at once,
and all three add their full duration to your browser hours: DEAD sessions bill
the time they ran.
Usage totals
Section titled “Usage totals”curl https://browser.rayobyte.com/user/api/usage \ -H "x-api-key: rb_live_YOUR_KEY"Totals plus up to 30 daily buckets, narrowed by since and until with the
same 400 for a malformed date. The counts and sums come back as JSON
strings, not numbers, so totals.total_sessions + 1 gives you "421".
Convert before you do arithmetic.
Your lifetime cap position is not on this endpoint. It is the usage block on
GET /user/api/me, with used_seconds, cap_seconds and remaining_seconds.
Was this page helpful?
Thanks — that helps us fix it.