Banata

Browser Sessions

Session Lifecycle

How browser sessions move through states from creation to cleanup, and how to handle each state in your application.

Every browser session follows a predictable state machine. Understanding these states helps you build reliable automation that handles edge cases gracefully.


State Machine

typescript
queued → assigning → ready → active → ending → ended
                                         ↑
                                       failed
StateWhat's HappeningCDP Available?
queuedSession created, waiting for a machine to be assignedNo
assigningMachine selected, browser context is being preparedNo
readyBrowser is running, CDP URL is available — connect nowYes
activeA client is connected via CDPYes
endingCleanup in progress — recording upload, profile save, resource releaseNo
endedSession complete, all artifacts availableNo
failedSomething went wrong during the lifecycleNo

What Happens at Each Stage

queued

The session record has been created with your requested configuration. The platform is looking for the best machine to run it on. This typically takes under a second if there is a warm machine available.

If no machine is immediately available, one may need to be woken from suspension (a few seconds) or created fresh (up to 30 seconds). The session stays in queued with automatic retries.

assigning

A machine has been selected and the session has been reserved on it. A fresh browser context is being set up with your requested configuration — fingerprint, proxy, profile, recording, and other settings.

This state is brief, usually under 2 seconds.

ready

The browser context is running and the CDP WebSocket URL is available in the cdpUrl field. You can now connect with Puppeteer, Playwright, or any CDP client.

The session stays in ready until a client connects (at which point it moves to active) or until the time limit is reached.

active

A CDP client is connected and using the browser. The session remains active until:

  • You disconnect and call DELETE /v1/browsers?id=...
  • The maxDurationMs limit is reached
  • An unrecoverable error occurs

ending

Cleanup is in progress. If recording was enabled, the video file is being finalized and uploaded. If a profile key was specified, the browser state is being serialized and saved. Machine resources are being freed.

This state usually lasts a few seconds. Do not attempt to reconnect during this phase.

ended

Everything is done. The session record contains final metadata:

  • duration — total session time in seconds
  • artifacts — keys/URLs for recordings, screenshots, HAR files, and console logs
  • Timestamps for creation and end

failed

The session could not complete its lifecycle. Common causes:

  • No machine could be assigned after retry attempts
  • The machine encountered a fatal error during setup
  • A network issue prevented communication

Failed sessions include error information in the response. Resources are automatically cleaned up.


Polling for Status

The standard pattern is to poll the GET endpoint with a short interval until the session reaches ready:

typescript
async function waitForReady(sessionId: string, apiKey: string): Promise<string> {
  const maxAttempts = 30;
 
  for (let i = 0; i < maxAttempts; i++) {
    const res = await fetch(
      `https://api.boxes.banata.dev/v1/browsers?id=${sessionId}`,
      { headers: { Authorization: `Bearer ${apiKey}` } }
    );
    const data = await res.json();
 
    if (data.status === "ready" || data.status === "active") {
      return data.cdpUrl;
    }
    if (data.status === "failed" || data.status === "ended") {
      throw new Error(`Session ${data.status}`);
    }
 
    await new Promise((r) => setTimeout(r, 1000));
  }
 
  throw new Error("Session did not become ready in time");
}

Typical wait times:

ScenarioTime to Ready
Warm machine available1–3 seconds
Machine needs to wake from suspension3–8 seconds
New machine needs to be created10–30 seconds

Tip: The @banata-boxes/sdk SDK includes a waitForReady() method and a launch() convenience method that handles polling automatically with configurable timeouts.


Concurrent Session Limits

Each plan has a maximum number of browser sessions that can exist at the same time (including sessions in queued and assigning states):

PlanConcurrent Browser Sessions
Free1
Builder5
Pro25
Scale100

If you try to create a session that would exceed your limit, the API returns 429 Concurrent browser session limit reached. End existing sessions or upgrade your plan.


Monthly Browser Hours

Each plan includes a monthly allocation of browser hours:

PlanBrowser Hours/Month
Free5
Builder100
Pro1,000
Scale5,000

Browser hours are calculated from when a session reaches ready to when it reaches ended. If your monthly usage reaches the limit, new session creation returns 429 Monthly browser hours limit reached.


Session Artifacts

When a session ends, the artifacts field contains pointers to any generated outputs:

json
{
  "artifacts": {
    "screenshots": ["screenshots/org123/session456/page1.png"],
    "har": "har/org123/session456.har",
    "recording": "recordings/org123/session456.mp4",
    "consoleLogs": "logs/org123/session456.log"
  }
}

All fields are null if the corresponding feature was not enabled or no output was generated.


Next Steps