Quick Start
Create a Session
Run the following with your wallet’s private key (requires USDC on Base):PRIVATE_KEY=0x... npx tsx scripts/test-with-wallet.ts
API Reference
Create Session
Creates a new browser session with prepaid time.
POST /browser/session/create
Request Body:
{
"estimatedMinutes": 30
}
First Response (402)
With Payment (200)
When you first make a request, you’ll receive a 402 Payment Required response with payment details:{
"x402Version": 1,
"accepts": [{
"scheme": "exact",
"network": "base",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"maxAmountRequired": "500000",
"payTo": "0x...",
"resource": "https://x402.browserbase.com/browser/session/create"
}]
}
After sending the payment header, you’ll receive your session details:{
"sessionId": "abc-123",
"connectUrl": "wss://connect.browserbase.com/...",
"paidMinutes": 30,
"expiresAt": "2025-12-03T18:00:00Z",
"pricing": {
"ratePerHour": 0.12,
"amountPaid": 0.06,
"currency": "USDC"
}
}
Get Session Status
Check the status of an active session.
GET /browser/session/:id/status
Response:
{
"sessionId": "abc-123",
"status": "active",
"usage": {
"minutesPaid": 30,
"minutesUsed": 5,
"minutesRemaining": 25
},
"expiresAt": "2025-12-03T18:00:00Z"
}
Extend Session
Add more time to an active session.
POST /browser/session/:id/extend
Request Body:
{
"additionalMinutes": 15
}
Extending a session requires another x402 payment for the additional time.
Terminate Session
End a session early. Unused time may be eligible for refund.
POST /browser/session/:id/terminate
Response:
{
"sessionId": "abc-123",
"finalStatus": "terminated",
"usage": {
"minutesPaid": 30,
"minutesUsed": 10
},
"refund": {
"eligible": true,
"amount": 0.33,
"currency": "USDC"
}
}
Making x402 Payments
Use the x402 package for full control over the payment flow:import { privateKeyToAccount } from "viem/accounts";
import { getAddress } from "viem";
import { exact } from "x402/schemes";
const account = privateKeyToAccount("0x...");
// 1. Get payment requirements
const res = await fetch("https://x402.browserbase.com/browser/session/create", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ estimatedMinutes: 30 }),
});
const { accepts } = await res.json();
const req = accepts[0];
// 2. Create payment header
const paymentHeader = await exact.evm.createPaymentHeader(account, 1, {
scheme: req.scheme,
network: req.network,
maxAmountRequired: req.maxAmountRequired,
resource: req.resource,
description: req.description,
mimeType: req.mimeType,
payTo: getAddress(req.payTo),
maxTimeoutSeconds: req.maxTimeoutSeconds,
asset: getAddress(req.asset),
extra: req.extra,
});
// 3. Send with payment
const session = await fetch("https://x402.browserbase.com/browser/session/create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-PAYMENT": paymentHeader,
},
body: JSON.stringify({ estimatedMinutes: 30 }),
}).then(r => r.json());
console.log(session.connectUrl); // wss://connect.browserbase.com/...
Use x402-fetch for automatic payment handling:import { wrapFetch } from "x402-fetch";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("0x...");
const x402Fetch = wrapFetch(fetch, account);
// Payments are handled automatically
const session = await x402Fetch("https://x402.browserbase.com/browser/session/create", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ estimatedMinutes: 30 }),
}).then(r => r.json());
console.log(session.connectUrl); // wss://connect.browserbase.com/...
The x402-fetch wrapper automatically handles the 402 response, signs the payment, and retries the request with the payment header.
Using Your Session
Once you have a connectUrl, connect with Playwright or Puppeteer:
import { chromium } from "playwright";
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = browser.contexts()[0].pages()[0];
await page.goto("https://example.com");
await page.screenshot({ path: "screenshot.png" });
await browser.close();
Further Reading