Live view and sessions
Watch a hosted browser live, take control or share the view, manage your sessions, and keep a browser running so you can reconnect to it later.
Live view: watch, take control, share
In the dashboard, click a session to see which sites its traffic went to and to watch it live. Press Take control to click, type, scroll, paste and navigate in it yourself, for example to sign in or get past a check your script cannot. Your script stays connected the whole time, so pause it while you act. Human input counts as activity, so a session you are driving is not closed as idle. Share makes a link anyone can open without an account, watch only or with control, for 15 minutes to 4 hours and never past the end of the session.
Through the API:
# a live-view WebSocket for a running session (open it within 60 s)
# binary messages are JPEG frames, text messages are {"url","title","tabs"}
curl -H "authorization: Bearer cc_live_..." https://www.clearcotelabs.com/api/v1/browsers/<id>/live
# with control: the answer says "interactive": true when it was granted
curl -H "authorization: Bearer cc_live_..." "https://www.clearcotelabs.com/api/v1/browsers/<id>/live?control=1"
# a share link: control optional, 1 to 240 minutes (default 30)
curl -X POST -H "authorization: Bearer cc_live_..." -H "content-type: application/json" -d '{"control": false, "minutes": 60}' https://www.clearcotelabs.com/api/v1/browsers/<id>/shareWith control, send JSON text messages on the same WebSocket. Coordinates are fractions (0 to 1) of the frame you are looking at; anything else is ignored.
| Message | Does |
|---|---|
{"t":"mouse", | Press (down), release (up) or move; n is the click count, m the modifiers (Alt 1, Ctrl 2, Meta 4, Shift 8). |
{"t":"wheel", | Scroll by pixels at a point. |
{"t":"key", | A key going down or up, as a keyboard sends it. |
{"t":"text", | Insert text as if typed (up to 5000 characters). |
{"t":"nav",, forward, reload, or {"t":"nav", | History, reload, or open an http(s) address. |
GET /api/v1/browsers/<id> includes traffic: the top 20 sites by bytes for that session.
Managing sessions
# one session: status, traffic, seconds, cost so far
curl -H "authorization: Bearer cc_live_..." https://www.clearcotelabs.com/api/v1/browsers/<id>
# stop it (a running browser closes within about 15 seconds)
curl -X DELETE -H "authorization: Bearer cc_live_..." https://www.clearcotelabs.com/api/v1/browsers/<id>
# balance + your 20 most recent sessions
curl -H "authorization: Bearer cc_live_..." https://www.clearcotelabs.com/api/v1/browsers
# filtered by status and note text, up to 100; page back with before=<a createdAt you got>
curl -H "authorization: Bearer cc_live_..." "https://www.clearcotelabs.com/api/v1/browsers?status=active,ended¬e=shop-de&limit=50"
# label a session (null clears it)
curl -X PATCH -H "authorization: Bearer cc_live_..." -H "content-type: application/json" -d '{"note": "shop-de nightly"}' https://www.clearcotelabs.com/api/v1/browsers/<id>Give a session a note when you create it to find it again in the list and the dashboard. To start a session on the same server as an earlier one (warm caches, the same machine), pass that session's worker; when that server is full you get a 503, not another server.
A session also ends when you close the browser or disconnect, and when a limit below is reached. A stop request ends a session nobody connected to at once; a running browser is closed by its server within one report interval, about 15 seconds. GET answers with:
{
"id": "bs_…",
"status": "active", // see the table below
"proxy": "managed", // or "custom"
"createdAt": "…", "startedAt": "…", "endedAt": null,
"endReason": null, // set once ended, e.g. "user", "balance", "launch_failed"
"stopRequested": false,
"usage": { "bytesUp": 120334, "bytesDown": 4812009, "gb": 0.0049, "seconds": 41 },
"traffic": [ { "site": "example.com", "bytesUp": 20400, "bytesDown": 3100000 }, … ], // top 20 sites
"costEur": 0.0050,
"pricing": { "eurPerGb": 1, "eurPerHour": 0 }
}| status | Meaning |
|---|---|
pending | Created; nobody has connected yet. Counts towards the concurrency limit until it starts or expires. |
active | A browser is running and reporting usage. |
lost | No usage report for 5 minutes. Billed up to the last report; a late report puts it back to active. |
ended | Closed: you disconnected, stopped it, or a limit or the balance ended it. endReason says which. |
expired | Nobody connected within two minutes of creating it. Never billed. |
The list call, GET /api/v1/browsers, returns { balanceEur, sessions: [...] } with the same session objects, newest first.
Keeping a browser open and reconnecting
By default a session ends when your client disconnects. Start it with keepAlive: true and the browser keeps running instead, with its tabs, cookies and exit IP, so a later script (or the same one after a crash or a closed laptop) can pick up where the last one stopped:
# a new single-use connect URL for a running keepAlive session (connect within two minutes)
curl -X POST -H "authorization: Bearer cc_live_..." https://www.clearcotelabs.com/api/v1/browsers/<id>/connect- Leave it running by disconnecting: Playwright's
browser.close()(overconnectOverCDPit only disconnects), Puppeteer'sbrowser.disconnect(), or simply ending your process. - End it with
DELETE /api/v1/browsers/<id>, or by sending the CDP commandBrowser.close: Puppeteer'sbrowser.close()does, and in Playwrightawait (await browser.newBrowserCDPSession()).send("Browser.close"). Until then it keeps its slot in your concurrency limit. - One client at a time: a reconnect while another client is attached is refused with
409, as is one for a session started withoutkeepAlive. - The limits still apply while nobody is connected:
idleTimeoutSec(raise it, up to 1800, for a browser you mean to come back to),timeoutSec,maxGband your balance. A page left open keeps loading its background traffic, which is billed like any other.