Hybrid Automation
info
Hybrid Automation is only available on paid plans.
Hybrid automation lets you pause an automated script, hand control to a human via a secure live URL, and resume automation once they finish. Use it for login flows, 2FA, CAPTCHAs, or any step that requires human judgment.

How It Works
Create a liveURL through CDP and Browserless returns a one-time, shareable link. No API tokens are exposed and no extra software is needed.
| Behavior | Default | Override |
|---|---|---|
| Viewport | Resizes to match the end user's screen | resizable: false to keep the current viewport |
| Interaction | Click, type, scroll, touch, and tap enabled | interactable: false to block all input (view-only mode) |
| Stream quality | Full quality compressed video | quality: 1-100 to reduce bandwidth (useful for mobile) |
| Tab scope | Only the page used to create the URL | showBrowserInterface: true to stream all tabs (may increase CAPTCHA challenges) |
| Events | None | Listen for Browserless.liveComplete and Browserless.captchaFound |
Basic Implementation
- Puppeteer
- Playwright
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://production-sfo.browserless.io?token=YOUR_API_TOKEN_HERE',
});
const page = await browser.newPage();
await page.goto('https://practicetestautomation.com/practice-test-login/');
const cdp = await page.createCDPSession();
const { liveURL } = await cdp.send('Browserless.liveURL');
console.log('Share this URL:', liveURL);
// Wait for the user to complete their tasks
await new Promise((r) => cdp.on('Browserless.liveComplete', r));
// Continue automation...
await browser.close();
import { chromium } from 'playwright-core';
const browser = await chromium.connectOverCDP(
'wss://production-sfo.browserless.io/chromium/stealth?token=YOUR_API_TOKEN_HERE'
);
const [context] = await browser.contexts();
const page = await context.newPage();
await page.goto('https://practicetestautomation.com/practice-test-login/');
const cdpSession = await context.newCDPSession(page);
const { liveURL } = await cdpSession.send('Browserless.liveURL');
console.log('Share this URL:', liveURL);
// Wait for the user to complete their tasks
await new Promise((r) => cdpSession.on('Browserless.liveComplete', r));
// Continue automation...
await browser.close();
Example: Authentication with 2FA
Hand off the browser to a human for login flows that require verification, then resume automation with the authenticated session.
- Puppeteer
- Playwright
const login = async () => {
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://production-sfo.browserless.io?token=YOUR_API_TOKEN_HERE',
});
const page = await browser.newPage();
await page.goto('https://accounts.google.com');
const cdp = await page.createCDPSession();
const { liveURL } = await cdp.send('Browserless.liveURL');
console.log('Please complete login:', liveURL);
// Wait for the user to finish authentication
await new Promise((r) => cdp.on('Browserless.liveComplete', r));
// Continue with the authenticated session
// Your automation code here...
await browser.close();
};
const login = async () => {
const browser = await chromium.connectOverCDP(
'wss://production-sfo.browserless.io/chromium/stealth?token=YOUR_API_TOKEN_HERE'
);
const [context] = await browser.contexts();
const page = await context.newPage();
await page.goto('https://accounts.google.com');
const cdpSession = await context.newCDPSession(page);
const { liveURL } = await cdpSession.send('Browserless.liveURL');
console.log('Please complete login:', liveURL);
// Wait for the user to finish authentication
await new Promise((r) => cdpSession.on('Browserless.liveComplete', r));
// Continue with the authenticated session
// Your automation code here...
await browser.close();
};
tip
For advanced patterns like multi-stage workflows, read-only monitoring, programmatic session control, and bandwidth optimization, see Advanced Hybrid Automation Configurations.