---
title: "Launch a profile's browser and wait for it to start; returns `{pid, cdpUrl}`, a full pool fails with 409 rather than queuing. Optional body `{diagnostic?: bool, headless?: bool, idle_timeout_secs?: integer}`: `diagnostic` opens the profile's proxy without its fingerprint, in a temporary directory; `headless` runs it without a window; `idle_timeout_secs` stops it after that long with no API call naming it (0 = never; default 30 min). A profile that is already running is not relaunched (409)."
method: POST
path: "/v1/profiles/{id}/launch"
---

# Launch a profile's browser and wait for it to start; returns \`{pid, cdpUrl}\`, a full pool fails with 409 rather than queuing. Optional body \`{diagnostic?: bool, headless?: bool, idle_timeout_secs?: integer}\`: \`diagnostic\` opens the profile's proxy without its fingerprint, in a temporary directory; \`headless\` runs it without a window; \`idle_timeout_secs\` stops it after that long with no API call naming it (0 = never; default 30 min). A profile that is already running is not relaunched (409).

`POST /v1/profiles/{id}/launch`

## Request

- Base URL: `http://127.0.0.1:10108`
- URL: `http://127.0.0.1:10108/v1/profiles/{id}/launch`
- Auth: HTTP bearer

Opens this profile's browser with its fingerprint, proxy, cookies and logins, and waits until it has started. It takes a slot of the browser pool until it is stopped, or until it sits idle past `idle_timeout_secs`. The returned `cdpUrl` lets any local process drive the browser while it runs.

## Path parameters

- `id` string, required

## Request body

- object
  - `diagnostic` boolean: Diagnostic launch: the profile's proxy, but none of its fingerprint, in a fresh temporary browser directory deleted on stop — no cookies or logins, and nothing is written to the profile. The page sees THIS machine's real values (platform, CPU cores, GPU, screen, timezone, languages): use it to tell whether a site blocks the fingerprint or the IP/proxy, never on an account you care about. The engine's CDP hiding still applies; WebRTC is restricted to the proxy. Default false.
  - `headless` boolean: Headless launch: the browser runs without a window (`--headless=new`). The profile's fingerprint is unchanged, including its screen size, and the engine's CDP hiding still applies. Measured on the macOS engine 154: detector sites score a headless launch like a windowed one — it is NOT a stealth feature and NOT more detectable. A profile that is already running is not relaunched (409): reuse it through the profile list, which reports its `cdpUrl` and whether it runs headless. Default false.
  - `idle_timeout_secs` integer: Stop this browser after this many seconds with no Veilus API/MCP call naming the profile (navigate, click, snapshot, ...). Traffic sent straight to `cdpUrl` by another client does NOT count: a framework driving the profile over CDP should pass 0, which never stops it. Default: the app setting, 30 minutes unless changed. Profiles opened from the Veilus window are never stopped this way.

## Response `200`

The browser started. `diagnostic` and `headless` appear only when true.

- object
  - `cdpUrl` string, required
  - `diagnostic` unknown
  - `headless` unknown
  - `pid` integer, required

## Other responses

- `400`: The id is not a uuid, or the body has an unknown key or a value of the wrong type.
- `401`: No bearer token, or not a token this app issued. The body is empty: it never says which.
- `403`: Refused by the plan: it no longer includes the local API (checked on every request), or it does not allow this action (profile or schedule limit, parallel runs). A request whose Host header is not loopback is also 403, with an empty body.
- `409`: Not launched: the pool is full, the profile is already running or does not exist, or the engine failed to start. Retrying the same call does not help until that changes.
- `429`: Too many expensive calls from this token: launch, script run, batch, run schedule now, create profiles and import proxies count together, 30 per rolling 60 s. The Retry-After header gives the seconds to wait.
- `500`: Veilus failed: storage could not be read or written, or a task panicked. The message says what failed; retrying rarely helps.

---

[API](https://skmtc.dev/veilus/apis/veilus-local-api.md) · [All operations](https://skmtc.dev/veilus/apis/veilus-local-api/llms.txt) · [OpenAPI document](https://skmtc.dev/veilus/apis/veilus-local-api/revisions/67ac3818f9d2?raw)
