# Cloud Browser (/en/docs/developers/browser)



Cloud Browser is Chrome running in the cloud: connect directly with Playwright or Puppeteer, or watch and take over in Console.

## Three ways to connect [#three-ways-to-connect]

Run these examples with Node.js. Set `PRAXIS_API_KEY`, save the code as an `.mjs` file, then run it with `node`. Install the client packages; no local Chrome download is needed.

```bash
export PRAXIS_API_KEY="your API Key"
npm install playwright @browserbasehq/sdk
```

### One-step connection [#one-step-connection]

Connect to `wss://api-develop.deepraxis.ai/browser/v1/connect` to create a browser. Use `?session=<id>` to attach to an existing session, or `?name=<name>` to attach if that name exists and create otherwise. Names accept 1–128 letters, digits, or `. _ : -`. Do not send both `session` and `name`.

```javascript
import { chromium } from "playwright";

const headers = { Authorization: `Bearer ${process.env.PRAXIS_API_KEY}` };
const browser = await chromium.connectOverCDP(
  "wss://api-develop.deepraxis.ai/browser/v1/connect",
  { headers },
);
const cdp = await browser.newBrowserCDPSession();
const session = await cdp.send("Praxis.getSession");
console.log(session.sessionId, session.liveViewUrl, session.consoleUrl);
try {
  const page = await browser.contexts()[0].newPage();
  await page.goto("https://api-develop.deepraxis.ai/meta/v1/health");
  console.log(await page.textContent("body"));
} finally {
  await browser.close();
  // Release immediately when finished to stop billing.
  const closed = await fetch(
    `https://api-develop.deepraxis.ai/browser/v1/sessions/${session.sessionId}`,
    { method: "POST", headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({ status: "REQUEST_RELEASE" }) },
  );
  if (!closed.ok) throw new Error(await closed.text());
}
```

When creating a session, you may also pass `context`, `persist`, `timeout` (seconds), `idle` (milliseconds), `labels` and `viewport`. Encode the last two with `JSON.stringify` and `URLSearchParams`. Creation options are ignored when attaching to an existing session. A returned `connectUrl` carries credentials, so connecting needs no extra API key. Keep this URL private.

### Official Browserbase SDK [#official-browserbase-sdk]

Use your Praxis API key and set the official SDK's `baseURL` to `https://api-develop.deepraxis.ai/browserbase`. The SDK sends `X-BB-API-Key` automatically. You do not need a Browserbase project; `projectId` can be omitted.

```javascript
import Browserbase from "@browserbasehq/sdk";
import { chromium } from "playwright";

const bb = new Browserbase({
  apiKey: process.env.PRAXIS_API_KEY,
  baseURL: "https://api-develop.deepraxis.ai/browserbase",
});
const session = await bb.sessions.create({ timeout: 300, keepAlive: true });
try {
  const browser = await chromium.connectOverCDP(session.connectUrl);
  try {
    const page = await browser.contexts()[0].newPage();
    await page.goto("https://api-develop.deepraxis.ai/meta/v1/health");
    console.log(await page.textContent("body"));
  } finally {
    await browser.close();
  }
} finally {
  await bb.sessions.update(session.id, { status: "REQUEST_RELEASE" });
}
```

See the [Browserbase-compatible API](/en/docs/api/compatible/browserbase) for available endpoints. Proxies, stealth options, extensions and Selenium are unavailable. `region` and `solveCaptchas` are currently accepted but ignored: they do not select a region or solve CAPTCHAs.

### Create with REST, then connect [#create-with-rest-then-connect]

`POST /browser/v1/sessions` returns a `connectUrl` with credentials valid for the session's lifetime. Pass it directly to Playwright or Puppeteer without an additional API key.

```javascript
import { chromium } from "playwright";

const base = "https://api-develop.deepraxis.ai/browser/v1";
const headers = {
  Authorization: `Bearer ${process.env.PRAXIS_API_KEY}`,
  "Content-Type": "application/json",
};
const response = await fetch(`${base}/sessions`, {
  method: "POST", headers, body: JSON.stringify({ timeout: 300, keepAlive: true }),
});
if (!response.ok) throw new Error(await response.text());
console.log("X-Request-Id:", response.headers.get("X-Request-Id"));
const session = await response.json();
try {
  const browser = await chromium.connectOverCDP(session.connectUrl);
  try {
    const page = await browser.contexts()[0].newPage();
    await page.goto("https://api-develop.deepraxis.ai/meta/v1/health");
    console.log(await page.textContent("body"));
  } finally {
    await browser.close();
  }
} finally {
  const closed = await fetch(`${base}/sessions/${session.id}`, {
    method: "POST", headers, body: JSON.stringify({ status: "REQUEST_RELEASE" }),
  });
  if (!closed.ok) throw new Error(await closed.text());
}
```

See [Cloud Browser API](/en/docs/api/native/browser) for the full parameter reference. With Puppeteer, connect to the same URL using `puppeteer.connect({ browserWSEndpoint: session.connectUrl })`.

## Watch and take over [#watch-and-take-over]

Open **Browser › Sessions** in [Console](https://console-develop.deepraxis.ai), then choose a session to watch or take over. Send the CDP command `Praxis.getSession` to get `sessionId`, `liveViewUrl` and `consoleUrl`. To ask a user to log in or confirm an action, [request human takeover](/en/docs/api/native/browser/browserRequestHandoff) and [complete it](/en/docs/api/native/browser/browserCompleteHandoff) when finished.

Session statuses are `PENDING`, `RUNNING`, `ERROR`, `TIMED_OUT` and `COMPLETED`. API sessions created with `keepAlive=false` end after clients disconnect and no viewer remains. Sessions opened through one-step connection or Console are released by default after five minutes without a client or viewer. The maximum lifetime is six hours. There is no pause or hibernation; use a Context to retain login state for next time.

## Login state [#login-state]

[Create a Context](/en/docs/api/native/browser/browserCreateContext), then pass `browserSettings.context` when creating a session. `persist: true` saves cookies and localStorage when the session closes; IndexedDB is not saved. A concurrent writer using the same context may receive `409 CONTEXT_LOCKED`.

```javascript
// Reuse the REST setup above; contextId is the id returned by context creation.
const response = await fetch(`${base}/sessions`, {
  method: "POST", headers,
  body: JSON.stringify({
    timeout: 300,
    browserSettings: { context: { id: contextId, persist: true } },
  }),
});
```

## Pricing and limits [#pricing-and-limits]

* **$0.12 per browser hour**, billed per second with a one-minute minimum per session. Failures caused by the platform are billed only for actual seconds. Billing stops after release.
* By default, each account can run **10 concurrent sessions**, with a maximum of **six hours** per session.
* Proxies, CAPTCHA solving, stealth options, region selection and extensions are unavailable. Unsupported proxy, stealth and extension settings return `501`; `region` and `solveCaptchas` are currently accepted but ignored.
* Some websites, including Google and Baidu, may identify cloud browsers as bots.
* Keep the `X-Request-Id` response header when troubleshooting a request.
