Local API reference
Every route the local API serves, with its method, its parameters and what comes back.
On this page
- π The basics
- π©Ί Status
- GET /api/v1/status
- π§© Profiles
- GET /api/v1/profiles
- POST /api/v1/profiles/create
- π Proxies
- GET /api/v1/proxies
- π₯οΈ Browser sessions
- POST /api/v1/browser/start
- POST /api/v1/browser/stop
- GET /api/v1/browser/list
- GET /api/v1/browser/active
- β‘ Flows
- GET /api/v1/flows
- GET /api/v1/flows/get
- GET /api/v1/flows/templates
- POST /api/v1/flows/use-template
- POST /api/v1/flows/run
- GET /api/v1/flows/run
- GET /api/v1/flows/runs
- POST /api/v1/flows/stop
- POST /api/v1/flows/run-many
- GET /api/v1/flows/batch
- POST /api/v1/flows/batch/stop
- GET /api/v1/flows/history
- π¨ Status codes and errors
- βΉοΈ Good to know
The complete list of what LoginDeck's local API serves. To switch it on and get your token, see Get started with the local API.
Part of Pro, Team and Custom.
π The basics#
| Base URL | http://127.0.0.1:19222 (your port is in Settings β API & MCP) |
| Auth | Authorization: Bearer <token> on every request |
| Reads | GET, parameters in the query string |
| Writes | POST with Content-Type: application/json and a JSON body |
| Success | 200 and {"ok": true, "data": { β¦ }} |
| Failure | {"ok": false, "error": "β¦"} with a matching status |
| Refused | Any request with an Origin header, or a Host that is not loopback and your port |
| Body limit | 64 KB |
Trailing slashes are ignored. GET /status is an alias for GET /api/v1/status.
Picking a profile. Routes that act on a profile take profile_id (or id) or name, in the body for a POST or the query string for a GET. A name shared by two profiles is refused β 2 profiles are named "Shop" β use profile_id β rather than guessed at.
Picking a Flow. Routes that act on a Flow take flow_id, or flow (or flow_name). Ambiguous names are refused the same way.
π©Ί Status#
GET /api/v1/status#
Is the app there, and in what state.
{"app":"antiorbit","api":1,"version":"0.1.209",
"engine":{"path":"β¦","patched":true},"profiles":42,"running":1}
π§© Profiles#
GET /api/v1/profiles#
Every profile. Optional ?tag=<tag> filters to one tag.
Returns {"profiles": [...], "count": n}. Each row: id, name, tags, os, notes, proxy_kind (device Β· saved Β· custom Β· none), last_launch_at, running, automation.
POST /api/v1/profiles/create#
Create one or more profiles, each with a freshly generated fingerprint.
| Field | Notes |
|---|---|
name | With count > 1 it becomes the base: Name 1, Name 2, β¦ |
os | OS preset, for example win11, win10, macintel, macarm, linux. Defaults to win11 |
tags | Array of strings |
notes | Free text |
proxy_id | A saved proxy, from GET /api/v1/proxies |
device_id | One of your phone devices |
proxy | A raw proxy string: scheme://user:pass@host:port or host:port:user:pass |
count | 1β100. Default 1 |
Returns {"created": [...], "count": n}. Your plan's profile limit is enforced here exactly as it is on the + New Profile button, so a script cannot mint past your tier.
π Proxies#
GET /api/v1/proxies#
The saved proxy library, without passwords: id, name, label, protocol, host, port, has_auth, rotate.
π₯οΈ Browser sessions#
POST /api/v1/browser/start#
Open a profile as a real LoginDeck session and get a DevTools endpoint.
| Field | Notes |
|---|---|
profile_id / name | Which profile |
url | Optional page to open on start |
headless | Default false. More detectable β avoid for anything logged in |
Returns the session: profile_id, name, pid, started_at, debug_port, ws, http, headless, proxy (masked), timezone, exit (ip, country, city, isp), engine (path, patched, version), and warnings when there is something to say β headless, or a session on stock Chrome where the masking is inert.
A profile that is already open with an automation port comes back as that same session (and url, if you sent one, opens in it). A profile you opened by hand from the app is refused: this profile is already running without an automation port β stop it first, then start it through the API.
POST /api/v1/browser/stop#
Stop a session. Takes profile_id / name, returns {"profile_id": "β¦", "name": "β¦", "stopped": true}.
GET /api/v1/browser/list#
Every running session, in the same shape as browser/start returns: {"sessions": [...], "count": n}.
GET /api/v1/browser/active#
One profile's session. Takes ?profile_id= or ?name=. Returns {"running": false, "profile_id": "β¦", "name": "β¦"}, or running: true plus the whole session.
β‘ Flows#
GET /api/v1/flows#
Your Flow library: {"flows": [...], "count": n}. Each: id, name, steps, inputs, template, updated_at.
Each entry in inputs is {key, label, kind, required, default, hint, options?} β what the Flow asks for at run time.
GET /api/v1/flows/get#
One Flow in full. Takes ?flow_id= or ?flow=. Adds notes and nodes (each id, type, next, branches) to the fields above.
GET /api/v1/flows/templates#
The bundled template gallery: {"templates": [...], "count": n} β id, name, platform, blurb, version, steps, inputs.
POST /api/v1/flows/use-template#
Copy a template into the library as an editable Flow of your own. Takes template_id (or id), returns the new Flow in full.
POST /api/v1/flows/run#
Run a Flow on one profile.
| Field | Default | Notes |
|---|---|---|
flow_id / flow | β | Which Flow |
profile_id / name | β | Which profile |
inputs | β | An object keyed by the input's key |
headless | false | No window |
keep_open | false | Leave the browser open when the run ends |
heal | true | Self-heal a failing step with your AI model. Send false to turn it off |
wait | false | Block until the run finishes |
timeout_s | 300 | With wait: 1β3600 seconds |
Returns the run: run_id, flow_id, flow, profile_id, profile, batch_id, phase, running, step, steps, skipped, repaired, error, started_at, finished_at, vars, and the last 60 log lines. If the wait ran out, timed_out: true comes back and the run keeps going.
vars never includes the profile's saved logins, and a generated persona's password is masked.
An API run never pauses to ask
Nobody is at the keyboard, so there is no stuck card. A failure comes back as a failure, with the step, the log and the page it was on. Self-heal still applies unless you send heal: false.
GET /api/v1/flows/run#
The state of one run. Takes ?run_id= (or ?id=). Live runs answer from memory; a run that finished more than a minute ago answers from history, with its full log. An unknown id is 404.
GET /api/v1/flows/runs#
Every run the app currently knows about, live: {"runs": [...], "count": n}.
POST /api/v1/flows/stop#
Stop a run. Takes run_id (or id), returns {"run_id": "β¦", "stopped": true}.
POST /api/v1/flows/run-many#
Run one Flow across many profiles as a batch.
| Field | Default | Notes |
|---|---|---|
flow_id / flow | β | Which Flow |
profile_ids | β | Array of ids |
names | β | Array of names, each unambiguous |
tag | β | Every profile carrying this tag |
inputs | β | Used for every profile |
concurrency | 3 | Browsers at once, 1β20 |
headless | false | No windows |
heal | true | Self-heal |
wait | false | Block until the batch finishes |
timeout_s | 300 | With wait: 1β3600 seconds |
Give at least one of profile_ids, names or tag. Returns the batch: batch_id, flow_id, flow, phase, total, done, ok, failed, stopped, running, results (per profile: run_id, profile_id, profile, phase, error) and live (the runs still going).
GET /api/v1/flows/batch#
A batch's state. Takes ?batch_id= (or ?id=). Unknown id is 404.
POST /api/v1/flows/batch/stop#
Stop a batch: runs in progress stop, queued profiles are not started. Takes batch_id (or id).
GET /api/v1/flows/history#
Finished runs, newest first. Optional ?flow_id= or ?flow= for one Flow, and ?limit= (1β200, default 50).
Each row: run_id, flow_id, flow, profile_id, profile, batch_id, phase, steps, skipped, repaired, error, started_at, finished_at, and page (url, title) when the run captured one. History is kept on this computer only.
π¨ Status codes and errors#
| Code | When |
|---|---|
400 | Anything the request got wrong: a missing parameter, an ambiguous name, a launch that failed. The error string says which |
401 | missing or wrong token β send Authorization: Bearer <token> |
403 | this API does not serve browser origins, or bad Host header |
404 | no route for {method} {path}, or an unknown run_id / batch_id |
405 | A method other than GET or POST |
415 | POST bodies must be application/json |
501 | profile creation is not available |
Common 400 messages, worth matching on in a script:
- give a profile_id or a name Β· no profile with id {id} Β· no profile named "{name}"
- give a flow_id or a flow name Β· no flow with id {id} Β· no flow named "{name}"
- give profile_ids, names, or a tag that matches at least one profile
- give a run_id Β· give a batch_id Β· give a template_id (see /api/v1/flows/templates)
- body is not valid JSON β {reason} Β· request body too large
- automation (API/MCP) is not supported for Firefox profiles yet β run it from the app, or use a Chromium profile
- "{flow}" is already running on this profile
- this profile is open on another computer β run it there, or take it over first
βΉοΈ Good to know#
- There is no
PUT,PATCHorDELETE, and no route that edits or deletes a profile or a Flow. The API opens things and runs things. - Everything here is also available to an AI agent through the MCP server, which is a wrapper around these same routes: Let AI agents drive LoginDeck (MCP).
- The API serves this computer only, and the token is per computer.
- Passwords never appear in a reply: proxy credentials are stripped, and saved logins are left out of run variables.