Sessions
A session is a Chromium instance you drive with the standard Playwright API. Create, drive, release.
Lifecycle
launch() opens a session and connects the browser in one call. close() closes the browser and releases the session — safe to call from finally.
import { Solari } from "@solaribrowser/sdk"
const client = new Solari({ apiKey: process.env.SOLARI_API_KEY! })
const browser = await client.launch()
try {
const page = await browser.newPage()
await page.goto("https://example.com")
await page.locator("h1").waitFor()
console.log(await page.locator("h1").innerText())
} finally {
await browser.close()
}Bring your own client
If you're wiring Solari into Puppeteer, browser-use, or anything else that speaks raw Chrome DevTools Protocol, drop down to sessions.create() and connect to the session's CDP endpoint yourself.
const session = await client.sessions.create({ stealth: true })
// Any CDP client. Examples: playwright-core's connectOverCDP,
// puppeteer-core's connect, browser-use's BrowserSession.
const browser = await chromium.connectOverCDP(session.cdpEndpoint)
// ...drive the browser...
await browser.close()
await client.sessions.releaseAndWait(session.id)The CDP endpoint has no version pinning to the pool — any recent CDP-compatible client works against it. The default launch() path uses Playwright's wire protocol under the hood for slightly lower per-action latency, with the SDK shipping its own version-matched client so you don't manage it.
Or connect via the wire protocol with wsEndpoint for slightly lower per-action latency.
const session = await client.sessions.create()
const browser = await chromium.connect(session.wsEndpoint)patchright-core@1.59.3 in your project.Options
Every option is opt-in. The default is a fast headless browser with no profile, recording, proxy, or stealth.
stealth
Enables full Chromium with a fingerprint shim. Required for proxy and captcha. See Stealth.
profileId
Hydrates cookies and localStorage from a saved profile before the first navigation. See Profiles.
recording
Captures every DOM mutation with rrweb and stores the replay in S3. See Session recording.
proxy
Managed proxy egress. proxy: "us" picks rotating residential; the object form lets you choose static ISP, mobile carrier, sticky sessions, or ASN. See Proxies.
captcha
Auto-solves reCaptcha v2/v3, hCaptcha, Turnstile, and others. See Captcha solving.
Full example
const browser = await client.launch({
stealth: true,
recording: true,
captcha: true,
profileId: "prof_abc123",
proxy: { country: "us", session: "warmup-1", sessionDuration: 10 },
})
const page = await browser.newPage()
await page.goto("https://example.com")
await page.locator("button[type=submit]").click()
await browser.close()Releasing
browser.close() closes the underlying browser and releases the session in one step — that's the path most callers want. If you used sessions.create() directly, release(id) is fire-and-forget and releaseAndWait(id) blocks until the release is confirmed (use it before reading getReplayUrl()).