Node.js SDK
@browser-forest/sdk is the official Browser Forest Node.js SDK, providing a type-safe API wrapper with a Stripe-style resource-oriented design.
Installation
npm install @browser-forest/sdk
# or
pnpm add @browser-forest/sdkNote: The SDK uses Node.js 20+ built-in fetch — no additional dependencies like node-fetch are needed.
Initialization
import { BrowserForestClient } from '@browser-forest/sdk';
const client = new BrowserForestClient({
apiKey: 'bf_live_xxxxxxxxxxxxxxxxxxxx',
// baseUrl: 'https://bf.mktindex.com/api/v1', // optional, default
// timeout: 30000, // optional, ms, default 30s
});Sessions
// Create Session
const session = await client.sessions.create({
contextId: 'ctx_xxx', // optional
proxyId: 'prx_xxx', // optional
url: 'https://google.com', // optional
});
console.log(session.cdpUrl); // wss://bf.mktindex.com/ws/session/ses_xxx
// List Sessions
const sessions = await client.sessions.list();
// Get Session
const s = await client.sessions.get('ses_xxx');
// Stop Session
await client.sessions.stop('ses_xxx');Contexts
// Create Context
const ctx = await client.contexts.create({ name: 'my-account' });
// List Contexts
const contexts = await client.contexts.list();
// Get Context
const c = await client.contexts.get('ctx_xxx');
// Delete Context
await client.contexts.delete('ctx_xxx');Proxies
// Create proxy
const proxy = await client.proxies.create({
name: 'US Proxy',
type: 'http',
host: 'proxy.example.com',
port: 8080,
username: 'user', // optional
password: 'pass', // optional
country: 'US', // optional
});
// Test proxy
const result = await client.proxies.test('prx_xxx');
console.log(result.healthy, result.latencyMs);
// Delete proxy
await client.proxies.delete('prx_xxx');Scrape
const result = await client.scrape.scrape({
url: 'https://example.com',
contextId: 'ctx_xxx', // optional
proxyId: 'prx_xxx', // optional
waitFor: 2000, // optional, ms
javascript: 'return document.title', // optional
});
console.log(result.html); // full HTML
console.log(result.title); // page title
console.log(result.jsResult); // JS execution resultAuthentication
// Login
const { token } = await client.auth.login({
email: '[email protected]',
password: 'yourpassword',
});
// Create API Key (requires JWT token)
const apiKey = await client.auth.createApiKey({ name: 'my-key' });
// List API Keys
const keys = await client.auth.listApiKeys();
// Revoke API Key
await client.auth.revokeApiKey('key_id');Usage
const stats = await client.usage.get();
console.log(stats);
// {
// totalSessions: 42,
// totalDurationSeconds: 3600,
// avgDurationSeconds: 85.7
// }Error Handling
The SDK provides specific error classes for each HTTP error, all extending BrowserForestError:
import {
BrowserForestError,
AuthenticationError,
NotFoundError,
BadRequestError,
ConflictError,
RateLimitError,
} from '@browser-forest/sdk';
try {
const session = await client.sessions.get('ses_nonexistent');
} catch (err) {
if (err instanceof NotFoundError) {
console.log('Session not found');
} else if (err instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (err instanceof BrowserForestError) {
console.log('API error:', err.message, err.status);
}
}Error Types
| Error Class | HTTP Status | Description |
|---|---|---|
| AuthenticationError | 401 | API Key is invalid or missing |
| NotFoundError | 404 | Resource not found |
| BadRequestError | 400 | Invalid request parameters |
| ConflictError | 409 | Resource conflict (e.g., email already registered) |
| RateLimitError | 429 | Too many requests |
| LaunchFailedError | 503 | Browser launch failed |
| WorkerUnavailableError | 503 | Worker unavailable |
| ApiError | Other | Generic API error |
Complete Example
import { BrowserForestClient } from '@browser-forest/sdk';
import puppeteer from 'puppeteer-core';
const client = new BrowserForestClient({
apiKey: process.env.BROWSER_FOREST_API_KEY!,
});
async function main() {
// Create Context (for persistent state)
const ctx = await client.contexts.create({ name: 'my-scrape-session' });
// Create Session
const session = await client.sessions.create({ contextId: ctx.id });
console.log('Session started:', session.id);
// Connect to browser
const browser = await puppeteer.connect({
browserWSEndpoint: session.cdpUrl,
});
const page = await browser.newPage();
await page.goto('https://example.com');
const title = await page.title();
console.log('Page title:', title);
await browser.disconnect();
// Stop Session (auto-save state to Context)
await client.sessions.stop(session.id);
console.log('Session stopped, state saved to context');
}
main().catch(console.error);