Skip to main content
Every Hyperbrowser session follows a predictable lifecycle from creation to termination. Understanding this lifecycle helps you build reliable automation workflows and manage resources effectively.

Session States

Sessions transition through these states:
  • active - Session is running and ready to accept connections
  • closed - Session has been terminated normally
  • error - Session encountered an error and terminated unexpectedly

Creating a Session

Create a new session with optional configuration.
import { Hyperbrowser } from "@hyperbrowser/sdk";

const client = new Hyperbrowser({
  apiKey: process.env.HYPERBROWSER_API_KEY,
});

// Create a new session
const session = await client.sessions.create({
  screen: {
    width: 1920,
    height: 1080,
  }
});

console.log(`Session ${session.id} is ${session.status}`);
console.log(`WebSocket endpoint: ${session.wsEndpoint}`);
console.log(`Live view: ${session.liveUrl}`);

Getting Session Details

Retrieve current information about a specific session:
const session = await client.sessions.get("session-id");

console.log("Session details:", {
  id: session.id,
  status: session.status,
  createdAt: session.createdAt,
  wsEndpoint: session.wsEndpoint,
  liveUrl: session.liveUrl,
});

Listing Sessions

Query all your sessions with optional filtering by status:
// List all sessions
const response = await client.sessions.list({
  status: "active",
  page: 1,
});

console.log(`Total sessions: ${response.totalCount}`);
console.log(`Showing page ${response.page} of ${Math.ceil(response.totalCount / response.perPage)}`);

response.sessions.forEach((session) => {
  console.log(`- ${session.id} (${session.status})`);
});

Stopping a Session

Always stop sessions when you’re done to free up resources:
// Stop a specific session
await client.sessions.stop("session-id");

console.log("Session stopped successfully");
Stopping a session is idempotent - you can safely call it multiple times without errors.

Complete Lifecycle Example

Here’s a complete example demonstrating best practices for session management:
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { chromium } from "playwright-core";
import { config } from "dotenv";

config();

const client = new Hyperbrowser({
  apiKey: process.env.HYPERBROWSER_API_KEY,
});

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

async function runAutomation() {
  // 1. Create session with configuration
  console.log("Creating session...");
  const session = await client.sessions.create({
    acceptCookies: true,
  });
  console.log(`Session created: ${session.id}`);
  console.log(`Watch live: ${session.liveUrl}`);

  try {
    // 2. Connect with Playwright
    const browser = await chromium.connectOverCDP(session.wsEndpoint);
    const context = browser.contexts()[0];
    const page = context.pages()[0];

    // 3. Use the session
    console.log("Waiting 5 seconds before navigating to example.com");
    await sleep(5000);
    await page.goto("https://example.com");
    const title = await page.title();
    console.log(`Page title: ${title}`);
    console.log("Waiting 5 seconds before stopping the session");
    await sleep(5000);
  } catch (error) {
    console.error("Automation failed:", error);
  } finally {
    // 4. Always stop the session
    console.log("Stopping session...");
    await client.sessions.stop(session.id);
    console.log("Session stopped");
  }
}

runAutomation().catch(console.error);

Automatic Timeout

Sessions automatically stop after some time based on their timeout. By default, this is based on your team’s default Session Timeout setting which you can change on the Settings page. You can also configure the timeout per session during session creation:
const session = await client.sessions.create({
  timeoutMinutes: 15,
});
Don’t rely solely on automatic timeouts. Always explicitly stop sessions in your cleanup logic to avoid unexpected charges and ensure proper resource management.

Error Handling

Use try-finally blocks to guarantee sessions are stopped, even when errors occur:
async function safeAutomation() {
  let session;
  
  try {
    session = await client.sessions.create();
    
    // Your automation code here
    await doSomething(session);
    
  } catch (error) {
    console.error("Automation failed:", error);
  } finally {
    // This always runs, whether success or failure
    if (session) {
      await client.sessions.stop(session.id);
    }
  }
}

Long Running Sessions

By default, when you disconnect from a session with an automation library like Playwright or Puppeteer, your session will automatically stop. To keep your session alive across disconnects, you can add the &keepAlive=true query parameter to your session’s WebSocket endpoint when you connect via CDP. This will keep your session alive until it times out based on the session’s timeout value (default team setting or timeoutMinutes parameter passed in when you create the session) or if you stop the session manually via the API.
The keepAlive won’t work if all the pages in the browser are closed. If all pages get closed, then the session will automatically stop.
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { chromium } from "playwright-core";
import { config } from "dotenv";

config();

const client = new Hyperbrowser({
  apiKey: process.env.HYPERBROWSER_API_KEY,
});

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

async function runAutomation() {
  // 1. Create session with configuration
  console.log("Creating session...");
  const session = await client.sessions.create({
    acceptCookies: true,
  });
  console.log(`Session created: ${session.id}`);
  console.log(`Watch live: ${session.liveUrl}`);

  try {
    // 2. Connect with Playwright and add the keepAlive parameter
    const browser = await chromium.connectOverCDP(
      `${session.wsEndpoint}&keepAlive=true`
    );
    const context = browser.contexts()[0];
    const page = context.pages()[0];

    // 3. Use the session
    console.log("Waiting 5 seconds before navigating to example.com");
    await sleep(5000);
    await page.goto("https://example.com");
    const title = await page.title();
    console.log(`Page title: ${title}`);
    console.log("Waiting 5 seconds before disconnecting from the browser");
    await sleep(5000);
    await browser.close();
  } catch (error) {
    console.error("Automation failed:", error);
  }
}

runAutomation().catch(console.error);

Best Practices

Follow these patterns to build reliable, cost-effective automation:

1. Always Use Try-Finally

Wrap session usage in try-finally blocks to guarantee cleanup:
let session;
try {
  session = await client.sessions.create();
  // ... use session
} finally {
  if (session) await client.sessions.stop(session.id);
}

2. Set Appropriate Timeouts

Match timeout to task duration. Add a buffer for unexpected delays:
  • Quick tasks: 5-10 minutes
  • Data scraping: 15-30 minutes
  • Long workflows: 30-60 minutes

3. Monitor Session State

Check session status before long-running operations:
const session = await client.sessions.get(sessionId);
if (session.status !== 'active') {
  throw new Error('Session is no longer active');
}

4. Clean Up Orphaned Sessions

Periodically audit for abandoned sessions:
const response = await client.sessions.list({ status: 'active' });
// Review and stop any unexpected active sessions

5. Handle Network Failures

Network issues can leave sessions running. Always implement cleanup:
process.on('SIGTERM', async () => {
  if (session) await client.sessions.stop(session.id);
  process.exit(0);
});

Next Steps