Start Here
Quick Start
Launch your first browser session and connect to it with Puppeteer in under 5 minutes.
This guide walks you through creating a browser session, connecting to it, and navigating a page. By the end, you will have a working browser controlled from your local machine.
Prerequisites
- An API key (get one from the Banata dashboard or the seed endpoint)
- Node.js 18+ or Bun installed locally
puppeteer-coreinstalled (npm install puppeteer-core)
Step 1 — Create a Browser Session
Make a POST request to create a new session:
curl -X POST "https://api.boxes.banata.dev/v1/browsers" \
-H "Authorization: Bearer br_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'An empty body creates a session with default settings: light weight, shared isolation, shared-dc egress, no stealth, no recording.
Response:
{
"id": "j57f40gk2nm535kdj49n8e051s81wt6y",
"status": "queued",
"cdpUrl": null,
"weight": "light",
"isolation": "shared",
"egressProfile": "shared-dc"
}The session starts in queued status while a machine is assigned.
Step 2 — Poll Until Ready
Check the session status until it reaches ready:
curl "https://api.boxes.banata.dev/v1/browsers?id=j57f40gk2nm535kdj49n8e051s81wt6y" \
-H "Authorization: Bearer br_live_YOUR_API_KEY"When ready, the response includes a cdpUrl:
{
"id": "j57f40gk2nm535kdj49n8e051s81wt6y",
"status": "ready",
"cdpUrl": "wss://browsers.banata.dev/ws?token=eyJ...&session=j57f...",
"weight": "light",
"isolation": "shared",
"egressProfile": "shared-dc",
"artifacts": null,
"duration": null,
"createdAt": 1772078705353
}Step 3 — Connect with Puppeteer
Use the cdpUrl to connect Puppeteer to the remote browser:
import puppeteer from "puppeteer-core";
const API_KEY = "br_live_YOUR_API_KEY";
const BASE_URL = "https://api.boxes.banata.dev";
// Create session
const createRes = await fetch(`${BASE_URL}/v1/browsers`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
const session = await createRes.json();
// Poll until ready
let status = session;
while (status.status !== "ready") {
await new Promise((r) => setTimeout(r, 1000));
const res = await fetch(`${BASE_URL}/v1/browsers?id=${session.id}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
status = await res.json();
}
// Connect to the browser
const browser = await puppeteer.connect({
browserWSEndpoint: status.cdpUrl,
});
// Each session comes with a pre-configured page ready to use
const page = (await browser.pages())[0];
await page.goto("https://example.com");
console.log("Title:", await page.title());
// Clean up
await browser.disconnect();
await fetch(`${BASE_URL}/v1/browsers?id=${session.id}`, {
method: "DELETE",
headers: { Authorization: `Bearer ${API_KEY}` },
});Note: Each session provides a single pre-configured page. Use
(await browser.pages())[0]to access it.browser.newPage()is not supported — if you need multiple pages, create multiple sessions.
Enabling Stealth Mode
If you need anti-detection (requires Builder plan or higher), pass stealth: true:
curl -X POST "https://api.boxes.banata.dev/v1/browsers" \
-H "Authorization: Bearer br_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"stealth": true}'On the Free plan, stealth mode is not available. If you try to enable it, the API returns:
{
"error": "Stealth mode is not available on the Free plan. Upgrade to Builder or higher to enable anti-detection.",
"code": "PLAN_FEATURE_UNAVAILABLE",
"requiredPlan": "builder"
}Using the SDK
The @banata-boxes/sdk SDK handles polling and cleanup automatically:
npm install @banata-boxes/sdk puppeteer-coreimport puppeteer from "puppeteer-core";
import { BrowserCloud } from "@banata-boxes/sdk";
const cloud = new BrowserCloud({
apiKey: "br_live_YOUR_API_KEY",
baseUrl: "https://api.boxes.banata.dev",
});
const { cdpUrl, close } = await cloud.launch({
weight: "light",
stealth: true,
});
const browser = await puppeteer.connect({ browserWSEndpoint: cdpUrl });
const page = (await browser.pages())[0];
await page.goto("https://example.com");
console.log("Title:", await page.title());
await browser.disconnect();
await close();The SDK also includes automatic retry with exponential backoff for rate-limited and server-error responses.
Creating a Sandbox
Sandboxes work similarly. Create one with a runtime and size:
curl -X POST "https://api.boxes.banata.dev/v1/sandboxes" \
-H "Authorization: Bearer br_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"runtime": "bun", "size": "standard"}'Then execute commands:
curl -X POST "https://api.boxes.banata.dev/v1/sandboxes/exec" \
-H "Authorization: Bearer br_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "SANDBOX_ID", "command": "echo hello world"}'See Sandboxes for the full guide.
Next Steps
- Browser Sessions — Explore all session options (weight, stealth, recording, egress, proxy)
- Session Lifecycle — Understand session states and how to handle them
- CDP Connection — Details on connecting with Puppeteer, Playwright, and raw CDP
- Sandboxes — Launch code execution environments