> For the complete documentation index, see [llms.txt](/llms.txt)

# Reconnecting to sessions in BAP

# Reconnecting to sessions in BAP

`reconnect()` keeps the browser alive after your connection closes and hands you the endpoints to come back to it. That's how a session survives a client restart, moves between processes, or gets handed from BAP to Puppeteer mid-run.

- A Browserless API token from your [account dashboard](https://browserless.io/account/)
- The BAP SDK installed and connecting, from the [BAP Quickstart](/bap/getting-started)

## How reconnects work

Normally the browser shuts down when your page's WebSocket closes. Calling `reconnect()` changes that: after you disconnect, the browser stays up for the `timeout` you passed (default `30000` milliseconds) waiting for a new connection. The call returns the URLs a future connection needs. Nothing about your current connection changes, so you keep working on the page and disconnect whenever you're ready.

**TypeScript:**

```typescript

const TOKEN = "YOUR_API_TOKEN_HERE";

const browser = Browserless.connect({
  browserWSEndpoint: "wss://production-sfo.browserless.io/chromium/bql",
  token: TOKEN,
});

try {
  const page = await browser.newPage();
  await page.goto("https://example.com/dashboard");

  // After close(), the browser now survives for 60 seconds waiting for us.
  const session = await page.reconnect({ timeout: 60_000 });
  console.log(session.browserQLEndpoint);
} finally {
  // Safe either way: after a successful reconnect() the keep-alive window
  // outlives this close; before one, closing prevents a leaked session.
  await browser.close();
}
```

**Python (Coming soon):**

```python

TOKEN = "YOUR_API_TOKEN_HERE"

with bap.Browserless.connect(
    browser_ws_endpoint="wss://production-sfo.browserless.io/chromium/bql",
    token=TOKEN,
) as browser:
    with browser.page() as page:
        page.goto("https://example.com/dashboard")

        # After the block exits, the browser survives for 60 seconds waiting for us.
        session = page.reconnect(timeout=60000)
        print(session["browserQLEndpoint"])
```

**Response:**

```text
https://production-sfo.browserless.io/chromium/bql/e4f5a6b7-c8d9-4012-a3b4-c5d6e7f8a9b0
```

## The endpoints you get back

The response carries four URLs, each for a different way back in. None of them include your token, so append it when you connect.

| Field | Reconnects | Use it with |
| ----- | ---------- | ----------- |
| `browserQLEndpoint` | The BrowserQL session | BAP and raw BQL queries |
| `browserWSEndpoint` | The browser over CDP | Puppeteer or Playwright `connect()` |
| `devtoolsFrontendUrl` | Chrome DevTools remotely | A regular browser, for inspection |
| `webSocketDebuggerUrl` | One page over CDP | Libraries that attach to a page instead of a browser |

## Continue the session from BAP

`browserQLEndpoint` comes back as an `https://` URL for HTTP-based BQL queries. BAP talks BrowserQL over WebSocket, so swap the scheme to `wss://` and connect a fresh browser to it:

**TypeScript:**

```typescript
// The returned endpoint is https://; BAP connects over WebSocket.
const endpoint = session.browserQLEndpoint!.replace(/^https/, "wss");

const resumed = Browserless.connect({
  browserWSEndpoint: endpoint,
  token: TOKEN,
});

try {
  const samePage = await resumed.newPage();

  // Still on the dashboard: this is the same browser, same state.
  console.log(await samePage.url());
} finally {
  await resumed.close();
}
```

**Python (Coming soon):**

```python
# The returned endpoint is https://; BAP connects over WebSocket.
endpoint = session["browserQLEndpoint"].replace("https", "wss", 1)

with bap.Browserless.connect(
    browser_ws_endpoint=endpoint,
    token=TOKEN,
) as resumed:
    with resumed.page() as same_page:
        # Still on the dashboard: this is the same browser, same state.
        print(same_page.url())
```

**Response:**

```text
https://example.com/dashboard
```

Cookies, storage, and the open page all persist, because it's the same browser process that never shut down.

## Hand the session to Puppeteer or Playwright

`browserWSEndpoint` is a CDP URL, which means a session that BAP set up, solved a CAPTCHA in, or navigated through a login can be finished by CDP tooling:

```javascript

const TOKEN = "YOUR_API_TOKEN_HERE";

// The endpoint BAP's reconnect() returned, plus your token.
const browser = await puppeteer.connect({
  browserWSEndpoint: `${session.browserWSEndpoint}?token=${TOKEN}`,
});

const [page] = await browser.pages();
console.log(await page.title());

// Terminate the session when done; a browser left to wait out its
// reconnect timeout still bills and holds a concurrency slot.
await browser.close();
```

This is the escape hatch for the methods BAP deliberately doesn't have, such as arbitrary `evaluate()` with argument passing. Do the protected part in BAP, then reconnect into Puppeteer for the rest.

## Timeout limits and billing

## FAQ & Troubleshooting

<details>
<summary>My reconnect endpoint stopped working after a minute</summary>

The `timeout` you passed is an idle grace period measured from disconnect. Once it elapses with no new connection, the browser terminates and the endpoint dies. Call `reconnect()` again on each new connection to keep the chain going, within your plan's maximum session duration.

</details>

<details>
<summary>I get an authorization error connecting to the returned endpoint</summary>

Returned endpoints never include token information. Pass your token the same way as a normal connection: the `token` option in BAP, or `?token=` appended to the URL for Puppeteer and Playwright.

</details>

<details>
<summary>Does the session keep billing while nobody is connected?</summary>

Yes. A browser waiting out its reconnect timeout occupies a concurrency slot like any connected session, and each reconnection is billed as a new connection. Close sessions you're done with instead of letting the timeout expire.

</details>

<details>
<summary>Can I raise the timeout above my plan's session limit?</summary>

No. A `timeout` beyond the plan maximum fails immediately with `Reconnect timeout (Xms) exceeds the maximum allowed limit (Yms).`, and reconnecting never extends the absolute deadline measured from when the browser started.

</details>

## Next steps