Quick Start
Browser Forest is a cloud browser API platform that provides anti-detection browser services for developers and AI agents. Create and control browser sessions through a simple REST API, with support for persistent Contexts, proxy configuration, and web scraping.
Get Started
Pick one path to connect Browser Forest to your tools. Both use the same API key and bill against your plan quota.
First run with REST
Prerequisites: sign in, then create an API key on Settings → API Keys. Set these environment variables before running the script:
# API base URL including /api/v1 (use your deployment host)
export BROWSER_FOREST_BASE_URL="https://browserforest.com/api/v1"
export BROWSER_FOREST_API_KEY="YOUR_API_KEY"Copyable Python example — always DELETE the session in finally so the browser is released:
import os
import requests
BASE = os.environ["BROWSER_FOREST_BASE_URL"]
API_KEY = os.environ.get("BROWSER_FOREST_API_KEY", "YOUR_API_KEY")
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
session = None
try:
resp = requests.post(f"{BASE}/sessions", headers=HEADERS, json={}, timeout=60)
resp.raise_for_status()
session = resp.json()
print(session["id"])
print(session["cdpUrl"])
finally:
if session and session.get("id"):
requests.delete(
f"{BASE}/sessions/{session['id']}",
headers=HEADERS,
timeout=30,
)YOUR_API_KEY with a real key. Confirm BROWSER_FOREST_BASE_URL matches your environment (production vs bftest) before you run this.1. Login & Get API Key
Log in via browser (enterprise email, GitHub, or Google OAuth), then create an API Key on the Settings page:
# Log in and create an API Key on the Settings page
# Format: bf_live_xxxxxxxxxxxxxxxx2. Launch a Browser Session
curl -X POST https://browserforest.com/api/v1/sessions \
-H "X-API-Key: bf_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{}'
# Returns:
{
"id": "ses_xxxx",
"cdpUrl": "wss://browserforest.com/ws/session/ses_xxxx",
"status": "active"
}import requests
resp = requests.post(
"https://browserforest.com/api/v1/sessions",
headers={"X-API-Key": "bf_live_xxxxxxxxxxxx"},
json={},
)
session = resp.json()
print(session["id"]) # ses_xxxx
print(session["cdpUrl"]) # wss://browserforest.com/ws/session/ses_xxxx3. Control the Browser via CDP
Use cdpUrl to connect via Chrome DevTools Protocol. Works with Puppeteer, Playwright, or any CDP client:
import puppeteer from 'puppeteer-core';
const API_KEY = 'bf_live_xxxxxxxxxxxx';
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://browserforest.com/ws/session/ses_xxxx?key=' + API_KEY,
});
const page = await browser.newPage();
await page.goto('https://example.com');
const title = await page.title();
console.log(title); // "Example Domain"
await browser.disconnect();import asyncio
from playwright.async_api import async_playwright
API_KEY = "bf_live_xxxxxxxxxxxx"
async def main():
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(
"wss://browserforest.com/ws/session/ses_xxxx?key=" + API_KEY
)
page = await browser.new_page()
await page.goto("https://example.com")
print(await page.title()) # "Example Domain"
await browser.close()
asyncio.run(main())4. Stop the Session
curl -X DELETE https://browserforest.com/api/v1/sessions/ses_xxxx \
-H "X-API-Key: bf_live_xxxxxxxxxxxx"import requests
requests.delete(
"https://browserforest.com/api/v1/sessions/ses_xxxx",
headers={"X-API-Key": "bf_live_xxxxxxxxxxxx"},
)Using the REST API from Node.js
The official Node.js SDK is implemented but not published to npm yet. Until it ships, Node 20+ built-in fetch is all you need:
const res = await fetch('https://browserforest.com/api/v1/sessions', {
method: 'POST',
headers: {
'X-API-Key': 'bf_live_xxxxxxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({}),
});
const session = await res.json();
console.log(session.cdpUrl); // wss://browserforest.com/ws/session/ses_xxxx# Python — requests + Playwright(Python SDK 同样已实现但未发布):
import requests
from playwright.sync_api import sync_playwright
API_KEY = "bf_live_xxxx"
resp = requests.post(
"https://browserforest.com/api/v1/sessions",
headers={"X-API-Key": API_KEY},
json={},
)
session = resp.json()
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(session["cdpUrl"] + "?key=" + API_KEY)
page = browser.new_page()
# ... operate the browser ...
browser.close()
requests.delete(
f"https://browserforest.com/api/v1/sessions/{session['id']}",
headers={"X-API-Key": API_KEY},
)5. Cookie API (Session State Migration)
No need to hand-write CDP — directly export/inject cookies from active Sessions, or write them to a Context for automatic restoration on the next Session. See Sessions and Contexts docs for details; see Web Scraping use case for approach C.
# Inject cookies into an active Session
curl -X PUT https://browserforest.com/api/v1/sessions/ses_xxxx/cookies \
-H "X-API-Key: bf_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"cookies": [{"name":"token","value":"...","domain":".example.com","path":"/"}]}'
# Write to Context (auto-injected on next session create)
curl -X PUT https://browserforest.com/api/v1/contexts/ctx_xxxx/cookies \
-H "X-API-Key: bf_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"cookies": [ ... ]}'import requests
# Inject cookies into an active Session
requests.put(
"https://browserforest.com/api/v1/sessions/ses_xxxx/cookies",
headers={"X-API-Key": "bf_live_xxxxxxxx"},
json={"cookies": [{"name": "token", "value": "...", "domain": ".example.com", "path": "/"}]},
)
# Write to Context (auto-injected on next session create)
requests.put(
"https://browserforest.com/api/v1/contexts/ctx_xxxx/cookies",
headers={"X-API-Key": "bf_live_xxxxxxxx"},
json={"cookies": [...]},
)https://browserforest.com/api/v1. See the Sessions and Contexts docs for full API coverage.