/api/v1/statusStatus
Remote + LocalNo authHealth check. No authentication required.
curl https://vpbrowser.com/api/v1/status{
"code": 0,
"msg": "success",
"data": { "name": "VPBrowser", "version": "..." }
}Developer docs
Start, stop and automate browser profiles from your own code. Connect Puppeteer or Playwright to any profile, on any of your computers, from anywhere. Paths and parameters are AdsPower-compatible.
There are two APIs with the same endpoints and the same AdsPower-compatible response envelope. Pick the one that matches where your script runs.
https://vpbrowser.com/api/v1/…X-Api-Key: vb_live_… (or Authorization: Bearer vb_live_…).http://127.0.0.1:50325/api/v1/…X-Api-Key: <key>.# Either header works
curl -H "X-Api-Key: vb_live_..." https://vpbrowser.com/api/v1/user/list
curl -H "Authorization: Bearer vb_live_..." https://vpbrowser.com/api/v1/user/listcurl -H "X-Api-Key: <key>" http://127.0.0.1:50325/api/v1/user/listEvery response uses the same envelope. code is 0 on success and -1 on error, with msg explaining what went wrong.
{
"code": 0,
"msg": "success",
"data": { ... }
}{
"code": -1,
"msg": "Profile not found",
"data": {}
}Works like a cloud browser: run the VPBrowser app on any computer or server, then control its profiles from anywhere.
ws link from browser/start is a signed ticket valid for 24 h for that one running profile. Get a fresh one from browser/active.Engine support
Full browser control (Puppeteer/Playwright via CDP) works with Vanta profiles (Chromium engine). Vanta Fox (Firefox-based) profiles can be started and stopped via the API but return an empty ws (no remote control — Firefox has no CDP endpoint). Profiles created through the API are always Vanta (Chrome), so they are controllable by default; to control an existing Vanta Fox profile, switch its engine to Vanta in the profile editor.
Performance: control latency
Every CDP action (click, type, read) is a round-trip to the browser. On the Local API that's ~0 ms — the script and the browser are on the same machine. On the Remote API each action crosses the internet through the relay, ~200 ms each, which adds up over a form with many steps.
fill() per field (instant, paste-style) instead of typing character by character, and batch reads in a single evaluate().Resume where you left off
A running profile is a persistent session: disconnecting a CDP client does not close the browser. Calling browser/start (or browser/active) again for the same user_id returns the same running session — its tabs, URL, cookies and form state are all still there. To continue instead of restarting:
browser.contexts()[0].pages()[0] — don't open a new page.AI agents & computer use
Two ready-to-run examples ship in the repo under examples/: ai-agent (an LLM that drives a profile toward a goal with selector/screenshot tools) and computer-use-agent (the ChatGPT-Operator pattern — Claude computer-use looks at a screenshot and drives the browser with real mouse moves, clicks and typing, with a visible gliding cursor). Because they use genuine input events rather than DOM injection, there is no webdriver/automation tell.
There is also an MCP server under examples/mcp-server: add it to Claude Desktop, Claude Code or Cursor and manage and drive profiles in plain language (create_profile, start_browser, browser_goto, browser_click, rotate_proxy…). It wraps this same API, so it's bring-your-own-AI — your client runs the model.
Start a profile through the Remote API, connect to it, open a page, then disconnect. Set VBROWSER_KEY to a key from Settings → Remote API.
curl -H "X-Api-Key: $VBROWSER_KEY" "https://vpbrowser.com/api/v1/browser/start?user_id=900000123"Good to know
user_id accepts the profile's ID (UUID) or its numeric ID shown in the dashboard (e.g. 900000123).disconnect() (Puppeteer) or just exit. Don't call browser.close() unless you want to close the profile's browser.Paths below are for the Remote API. The Local API has the same browser, user and group endpoints at http://127.0.0.1:50325; endpoints marked Remote only exist only on the Remote API.
/api/v1/statusHealth check. No authentication required.
curl https://vpbrowser.com/api/v1/status{
"code": 0,
"msg": "success",
"data": { "name": "VPBrowser", "version": "..." }
}/api/v1/machinesYour computers running the VPBrowser app. Use an id or name as the machine parameter of browser/start.
curl -H "X-Api-Key: $VBROWSER_KEY" https://vpbrowser.com/api/v1/machines{
"code": 0,
"msg": "success",
"data": {
"list": [
{ "id": "...", "name": "...", "online": true, "last_seen": "..." }
]
}
}/api/v1/browser/startOpens the profile's browser and waits until it is up. If the profile is already open, the running one is returned. The ws links are signed tickets valid for 24 h for that one running profile.
| Name | Type | Description |
|---|---|---|
user_idrequired | string | Profile ID (UUID) or the numeric ID shown in the dashboard, e.g. 900000123. |
machineoptional | string | Remote only Computer id or name from /machines. Default: any of your online computers. |
headlessoptional | 0 | 1 | 1 = no window. Vanta only. |
open_urlsoptional | string | Comma-separated http(s) URLs to open. |
timeoutoptional | number | Seconds to wait. Default 120, max 170. The first start can take longer while the engine downloads. |
Local API returns ws: { puppeteer, selenium: "127.0.0.1:<port>" } plus debug_port.
Errors: no app online 409, profile not found 404, launch failed 502, timeout 504.
curl -H "X-Api-Key: $VBROWSER_KEY" \
"https://vpbrowser.com/api/v1/browser/start?user_id=900000123&machine=office-mac&open_urls=https://example.com"{
"code": 0,
"msg": "success",
"data": {
"user_id": "…uuid…",
"numeric_id": 900000123,
"name": "…",
"status": "Active",
"engine": "vanta", // "vanta" | "vantafox" | "chromium"
"machine": { "id": "…", "label": "…" },
"ws": {
"puppeteer": "wss://vpbrowser.com/cdp/<ticket>",
"playwright": "wss://vpbrowser.com/cdp/<ticket>"
}
}
}/api/v1/browser/stopSaves cookies & data and closes the browser.
| Name | Type | Description |
|---|---|---|
user_idrequired | string | Profile ID or numeric ID. |
Local API returns { user_id, stopped }.
{
"code": 0,
"msg": "success",
"data": { "user_id": "…", "stopping": true }
}/api/v1/browser/activeReturns the running entry (with a fresh ws link) or { user_id, status: "Inactive" }. Use it to get a new ticket for a profile that is already open.
| Name | Type | Description |
|---|---|---|
user_idrequired | string | Profile ID or numeric ID. |
{
"code": 0,
"msg": "success",
"data": { "user_id": "…", "status": "Inactive" }
}/api/v1/browser/list-activeAll running profiles you can see. Alias: /api/v1/browser/local-active.
{
"code": 0,
"msg": "success",
"data": { "list": [ { "user_id": "…", "status": "Active", ... } ] }
}/api/v1/user/listPaginated list of profiles. Each item uses the AdsPower field names.
| Name | Type | Description |
|---|---|---|
pageoptional | number | Page number. |
page_sizeoptional | number | Items per page, max 100. |
group_idoptional | string | Only profiles in this group. |
user_idoptional | string | Search by profile ID. |
{
"code": 0,
"msg": "success",
"data": {
"list": [
{
"user_id": "…",
"numeric_id": 900000123,
"serial_number": "…",
"name": "…",
"group_id": "…",
"group_name": "…",
"created_time": "…",
"last_open_time": "…",
"fingerprint_config": { "timezone": "…", "language": "…", "ua": "…", "screen_resolution": "1920_1080" },
"browser_kernel_config": { "type": "…" },
"proxy_config": { "proxy_soft": "…", "proxy_type": "…", "proxy_host": "…", "proxy_user": "…" }
}
],
"page": 1,
"page_size": 50,
"total": 1
}
}/api/v1/user/createJSON body with AdsPower fields. Omitted fingerprint fields are generated as a realistic, unique device. Returns the created profile.
| Name | Type | Description |
|---|---|---|
nameoptional | string | Profile name. |
group_idoptional | string | Group name. |
user_proxy_configoptional | object | proxy_soft ("other" | "no_proxy"), proxy_type ("http" | "socks5"), proxy_host, proxy_port, proxy_user, proxy_password. |
fingerprint_configoptional | object | Optional: ua, screen_resolution (e.g. "1920_1080"), timezone, language. |
Plan limits apply: over the limit returns 402 “Your X plan allows N profiles”.
curl -X POST https://vpbrowser.com/api/v1/user/create \
-H "X-Api-Key: $VBROWSER_KEY" -H "Content-Type: application/json" \
-d '{
"name": "Shop account 1",
"group_id": "Shops",
"user_proxy_config": {
"proxy_soft": "other",
"proxy_type": "socks5",
"proxy_host": "1.2.3.4",
"proxy_port": "1080",
"proxy_user": "user",
"proxy_password": "pass"
},
"fingerprint_config": { "screen_resolution": "1920_1080", "language": "en-US" }
}'/api/v1/user/updateBody: user_id plus the fields to change (same fields as create).
| Name | Type | Description |
|---|---|---|
user_idrequired | string | Profile to update. |
curl -X POST https://vpbrowser.com/api/v1/user/update \
-H "X-Api-Key: $VBROWSER_KEY" -H "Content-Type: application/json" \
-d '{ "user_id": "900000123", "name": "Renamed" }'/api/v1/user/deleteMoves the profiles to the Recycle Bin.
| Name | Type | Description |
|---|---|---|
user_idsrequired | string[] | Profiles to delete. A single user_id is also accepted. |
curl -X POST https://vpbrowser.com/api/v1/user/delete \
-H "X-Api-Key: $VBROWSER_KEY" -H "Content-Type: application/json" \
-d '{ "user_ids": ["900000123"] }'/api/v1/proxy/checkRoutes a geo/IP lookup through the profile's saved proxy and returns the real exit. On success it also marks the proxy OK and aligns the profile's timezone, language and location to the exit country.
| Name | Type | Description |
|---|---|---|
user_idrequired | string | Profile ID or numeric ID. |
curl -H "X-Api-Key: $VBROWSER_KEY" \
"https://vpbrowser.com/api/v1/proxy/check?user_id=900000123"{
"code": 0,
"msg": "success",
"data": {
"user_id": "…",
"exit_ip": "77.179.250.209",
"country": "DE", "city": "Frankfurt", "region": "Hesse",
"isp": "Telefonica Germany",
"latency_ms": 420
}
}/api/v1/proxy/rotateGets a new exit IP: a VPBrowser proxy rerolls a fresh, quality-checked IP (sticky mode); a custom proxy with a rotation URL has it fetched. Rotating-mode proxies already change on every connection.
| Name | Type | Description |
|---|---|---|
user_idrequired | string | Profile ID or numeric ID. |
through_proxyoptional | 0 | 1 | Send the rotation request through the proxy itself (custom rotation-URL proxies only). |
curl -X POST https://vpbrowser.com/api/v1/proxy/rotate \
-H "X-Api-Key: $VBROWSER_KEY" -H "Content-Type: application/json" \
-d '{ "user_id": "900000123" }'/api/v1/group/listAll profile groups.
/api/v1/group/createCreates a profile group.
| Name | Type | Description |
|---|---|---|
group_namerequired | string | Name of the new group. |
/api/v1/group/updateRenames a profile group.
| Name | Type | Description |
|---|---|---|
group_idrequired | string | Group to rename. |
group_namerequired | string | New name. |
Errors use the envelope with code: -1, and the HTTP status is meaningful:
| Status | Meaning |
|---|---|
| 401 | Bad or missing API key. |
| 402 | Plan limit reached when creating profiles, e.g. “Your X plan allows N profiles”. |
| 403 | Suspended workspace, or an API key used on the wrong route. |
| 404 | Not found (e.g. profile not found). |
| 409 | No computer online, or the chosen computer is offline. |
| 502 | Launch failed. |
| 504 | Timed out waiting for the browser. |
/api/v1/machines.machine=<name> and connect to the ws link from anywhere.Proxies stay with the profile
Each profile keeps its own proxy, so websites see the profile's proxy IP, never your server's or your script's.