Skip to main content
DemoZalo 0862020654

Local API

The desktop app serves an HTTP API on your machine so your own scripts can list profiles, launch them with a CDP endpoint, and run workflows.

26 endpoints

Base URL

The server binds to the loopback interface only, so it is reachable from the machine running the app and nowhere else. The port comes from LOCAL_API_PORT and defaults to 3030.

http://127.0.0.1:3030

Authentication

Every endpoint except /health and /status needs an API token in the X-Token header. Tokens are created in your account, not in the app.

Example request

curl http://127.0.0.1:3030/profiles \
  -H "X-Token: <your api token>"

Tokens are validated against the cloud and cached. If the cloud is unreachable the app falls back to the cached validation for up to a day, so automation keeps working through a short outage.

Permissions

Each token carries a permission set per category — profiles, workspaces, instant_profiles and rpa — and every endpoint below states the check it performs.

A broad grant covers the narrower checks it contains: delete also satisfies write and read. The operational actions are separate — start does not imply stop, and neither is implied by read — so grant each one you actually need.

Endpoint requiresSatisfied by any of
readreadwritedelete
writewritedelete
deletedelete
startstart
stopstop
executeexecute
logslogs
createcreate
connectconnectcontrol
controlcontrol

Rate limits

Limits are counted per token over a rolling minute, and each route group gets its own tier.

  • default100 requests/minute
  • profile60 requests/minute
  • rpa60 requests/minute
  • strict10 requests/minute

Every response carries the current budget

X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset

Errors

Failures answer with success: false, a human-readable error and a machine-readable code.

{ "success": false, "error": "Missing X-Token header", "code": "UNAUTHORIZED" }
{ "success": false, "error": "Permission denied: profiles.start", "code": "FORBIDDEN" }
{ "success": false, "error": "Too many requests", "code": "RATE_LIMIT_EXCEEDED", "retryAfter": 42 }

Health and status

Cheap checks for whether the app is up and whether it can still reach the cloud.

GET/health

Is the local API up

Reachable without a token — it is mounted before the auth middleware.

Permission: noneRate limit: 100 requests/minute

200 OK

{ "status": "ok", "timestamp": 1787553311344 }
GET/status

Cloud connection and last sync

Reachable without a token — it is mounted before the auth middleware.

Permission: noneRate limit: 100 requests/minute

200 OK — lastSync is the newest of profiles, workflows and workspaces

{ "online": true, "lastSync": 1787553311344, "timestamp": 1787553311999 }
GET/list

Profiles currently running

Permission: noneRate limit: 100 requests/minute

200 OK

{
  "success": true,
  "data": [{ "profile_id": "abc", "port": 19001, "status": "RUNNING" }]
}
GET/stats

Cache, sync queue and running counts

Permission: noneRate limit: 100 requests/minute

Profiles

Start and stop the profiles synced from your account. Starting one hands back a CDP endpoint you can drive with Puppeteer or Playwright.

GET/profiles

List cached profiles

Reads the local cache. If the cache is empty it syncs from the cloud first, so the first call after a fresh start is slower.

Permission: profiles.readRate limit: 60 requests/minute

NameInTypeDescription
workspace_idquerystringOnly return profiles in this workspace.
GET/profiles/sync

Force a sync from the cloud

Permission: profiles.readRate limit: 60 requests/minute

GET/profiles/:profileId

One profile from the cache

Permission: profiles.readRate limit: 60 requests/minute

NameInTypeDescription
profileIdrequiredpathstringProfile id.
POST/profiles/:profileId/start

Launch the profile browser

Returns the CDP url to attach an automation library to. Without a port the app picks a free one in 19000-19999. The profile must already be in the cache — sync first or you get 404.

Permission: profiles.startRate limit: 60 requests/minute

NameInTypeDescription
profileIdrequiredpathstringProfile id.
portquerynumberDebugging port to use, 1-65535.

200 OK

{
  "success": true,
  "data": {
    "profile_id": "abc",
    "port": 19001,
    "cdp_url": "http://127.0.0.1:19001"
  }
}
POST/profiles/:profileId/stop

Close the profile browser

Permission: profiles.stopRate limit: 60 requests/minute

NameInTypeDescription
profileIdrequiredpathstringProfile id.
GET/profiles/:profileId/status

RUNNING or STOPPED

Permission: profiles.readRate limit: 60 requests/minute

NameInTypeDescription
profileIdrequiredpathstringProfile id.

Instant profiles

Throwaway profiles created on the spot, without saving anything to your account. Rate limited hardest of all the groups.

POST/instant

Create and launch a throwaway profile

Permission: instant_profiles.createRate limit: 10 requests/minute

NameInTypeDescription
fingerprintbodyobjectFingerprint hints such as os and version.
proxy_idbodystringProxy from your account to route the profile through.

200 OK

{
  "success": true,
  "data": { "profile_id": "instant_…", "port": 19002, "cdp_url": "http://127.0.0.1:19002" }
}
DELETE/instant/:profileId

Close and discard an instant profile

Permission: instant_profiles.deleteRate limit: 10 requests/minute

NameInTypeDescription
profileIdrequiredpathstringProfile id.
GET/instant/:profileId

One instant profile

Permission: noneRate limit: 10 requests/minute

NameInTypeDescription
profileIdrequiredpathstringProfile id.
GET/instant

All live instant profiles

Permission: noneRate limit: 10 requests/minute

RPA

Run the workflows you built on the canvas, on a saved profile or on a fresh instant one, and follow the task while it runs.

GET/rpa/workflows

List workflows

Permission: rpa.readRate limit: 60 requests/minute

GET/rpa/workflows/:workflowId

One workflow, including its graph

Permission: rpa.readRate limit: 60 requests/minute

NameInTypeDescription
workflowIdrequiredpathstringWorkflow id.
POST/rpa/workflows/sync

Force a workflow sync

Permission: rpa.readRate limit: 60 requests/minute

POST/rpa/tasks

Run a workflow on a profile

Permission: rpa.executeRate limit: 60 requests/minute

NameInTypeDescription
workflow_idrequiredbodystringWorkflow to run.
profile_idrequiredbodystringProfile to run it on.

400 when either field is missing

{
  "success": false,
  "error": "workflow_id and profile_id are required in request body"
}
POST/rpa/tasks/instant

Run a workflow on a fresh instant profile

Creates the profile, runs the workflow on it, and needs no profile_id.

Permission: rpa.executeRate limit: 60 requests/minute

NameInTypeDescription
workflow_idrequiredbodystringWorkflow to run.
profile_configbodyobjectSame shape as the instant profile body.
GET/rpa/tasks

List tasks

Permission: rpa.readRate limit: 60 requests/minute

GET/rpa/tasks/:taskId

One task and its state

Permission: rpa.readRate limit: 60 requests/minute

NameInTypeDescription
taskIdrequiredpathstringTask id.
POST/rpa/tasks/:taskId/stop

Stop a running task

Permission: rpa.stopRate limit: 60 requests/minute

NameInTypeDescription
taskIdrequiredpathstringTask id.
GET/rpa/tasks/:taskId/logs

Logs for a task

Permission: rpa.logsRate limit: 60 requests/minute

NameInTypeDescription
taskIdrequiredpathstringTask id.

Workspaces

Read-only view of the workspaces profiles are grouped into.

GET/workspaces

List workspaces

Permission: workspaces.readRate limit: 60 requests/minute

GET/workspaces/sync

Force a workspace sync

Permission: workspaces.readRate limit: 60 requests/minute

GET/workspaces/:workspaceId

One workspace

Permission: workspaces.readRate limit: 60 requests/minute

NameInTypeDescription
workspaceIdrequiredpathstringWorkspace id.