What each route is for, what it takes, what it answers, and every refusal it can give. The badge beside an operation says whether the build you can download today answers it at all.
GET /v1/status
In the released buildIs Liminal running, and is anyone signed in
The cheapest call there is, and the one to poll while you wait for the app. It answers without an account: a false signedIn is a state, not an error.
Parameters
None.
Answer
{
"status": "running",
"version": "<version>",
"signedIn": true
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
GET /v1/profiles
In the released buildThe profiles in the catalog, filtered and paged
Reads the same catalog the app shows. Filters combine, and every one of them is exact except name, which matches any profile whose name contains what you typed, in any case.
Parameters
- pagequery · integer · optional · 1 to 1000000 · defaults to 1
- Which page to read, counting from one.
- pageSizequery · integer · optional · 1 to 100 · defaults to 100
- How many profiles a page holds. The ceiling is the default.
- workspaceIdquery · string · optional
- Only profiles of that workspace.
- folderIdquery · string · optional
- Only profiles of that folder.
- statusquery · string · optional
- Only profiles in that state; running is the state of an open profile.
- namequery · string · optional
- Only profiles whose name contains this, ignoring case.
Answer
{
"page": 1,
"pageSize": 100,
"total": 1,
"items": [
"<profile>"
]
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
- 403 not_signed_in — Nobody is signed in to the app; the catalog operations need an account.
- 503 catalog_unavailable — The profile catalog is not ready yet. Ask again.
- 400 invalid_pagination — page or pageSize is outside the accepted range.
GET /v1/profiles/{id}
In the released buildOne profile, with its proxy and its fingerprint
The same object the list returns, for one identifier. The proxy address is shown; its password never is.
Parameters
- idpath · string · required
- The profile identifier, as the catalog operations return it.
Answer
{
"id": "<profile-id>",
"name": "Shop EU",
"workspaceId": "<workspace-id>",
"folderId": "<folder-id>",
"status": "running",
"health": "ok",
"proxy": {
"id": "<proxy-id>",
"name": "Residential DE",
"type": "socks5",
"host": "proxy.example.net",
"port": 1080,
"working": true,
"lastCheckedExternalIp": "203.0.113.10",
"lastCheckedCountryCode": "DE"
},
"fingerprint": {
"platform": "MacIntel",
"language": "de-DE",
"timezone": "Europe/Berlin"
},
"lastOpenedAt": "2026-09-30T08:15:00.000Z"
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
- 403 not_signed_in — Nobody is signed in to the app; the catalog operations need an account.
- 503 catalog_unavailable — The profile catalog is not ready yet. Ask again.
- 404 profile_not_found — No profile with that identifier is in the catalog.
POST /v1/profiles/{id}/start
In the released buildOpen a profile and get the address a driver connects to
Starts the profile the way the app does — its fingerprint, its proxy, its cookies — and answers with the CDP address once the browser is up. The call waits; it does not return a job to poll.
Parameters
- idpath · string · required
- The profile identifier, as the catalog operations return it.
- debugPortbody · integer · optional · 1024 to 65534 · defaults to 0
- The port the CDP endpoint binds. 0 lets the app pick a free one; any other value has to be one your user can bind.
- timeoutSecondsbody · integer · optional · 1 to 180 · defaults to 60
- How long the call waits for the profile to come up before it gives up.
- maskAutomationbody · boolean · optional · defaults to true
- Only true is accepted. Automation masking cannot be turned off: a profile under a script is the same profile a site sees when you open it by hand.
Answer
{
"id": "<profile-id>",
"status": "running",
"cdpDiscoveryUrl": "http://127.0.0.1:48361/devtools/<token>/json/version",
"cdpBrowserUrl": "ws://127.0.0.1:9222/devtools/browser/<token>",
"seleniumDebuggerUrl": "127.0.0.1:9222",
"chromedriverPath": "/Applications/Liminal.app/.../chromedriver",
"debugPort": 9222,
"debugAddress": "127.0.0.1:9222",
"externalIp": "203.0.113.10",
"countryCode": "DE"
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
- 403 not_signed_in — Nobody is signed in to the app; the catalog operations need an account.
- 503 runtime_unavailable — The app cannot start or stop a profile right now.
- 404 profile_not_found — No profile with that identifier is in the catalog.
- 409 profile_already_running — The profile is open already, a start for it is still running, or a driver address handed out earlier is still good.
- 400 invalid_start_options — The body is not a JSON object.
- 400 invalid_port — debugPort is neither 0 nor a port in the accepted range.
- 400 invalid_start_timeout — timeoutSeconds is outside the accepted range.
- 400 masking_unavailable — maskAutomation was sent as false, which the app does not offer.
- 409 port_in_use — The debug port you asked for is taken.
- 409 listen_failed — The debug port could not be bound for another reason.
- 409 start_failed — The profile did not come up. A safe `detail` names the stage when the app can say it.
- 409 proxy_unavailable — The profile requires its proxy, and the proxy did not answer.
- 502 start_failed — Preparing the profile failed before the browser was asked to start.
- 503 cdp_unavailable — The profile started but its CDP endpoint did not come up.
- 504 start_timeout — The profile did not come up within timeoutSeconds.
POST /v1/profiles/{id}/attach-automation
In the released buildGet a driver address for a profile that is already open
For a profile you opened by hand and now want to drive. It does not restart anything: the session, its tabs and its cookies stay as they are.
Parameters
- idpath · string · required
- The profile identifier, as the catalog operations return it.
- debugPortbody · integer · optional · 1024 to 65534 · defaults to 0
- The port the CDP endpoint binds. 0 lets the app pick a free one; any other value has to be one your user can bind.
- timeoutSecondsbody · integer · optional · 1 to 180 · defaults to 60
- How long the call waits for the profile to come up before it gives up.
- maskAutomationbody · boolean · optional · defaults to true
- Only true is accepted. Automation masking cannot be turned off: a profile under a script is the same profile a site sees when you open it by hand.
Answer
{
"id": "<profile-id>",
"status": "running",
"cdpDiscoveryUrl": "http://127.0.0.1:48361/devtools/<token>/json/version",
"cdpBrowserUrl": "ws://127.0.0.1:9222/devtools/browser/<token>",
"seleniumDebuggerUrl": "127.0.0.1:9222",
"chromedriverPath": "/Applications/Liminal.app/.../chromedriver",
"debugPort": 9222,
"debugAddress": "127.0.0.1:9222",
"externalIp": "203.0.113.10",
"countryCode": "DE"
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
- 403 not_signed_in — Nobody is signed in to the app; the catalog operations need an account.
- 503 runtime_unavailable — The app cannot start or stop a profile right now.
- 404 profile_not_found — No profile with that identifier is in the catalog.
- 409 profile_already_running — The profile is open already, a start for it is still running, or a driver address handed out earlier is still good.
- 400 invalid_start_options — The body is not a JSON object.
- 400 invalid_port — debugPort is neither 0 nor a port in the accepted range.
- 400 invalid_start_timeout — timeoutSeconds is outside the accepted range.
- 400 masking_unavailable — maskAutomation was sent as false, which the app does not offer.
- 409 port_in_use — The debug port you asked for is taken.
- 409 listen_failed — The debug port could not be bound for another reason.
- 409 start_failed — The profile did not come up. A safe `detail` names the stage when the app can say it.
- 409 proxy_unavailable — The profile requires its proxy, and the proxy did not answer.
- 502 start_failed — Preparing the profile failed before the browser was asked to start.
- 503 cdp_unavailable — The profile started but its CDP endpoint did not come up.
- 504 start_timeout — The profile did not come up within timeoutSeconds.
- 409 profile_not_running — The profile is not open, so there is nothing to attach to.
POST /v1/profiles/{id}/stop
In the released buildClose a profile the way its window would
Lets the session finish writing its state. This is the one to call between scripted runs on the same profile.
Parameters
- idpath · string · required
- The profile identifier, as the catalog operations return it.
Answer
{
"id": "<profile-id>",
"status": "closed"
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
- 403 not_signed_in — Nobody is signed in to the app; the catalog operations need an account.
- 503 runtime_unavailable — The app cannot start or stop a profile right now.
- 404 profile_not_found — No profile with that identifier is in the catalog.
- 409 profile_not_running — The profile is not open, so there is nothing to close.
- 409 stop_failed — The app could not close the profile.
POST /v1/profiles/{id}/force-stop
In the released buildClose a profile that will not close
The same answer, without waiting for the session to settle. Reach for it when a stop did not return, not as a matter of course.
Parameters
- idpath · string · required
- The profile identifier, as the catalog operations return it.
Answer
{
"id": "<profile-id>",
"status": "closed"
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
- 403 not_signed_in — Nobody is signed in to the app; the catalog operations need an account.
- 503 runtime_unavailable — The app cannot start or stop a profile right now.
- 404 profile_not_found — No profile with that identifier is in the catalog.
- 409 profile_not_running — The profile is not open, so there is nothing to close.
- 409 stop_failed — The app could not close the profile.
GET /v1/running-profiles
In the released buildWhat is open right now, and what can be driven
Every profile that is open, whether a window or a call opened it — startedBy says which — with its driver address when one is available. Reconnect from here after your script restarts.
Parameters
None.
Answer
{
"items": [
{
"id": "<profile-id>",
"workspaceId": "<workspace-id>",
"status": "running",
"automationAvailable": true,
"startedBy": "api",
"cdpBrowserUrl": "ws://127.0.0.1:9222/devtools/browser/<token>",
"seleniumDebuggerUrl": "127.0.0.1:9222",
"chromedriverPath": "/Applications/Liminal.app/.../chromedriver",
"debugPort": 9222,
"debugAddress": "127.0.0.1:9222"
}
]
}
Refusals
- 401 invalid_key — The key is missing, malformed or has been regenerated since.
- 403 not_signed_in — Nobody is signed in to the app; the catalog operations need an account.
- 503 catalog_unavailable — The profile catalog is not ready yet. Ask again.