Solari

Sessions

A session is a real browser you drive with the standard Playwright API. Open it, drive it, close it.

Lifecycle

launch() opens a browser and connects you to it in one call. close() shuts it down and cleans up, so it's safe to call from a finally block.

import { Solari } from "@solarisdk/browser"

const client = new Solari({ apiKey: process.env.SOLARI_API_KEY!, baseUrl: "https://api.getsolari.com" })

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

Already using Puppeteer, browser-use, or another tool that speaks Chrome DevTools Protocol? Call sessions.create() and connect your own client to the session.

import { chromium } from "playwright-core"

const session = await client.sessions.create({ stealth: true })

// Connect with the client you already use. 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)

Any recent CDP-compatible client works with cdpEndpoint. The default launch() path is a bit faster per action, and the SDK ships its own matching client so you don't have to think about versions.

You can also connect with wsEndpoint, which is a bit faster per action.

import { chromium } from "patchright-core"

const session = await client.sessions.create()
const browser = await chromium.connect(session.wsEndpoint)
Pin patchright-core to 1.59.3
This path needs a matching client. Pin 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

Makes the browser look and behave like a real person's. Turn this on to use proxy and captcha. See Stealth.

profileId

Starts the session already logged in, using cookies and site data from a saved profile. See Profiles.

recording

Records the session so you can replay it later. See Session recording.

proxy

Routes traffic through a proxy. proxy: "us" uses a rotating residential IP; the object form lets you pick static ISP, mobile carrier, sticky sessions, and more. See Proxies.

captcha

Solves reCaptcha v2/v3, hCaptcha, Turnstile, and others for you. 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()

Closing

browser.close() shuts down the browser and cleans up in one step. That's what most people want. If you used sessions.create() directly, release(id) closes the session without waiting, and releaseAndWait(id) waits until it's fully done. Use releaseAndWait before you read getReplayUrl().