Skip to main content
When multiple CDP clients are enabled for your account, a session supports one main client and up to two observers. Use the session’s connect_url for the main client. Add &role=observer for each observer. Observers can send CDP commands and receive events. They share the same browser and can change its pages, so coordinate actions between clients. The observer role is not read-only.

Attach two clients

Start with a running session and set TILION_API_KEY and TILION_SESSION_ID. Install requests and playwright for Python, or playwright-core for Node.js. No local browser installation is required. These examples connect a main client and an observer, open a page through the main client, and read its title through the observer. Run the Node.js example as an .mjs file with Node 20 or later.
The examples print Example Domain and disconnect both Playwright clients. The session remains running. Delete it with DELETE /v1/session/{id} when finished.

Add a second observer

Another process can connect to the same URL with &role=observer, including a raw CDP recorder. Clients can connect and disconnect in any order. Observers can connect before the main client and stay connected after it leaves. Main-client navigation receives automatic recovery when cdp_observe: true, the default. Setting it to false disables that behavior. Observer commands go directly to the browser without that recovery. On a custom-proxy session, recovery never switches the proxy exit.

Send raw CDP commands from an observer

Address targets with sessionId, as Playwright and Puppeteer already do. Observers cannot use Target.sendMessageToTarget or Target.exposeDevToolsProtocol, which can carry another command. The browser-wide commands Browser.close, Browser.crash, and Browser.crashGpuProcess are also refused with a CDP error, regardless of how the method name is written. Send text frames containing one JSON object each, with no repeated keys. Other frame formats return CDP error -32700. See Observer protocol restrictions for the reference.

Use REST alongside observers

A connected main client holds the session, so REST drive calls return 409 session_driven_by_client. Disconnect the main client before using REST. Observers do not hold the session and can remain connected, but their commands can still interfere with REST actions. Playwright’s browser.close() disconnects a client attached through connect_over_cdp or connectOverCDP. The raw CDP command Browser.close closes the browser when sent by the main client and is refused for observers. Close a raw observer’s WebSocket to disconnect it. See the CDP reference for client permissions and WebSocket close codes.