Guides
TypeScript SDK
The @browlix/sdk package — typed calls for every operation, safe retries, session helpers and webhook verification.
@browlix/sdk has no runtime dependencies and works in Node 20 or later, Bun, Deno, Cloudflare Workers and browsers that may hold a key.
Install
The package is published by Browlix, with its SHA-256 on the download page:
npm i https://browlix.com/api/public/sdk/v1/download/latestCreate a client
import { Browlix, BrowlixError } from "@browlix/sdk";
const bx = new Browlix({ apiKey: process.env.BROWLIX_API_KEY! }); // the SDK never reads env itselfOptions: baseUrl (default https://browlix.com), attempts for safe retries (default 3), timeoutMs per request (default 60 s), and a custom fetch.
Call any operation
const { data, page } = await bx.call("profiles.list", { query: { limit: 20, os: "windows" } });
for await (const profile of bx.paginate("profiles.list", { state: "active" })) {
console.log(profile);
}call(id, { path, query, body }) is typed from the OpenAPI document for each operation id: the input always, and from SDK 0.9.0 also data for every operation whose reply fields are published in the reference (profiles, sessions, bindings, devices, feedback, workspace). OPERATIONS lists them. New reply fields can appear without notice — see Versions and changelog.
Writes
Writes get a command_id when you omit one and report it as reply.commandId. Automatic retries resend the same id, so nothing is applied twice. After OUTCOME_UNKNOWN, read the result with bx.receipt(commandId).
Sessions
const s = await bx.startSession({ profileId, deviceId, wait: { timeoutMs: 120_000 } });
const a = await bx.attach(s.data.id);
// … connect Playwright on this machine with a.endpoint and a.headers …
await bx.stopSession(s.data.id);waitForSession and startSession({ wait }) only wait. Aborting with signal (INTERRUPTED) or timing out (WAIT_TIMEOUT) leaves the session running. stopSession is the only call that ends one.
Errors
Every failure is a BrowlixError with the API's code, retryable, and info (status, details, correlationId, commandId, retryAfterSeconds). Key-shaped text is redacted from messages.
try {
await bx.call("sessions.start", { body: { profile_id: profileId, device_id: deviceId } });
} catch (e) {
if (e instanceof BrowlixError && e.code === "BUSY") console.log("BUSY", e.info.details);
else throw e;
}Webhooks
verifyWebhook(secret, headers, rawBody) checks a Standard Webhooks signature and timestamp (5-minute tolerance) and returns the parsed event — see Webhooks.
