Documentation Index
Fetch the complete documentation index at: https://docs.nusomi.com/llms.txt
Use this file to discover all available pages before exploring further.
The SDK capture path is for runs without a human at the keyboard — Playwright suites, scripted automations, agent runs in CI, Browserbase / Anchor sessions. It produces sessions with the same shape as desktop or browser capture, so they’re indistinguishable downstream.
Install
# TypeScript
npm install @nusomi/sdk
# Python
pip install nusomi
Wrapping a Playwright page
import { chromium } from "playwright";
import { Nusomi } from "@nusomi/sdk";
const nusomi = new Nusomi({ apiKey: process.env.NUSOMI_API_KEY });
const session = await nusomi.sessions.create({
workflow: "scraper_login",
});
const browser = await chromium.launch();
const context = await browser.newContext();
// Attach Nusomi to the Playwright context
await session.attachPlaywright(context);
await session.start();
const page = await context.newPage();
await page.goto("https://app.example.com/login");
await page.fill("[name=email]", "ops@acme.com");
await page.fill("[name=password]", process.env.PASSWORD!);
await page.click("button[type=submit]");
await session.stop();
await browser.close();
attachPlaywright instruments the context to emit Nusomi events automatically — no need to call session.event(...) for every action. You still get a real frame stream because the SDK takes screenshots at the configured rate.
Wrapping Puppeteer
import puppeteer from "puppeteer";
import { Nusomi } from "@nusomi/sdk";
const browser = await puppeteer.launch();
const page = await browser.newPage();
const session = await nusomi.sessions.create({ workflow: "..." });
await session.attachPuppeteer(page);
await session.start();
// ...
await session.stop();
Browserbase / Anchor / Steel
These platforms run remote browsers but expose a CDP endpoint. Connect Nusomi via CDP:
const session = await nusomi.sessions.create({ workflow: "..." });
await session.attachCdp({ wsEndpoint: browserbaseSession.connectUrl });
await session.start();
// ...
await session.stop();
Manual events
You don’t have to attach to a browser at all. Push events directly:
const session = await nusomi.sessions.create({ workflow: "queue_processor" });
await session.start();
await session.event("click", {
target: { role: "button", name: "Approve" },
x: 612,
y: 388,
});
await session.event("submit", {
form: "approval_form",
payload: { approved: true },
});
await session.stop();
Frame uploads
If your run produces its own frames (server-rendered preview, headless pixel capture), upload them directly:
await session.frame({
t_ms: 12_480,
image: fs.readFileSync("frame_1.webp"),
viewport: { w: 1440, h: 900 },
});
Buffering & retries
The SDK buffers frames and events locally and retries on transient network failures. By default:
- Frame upload: 5 retries with exponential backoff, 60s total budget.
- Event upload: 5 retries, 30s budget.
- Buffer size: 200 MB on disk before back-pressuring.
Override:
new Nusomi({
apiKey: ...,
buffer: { maxBytes: 1_000_000_000, dir: "/var/cache/nusomi" },
retries: { events: 10, frames: 10 },
});
Sealing in CI
Always wrap a session in try / finally so a thrown test error doesn’t leave it recording forever:
const session = await nusomi.sessions.create({ workflow: "smoke_test" });
try {
await session.start();
await runSuite();
} finally {
await session.stop();
}
Self-hosted endpoint
new Nusomi({
apiKey: process.env.NUSOMI_API_KEY,
baseUrl: "https://nusomi.internal.acme.com",
});