curl -sS -X POST "https://api.adscrawl.net/cdp/live-token" \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{"sessionId": "SESSION_ID"}'
// Step 1: request a live control token
const token = await fetch("https://api.adscrawl.net/cdp/live-token", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
body: JSON.stringify({ sessionId: "SESSION_ID" }),
}).then((r) => r.json());
// Step 2: open the live control WebSocket using the returned controlUrl
const socket = new WebSocket(token.controlUrl);
socket.addEventListener("open", () => {
console.log("Live control session connected");
});
socket.addEventListener("close", (event) => {
console.log("Session closed:", event.code, event.reason);
});
{
"ok": true,
"controlUrl": "wss://api.adscrawl.net/cdp/live/SESSION_ID?controlToken=<single-use-token>",
"expiresAt": 1785726630000
}
Remote CDP
Issue Live Control Token
Issue a single-use, 30-second control token to take live interactive control of an existing CDP session via a dedicated WebSocket connection.
POST
/
cdp
/
live-token
curl -sS -X POST "https://api.adscrawl.net/cdp/live-token" \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{"sessionId": "SESSION_ID"}'
// Step 1: request a live control token
const token = await fetch("https://api.adscrawl.net/cdp/live-token", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
body: JSON.stringify({ sessionId: "SESSION_ID" }),
}).then((r) => r.json());
// Step 2: open the live control WebSocket using the returned controlUrl
const socket = new WebSocket(token.controlUrl);
socket.addEventListener("open", () => {
console.log("Live control session connected");
});
socket.addEventListener("close", (event) => {
console.log("Session closed:", event.code, event.reason);
});
{
"ok": true,
"controlUrl": "wss://api.adscrawl.net/cdp/live/SESSION_ID?controlToken=<single-use-token>",
"expiresAt": 1785726630000
}
When you need to step in and interact with a running CDP session in real time, use this endpoint to issue a short-lived control token. Pass the returned
When the live-control WebSocket closes, the server sends one of the following reason codes:
controlUrl directly to a WebSocket constructor to begin live control.
string
required
The active CDP session ID you want to take live control of.
Response
boolean
true when the token was issued successfully.string
A
wss:// WebSocket URL with the single-use controlToken already embedded as a query parameter. Pass this directly to new WebSocket(...); do not replace or modify the token.number
Unix timestamp in milliseconds when the
controlToken expires. The token is valid for 30 seconds and can only be used once.| Status | Meaning |
|---|---|
| 200 | Token issued; controlUrl and expiresAt are in the response body. |
| 400 | sessionId is missing from the request body. |
| 401 / 403 | The API key is invalid or does not own the target session. |
| 404 / 409 / 410 | The session is missing, stopping, or expired. |
| 503 | The session backend is unavailable. |
| 500 | Failed to issue or store the control token. |
The
controlToken expires after 30 seconds and can only be consumed once. If the WebSocket connection fails or is not opened in time, call POST /cdp/live-token again to get a fresh token.Open the live WebSocket
Open a live-control WebSocket connection to the target session atwss://api.adscrawl.net/cdp/live/{sessionId}?controlToken={token}. The server validates the controlToken, connects to the session backend, and then upgrades your client connection. Once connected, CDP messages are proxied bidirectionally and you have full interactive control.
string
required
The session ID embedded in the
controlUrl returned by POST /cdp/live-token.string
required
The single-use token from
POST /cdp/live-token. It must be used within 30 seconds of issuance and can only be consumed once.| Code | Reason | Cause |
|---|---|---|
| 1000 | cdp_upstream_closed | The upstream CDP session closed normally. |
| 1000 | idle_timeout | The session exceeded the configured idleTimeoutMs. |
| 1000 | max_timeout | The session exceeded the configured maxSessionMs. |
| 1011 | cdp_upstream_disconnected | The upstream CDP connection dropped unexpectedly. |
| 1011 | cdp_upstream_error | An error occurred on the upstream CDP connection. |
| Status | Meaning |
|---|---|
| 101 | WebSocket upgrade succeeded; live control is now active. |
| 401 | controlToken is invalid, expired, already used, or does not match sessionId. |
| 404 / 409 / 410 | The session is missing, stopping, or expired. |
| 502 | The session backend could not be reached before the 101 upgrade. |
| 503 | The session backend or control infrastructure is unavailable. |
Live control tokens are designed for short bursts of manual or conditional interaction. For fully automated workflows, drive the session directly through
cdpBaseUrl with Playwright or Puppeteer instead.curl -sS -X POST "https://api.adscrawl.net/cdp/live-token" \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{"sessionId": "SESSION_ID"}'
// Step 1: request a live control token
const token = await fetch("https://api.adscrawl.net/cdp/live-token", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
body: JSON.stringify({ sessionId: "SESSION_ID" }),
}).then((r) => r.json());
// Step 2: open the live control WebSocket using the returned controlUrl
const socket = new WebSocket(token.controlUrl);
socket.addEventListener("open", () => {
console.log("Live control session connected");
});
socket.addEventListener("close", (event) => {
console.log("Session closed:", event.code, event.reason);
});
{
"ok": true,
"controlUrl": "wss://api.adscrawl.net/cdp/live/SESSION_ID?controlToken=<single-use-token>",
"expiresAt": 1785726630000
}