Tilion exposes each session over the Chrome DevTools Protocol. Any CDP client attaches unchanged: Playwright, Puppeteer, chromedp, or a raw WebSocket.

Connect tokens are single-use and short-lived

This is the one piece of Tilion’s design that surprises people, so it is worth stating plainly. connect_url is minted on demand. It is not a stored property of the session. A null from the read endpoints does not mean the session is broken. The session is fine; you just asked for the wrong thing. Each URL carries a signed token scoped to that one session and expires in 300 seconds (connect_expires_in on create, expires_in on /connect). This design trades convenience for containment. A leaked URL is only useful for five minutes and cannot be replayed against a different session, and in exchange you cannot cache a connect_url or read one back.

Getting a fresh URL

The field is expires_in here and connect_expires_in on create. Handle both.

Writing a client that gets this right

Mint immediately before you attach, and never persist the URL:
If your process might sit idle between creating a session and attaching, always re-mint. A token minted more than five minutes ago will be rejected.

Use the existing context and page

A new session boots with exactly one browser context containing one page.
Calling browser.newContext() or context.newPage() starts an additional renderer. That is supported, but each one consumes memory in your session and you are unlikely to need it.

Closing

Close the CDP client first, then release the session:
DELETE is safe to call on a session that is already gone: it returns 404, which you can treat as success. Both calls belong in finally so a thrown error cannot leak a running session.

Puppeteer

Puppeteer attaches to the same URL through puppeteer.connect:
chromedp and every other CDP client work the same way: hand them the connect_url as the remote endpoint.

Raw WebSocket

The connect_url is an ordinary CDP endpoint, so you can speak the protocol directly:

Troubleshooting

connect_url is null on create. Raw CDP access is not enabled for your key. Contact support rather than retrying: retrying will not change the result. WebSocket closes immediately with code 1008. The token is expired, malformed, or belongs to a different session. Mint a fresh one. WebSocket closes with 1011. The session has no live browser, usually because it was already released or hit its idle timeout. Create a new session. connectOverCDP hangs. This is usually a network path problem. The connect URL uses a dedicated port, so confirm outbound WebSocket traffic on that port is not blocked by your firewall or CI egress rules.