SDKs & reference
Errors
How the API reports failures: the HTTP status codes it returns, the OculrError the SDKs raise, and the common failures you will hit while building.
HTTP status codes
The API uses standard HTTP status codes. A 2xx is success. Anything else carries a JSON body with a detail field describing what went wrong.
| Code | Meaning | When |
|---|---|---|
| 200 | OK | A successful read or action. |
| 201 | Created | A profile, proxy, or credential was created. |
| 400 | Bad request | The launch options or body were malformed. |
| 401 | Unauthorized | The bearer token is missing or wrong. |
| 404 | Not found | The profile, proxy, or credential does not exist, or the profile is not running. |
| 409 | Conflict | The profile is already running, a proxy leak was detected, or the browser kernel is missing. |
| 422 | Unprocessable entity | A create or update field failed validation. |
| 500 | Server error | The browser failed to launch. |
The OculrError shape
Both SDKs raise an OculrError on any non 2xx response. It carries the HTTP status and the parsed response body, so you can branch on exactly what went wrong rather than parsing a string.
export class OculrError extends Error { readonly status: number; // HTTP status code readonly body: unknown; // parsed JSON response body}| Property | Type | Description |
|---|---|---|
| status | number | HTTP status code of the failed response. |
| body | unknown | Parsed JSON body, usually { detail } or a structured error. |
| message | string | Human readable summary, from the base Error. |
Handling errors
Catch OculrError and branch on status. The example below handles an already running profile and a bad token, and rethrows anything else.
import { OculrClient, OculrError } from "@oculr/sdk"; const oculr = new OculrClient({ baseUrl: "http://127.0.0.1:8378", token: process.env.OCULR_TOKEN,}); try { await oculr.launch("de-store-01", { stealth: "balanced" });} catch (err) { if (err instanceof OculrError) { if (err.status === 409) { // Already running, or a proxy leak was caught. console.error("conflict:", err.body); } else if (err.status === 401) { console.error("check your token"); } else { throw err; } } else { throw err; }}Common failures
| Status | Failure | What to do |
|---|---|---|
| 401 | Missing or invalid token | Copy the current token from Settings and send it as Authorization: Bearer <token>. |
| 404 | Profile not found | Check the id with GET /api/profiles. |
| 404 | Profile is not running | Launch it before calling stop, status, or attach. |
| 409 | Profile is already running | Attach to the existing session, or stop it first. |
| 409 | Proxy leak detected | The egress IP equalled your local IP. Fix the proxy, or bind it to the profile so the leak guard can run. |
| 409 | Kernel missing | The browser kernel is not installed. The body carries code: "kernel_missing" with the engine_version to install. |
| 400 | Invalid launch options | A launch option was malformed. Check the stealth value and the window shape. |
| 422 | Validation error | A create or update field failed validation. The body lists the offending fields. |
stealth: "off" requires the Chrome engine. A profile on a non Chrome engine always spoofs its fingerprint and cannot disable injection.