Aurorium Local API v1 The Local API allows scripts running on your computer to manage Aurorium profiles, browser sessions, folders, proxies, and cookies. The server starts with the desktop application and is available only on the same computer.
This documentation covers Local API v1. The API version is included in the base URL: /api/v1. Team profiles are not currently supported by the Local API. Support for team profiles is planned for future releases. # Quick startStart Aurorium and sign in to your account. Open Automation → API and generate an API key. Save the key immediately: the backend displays it only once. Send the key with every request using Authorization: Bearer <api_key>. bash curl "http://127.0.0.1:50325/api/v1/health" \
-H "Authorization: Bearer $AURORIUM_API_KEY"Base URL:
text http://127.0.0.1:50325/api/v1The server listens on 127.0.0.1 only, not on an external network interface. The current fixed port is 50325.
# Response formatSuccessful results and application errors use the same response envelope:
json {
"code": 0,
"msg": "success",
"data": {},
"request_id": "req_0d30b83f3fbb43e6a2e1b255e21d24b8"
}code = 0 means success.code != 0 means an application error; checking only the HTTP status is not sufficient.Store request_id in your integration logs for diagnostics. The server usually returns HTTP 200 even for an application error. If the JSON body exceeds 5 MiB, the API returns code: 1001 and msg: "request body too large". Error example:
json {
"code": 1201,
"msg": "profile not found",
"data": null,
"request_id": "req_7f3ab37ea65048f99ebd0fdbe6f4da63"
}# Common parametersList endpoints accept:
Parameter Default Limit page1minimum 1 page_size50maximum 200; larger values are capped at 200
List response data format:
json {
"list": [],
"page": 1,
"page_size": 50,
"total": 0
}# Endpoint overviewMethod Path Purpose GET /healthApplication and cloud connection readiness GET /versionApplication and API versions GET /profileList non-archived profiles POST /profileCreate a profile GET /profile/:idGet profile details PATCH /profile/:idPartially update a profile DELETE /profile/:idDelete a profile GET /folderList folders POST /folderCreate a folder PUT /folder/:idRename a folder DELETE /folder/:idDelete a folder GET /browser/statusGet profile launch status GET /browser/activeList running profiles POST /browser/startStart a profile with CDP POST /browser/stopStop a profile POST /browser/stop-allStop local profiles POST /proxy/checkCheck a proxy PUT /profile/:id/proxyReplace a profile proxy GET /profile/:id/cookiesExport cookies POST /profile/:id/cookies/importImport cookies GET /deviceList account devices GET /catalogGet allowed fingerprint values
# System# GET /healthReturns local application readiness, cloud connection state, and the current device ID.
json {
"ready": true,
"cloud_connected": true,
"device_id": "device-id-or-null"
}Authentication is required even for the health check.
# GET /versionjson {
"app_version": "0.3.1",
"core_version": null,
"api_version": "v1"
}core_version is not implemented yet and always returns null.
# Profiles# GET /profileQuery parameters:
Parameter Values Description folder_idObjectId Filter by folder namestring Search by name statusall, running, idleDefaults to all page, page_sizeinteger Pagination
List item:
json {
"profile_id": "507f1f77bcf86cd799439011",
"name": "Automation profile",
"folder_id": null,
"status": "idle",
"location": null,
"os": "windows",
"os_version": "Windows 11",
"core": "chrome",
"core_version": "134",
"description": "",
"created_at": "2026-07-24T10:00:00Z",
"updated_at": "2026-07-24T10:00:00Z"
}Archived profiles are not returned. The running|idle filter is applied on the client only after the page has been loaded, so total and the number of items on the page may not match the filtered list.
# POST /profileMinimal request:
json {
"name": "Automation profile"
}Supported fields:
Field Type Required Notes namestring yes Non-empty name descriptionstring no Defaults to "" folder_idstring or null no Mongo ObjectId; null means no folder tagsarray no Defaults to [] osstring no windows, macos, linuxos_versionstring no OS version hint for fingerprint generation, such as "11" or "Tahoe"; see /catalog for recommended values is_armboolean no ARM hint; inferred from the GPU vendor when omitted proxyobject no Inline proxy in the format below proxy_idstring no Existing proxy reference; proxy takes precedence launch_argumentsstring no Launch arguments as one string start_pagestring no Start page fingerprintobject no Partial fingerprint overrides
Example with a proxy:
json {
"name": "Profile with proxy",
"os": "windows",
"proxy": {
"type": "socks5",
"host": "127.0.0.1",
"port": 1080,
"user": "login",
"password": "secret"
}
}Profile creation is asynchronous on the backend. The Local API waits for the completion event and normally returns the complete profile model. If the follow-up read fails, only profile_id may be returned.
# GET /profile/:idReturns a list item with additional proxy and fingerprint objects. A proxy password is never returned as plain text; when present, it is replaced with ******.
# PATCH /profile/:idPartially updates a profile:
json {
"name": "New name",
"description": "Updated through API",
"folder_id": null,
"fingerprint": {
"timezone_mode": "manual",
"timezone": "Europe/Moscow"
}
}An empty body is a successful no-op. Metadata is applied immediately. Fingerprint changes are applied immediately when the profile is stopped; for a running profile they are deferred until the next launch and listed in deferred_fields.
json {
"profile_id": "507f1f77bcf86cd799439011",
"deferred_fields": ["fingerprint.timezone_mode", "fingerprint.timezone"]
}For a stopped profile, deferred_fields is always empty.
# DELETE /profile/:idThe force=true query stops a profile running on the current device before deletion. Without force, such a profile returns 1203.
json {
"profile_id": "507f1f77bcf86cd799439011",
"deleted": true
}Deletion is idempotent for a syntactically valid ObjectId: a backend “not found” response is currently treated as an already deleted profile.
# FingerprintThe fingerprint object in POST and PATCH supports partial updates to these fields:
Field Type or values timezone_modeauto, manualtimezonestring or null language_modeauto, manuallanguagesstring[]; the first item is used languagestring; shorthand alternative screen_resolutionstring webrtc_modereal, replacecanvas_noiseboolean webgl_image_noiseboolean webgl_vendorstring or null webgl_rendererstring or null audio_noiseboolean client_rects_noiseboolean hardware_concurrencynumber device_memorynumber do_not_trackdefault, trueos_versionstring dns_modereal, manualdns_serverstring or null geolocation{mode, latitude, longitude, accuracy}media_devices{audio_inputs, audio_outputs, video_inputs}
Use /catalog to retrieve compatible OS, GPU, CPU, RAM, screen, timezone, and language values.
# Folders# GET /folderSupports name, page, and page_size.
json {
"folder_id": "507f1f77bcf86cd799439012",
"name": "QA",
"profile_count": 3,
"system": false
}# POST /folder# PUT /folder/:idjson { "name": "QA automation" }# DELETE /folder/:idProfiles are not deleted with a folder. The backend moves team profiles to the system folder and personal profiles to the no-folder state.
json {
"folder_id": "507f1f77bcf86cd799439012",
"deleted": true,
"moved_profiles": 3,
"moved_to": null
}moved_profiles and moved_to are calculated before deletion on a best-effort basis and may be inaccurate when cloud state cannot be read.
# Browser lifecycle# GET /browser/status?profile_id=:idReturns idle or running, the launch device, and locally available process coordinates.
# GET /browser/activeThe scope query accepts:
this_device — profiles running locally; the default;account — profiles running across all account devices according to the cloud registry.Standard pagination is supported.
# POST /browser/startjson {
"profile_id": "507f1f77bcf86cd799439011",
"headless": false,
"open_urls": ["https://example.com"],
"launch_args": ["--window-size=1280,800"],
"load_extensions": true
}Successful response:
json {
"profile_id": "507f1f77bcf86cd799439011",
"already_running": false,
"debug_port": 51432,
"ws": "ws://127.0.0.1:51432/devtools/browser/...",
"webdriver": null,
"pid": 12345,
"lease": {
"device_id": "device-id",
"device_name": "Workstation",
"is_current_device": true
}
}Starting a profile again on the current device is idempotent. A profile running on another device returns 1204. If the required browser core is missing or downloading, the Local API returns 1304; this method does not download it automatically.
# POST /browser/stopjson { "profile_id": "507f1f77bcf86cd799439011" }Stopping is idempotent and returns was_running.
# POST /browser/stop-allStops every profile on the current device:
json {
"stopped": ["507f1f77bcf86cd799439011"],
"count": 1
}# ProxyInline proxy format:
Field Type Notes typestring http, socks4, socks5, ssh, no_proxyhoststring Required except for no_proxy portinteger/string 1..65535, except for no_proxyuserstring Optional passwordstring Optional refresh_urlstring Optional
# POST /proxy/checkProvide exactly one source: proxy or profile_id.
json {
"proxy": {
"type": "http",
"host": "proxy.example.com",
"port": 8080
}
}json {
"ok": true,
"exit_ip": "203.0.113.10",
"country": "DE",
"city": "Frankfurt",
"latitude": 50.11,
"longitude": 8.68,
"timezone": null,
"latency_ms": null
}# PUT /profile/:id/proxyThe body is the proxy object itself, without a proxy wrapper:
json {
"type": "no_proxy"
}For a running profile, the change is deferred until the next launch and the response contains deferred_fields: ["proxy"].
# CookiesA cookie uses a flat format:
json {
"domain": ".example.com",
"name": "session",
"value": "value",
"path": "/",
"expires": 1790000000,
"http_only": true,
"secure": true,
"same_site": "lax"
}expires is Unix time in seconds; 0 or null means a session cookie. same_site accepts unspecified, no_restriction, lax, or strict.
# GET /profile/:id/cookiesReads the local Chromium SQLite database first and falls back to cookies stored in the cloud when it is unavailable.
# POST /profile/:id/cookies/importjson {
"clear": true,
"cookies": [
{
"domain": ".example.com",
"name": "session",
"value": "value"
}
]
}clear=true replaces cookies and is the default;clear=false merges them with the existing cloud copy;the profile must be stopped on every device; every accepted cookie must include at least domain and name. # Devices# GET /deviceReturns a paginated list:
json {
"device_id": "device-id",
"device_name": "Workstation",
"platform": "windows",
"is_current_device": true,
"online": true,
"last_seen": "2026-07-24T10:00:00Z",
"running_profiles": 1,
"running_profile_ids": ["507f1f77bcf86cd799439011"]
}# Catalog# GET /catalogReturns allowed fingerprint values and GPU → CPU/RAM/screen dependencies. Use os=windows|macos|linux to limit the result to one operating system.
The catalog depends on the cloud and returns 1701 when the cloud is unavailable.
# Error codesCode Meaning 0 Success 1001 Invalid JSON or request body too large 1002 Unknown endpoint or HTTP method 1003 Missing or invalid API key 1101 Required parameter is missing 1103 Invalid parameter value or format 1201 Profile not found 1202 Profile is archived 1203 Profile is running on this device 1204 Profile is running on another device 1301 Browser core failed to start 1304 Browser core is missing or downloading 1401 Invalid proxy configuration 1402 Proxy check failed 1501 Folder not found 1503 A system folder cannot be deleted 1601 Invalid cookie format 1602 Cookies cannot be imported into a running profile 1701 Cloud is unavailable 1901 Internal error
# Minimal JavaScript examplejs const baseUrl = "http://127.0.0.1:50325/api/v1";
const token = process.env.AURORIUM_API_KEY;
async function aurorium(path, options = {}) {
const response = await fetch(`${baseUrl}${path}`, {
...options,
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
...options.headers,
},
});
const result = await response.json();
if (result.code !== 0) {
throw new Error(`[${result.code}] ${result.msg}; ${result.request_id}`);
}
return result.data;
}
const profiles = await aurorium("/profile?page_size=10");
console.log(profiles.list);# CompatibilityThe API version is included in the URL: /api/v1. Numeric error codes are stable within a major API version. Clients should ignore unknown fields because optional response fields may be added without breaking compatibility. Breaking changes require a new major URL such as /api/v2, or an explicitly agreed migration period.