Automation API

A local HTTP API for driving profiles from your own scripts: start a profile with its full fingerprint and proxy applied, and get back a real Chrome DevTools Protocol endpoint to attach Puppeteer, Playwright, or anything else that speaks CDP.

Base URL & auth

The API is bound to 127.0.0.1 only: nothing outside your machine can reach it. Find the port and your token in the app's ⚙ Settings panel, which also has a ready-to-copy connection snippet.

Base URLhttp://127.0.0.1:<port>
Auth headerAuthorization: Bearer <token> or X-API-Token: <token>

Endpoints

GET/profiles

List every profile with its id, name, status, and whether it's currently running.

POST/profiles/:id/start

Launches the profile with its full fingerprint and proxy applied, and returns its CDP webSocketDebuggerUrl. Add ?headless=true to launch without a visible window.

Headless changes what the page does, not just what you see. Sites serve less to a browser with no window: deferred content may never load, and smooth scrolling does not run at all. Use it for fetching data; leave it off when the run is meant to look like ordinary use. What we measured.
Returns 402 if the profile is frozen (over your account's current plan limit), upgrade or free up a slot to launch it.

POST/profiles/:id/stop

Stops the launched browser for that profile.

GET/profiles/:id/status

Returns whether the profile is currently running and its CDP endpoint if so.

Creating profiles, proxies and groups

The endpoints above drive profiles that already exist. These make them, so a script, or an AI assistant through the MCP server, can set a workspace up rather than only work in one that is already set up.

Everything here goes through the same code as the buttons in the app. Your plan limit, the name rules, the operating-system and browser-version checks and the proxy format checks all apply exactly as they would if you clicked Create.

POST/profiles

Creates one profile, or a numbered batch with count (maximum 200). Each gets its own coherent fingerprint and its own storage: a batch is that many different machines, not one identity repeated. Body: name (required), count, os (Windows or macOS), proxyId, group, tags, startUrls, notes.

The plan limit answers differently for one profile and for a batch. A single profile over the limit is a 402. A batch is a 200: the profiles it already made are kept and stoppedAtLimit says where it stopped, because losing forty successful creations when the forty-first hits the cap would be the worse outcome. Check that field: a 200 here does not mean you got everything you asked for.
A proxyId that does not exist is refused with a 400 naming the id, rather than stored as given. “Make twenty profiles on this proxy” with a stale or mistyped id used to produce twenty profiles that all looked correct and none of which could open, and you found out one at a time, at launch. The app’s own UI cannot reach that state because it picks from a list; an id arriving here is free text. Omit proxyId for a direct connection.

PATCH/profiles/:id

Rename a profile, move it to a group, re-tag it, change its start URLs, or bind and unbind a proxy (proxyId: null makes it direct; an id that does not exist is refused the same way it is on create). Two fields are deliberately not accepted: the fingerprint seed, because changing it would quietly make the profile a different computer while keeping its name and its cookies, and the running status, which only actually launching a browser should set.

GET/proxies

Every proxy, with the country and timezone it resolved to once tested. Credentials are never returned.

POST/proxies

Add proxies. Send list with a pasted provider list: one per line, in any of the formats the import dialog accepts (host:port, host:port:user:pass, user:pass@host:port, scheme://…), and the reply reports every line it could not read, so a list of fifty that yields forty-seven proxies tells you which three to fix. Or send one proxy as host, port, type, username, password.

GET/groups

The groups, with how many profiles are in each.

POST/groups

Creates a group. Put profiles in it with PATCH /profiles/:id or when creating them.

There is no delete endpoint, on purpose. This API is a standing credential sitting on your machine. One that can open a browser is a different proposition from one that can erase every profile and the logged-in sessions inside it. Deleting stays in the app, where it goes through the thirty-day trash.

Example: connect with Puppeteer

const res = await fetch('http://127.0.0.1:PORT/profiles/PROFILE_ID/start', {
  method: 'POST',
  headers: { Authorization: 'Bearer YOUR_TOKEN' }
})
const { webSocketDebuggerUrl } = await res.json()

const browser = await puppeteer.connect({ browserWSEndpoint: webSocketDebuggerUrl })
const [page] = await browser.pages()
await page.goto('https://example.com')

The same webSocketDebuggerUrl works with Playwright's chromium.connectOverCDP() or any Selenium CDP-based driver.