01 · Get started

Where the API lives.

View as Markdown

Donut Browser ships an HTTP server that starts when you launch the app. It listens on loopback only — your local API surface, never the network.

Ports and endpoints

  • REST API: http://127.0.0.1:10108 — base path /v1, OpenAPI spec at /openapi.json.
  • Per-profile CDP: the run response returns a per-profile CDP port (default 9222). Connect Playwright, Puppeteer, or any CDP client.
  • MCP server: stdio transport — invoked by Claude / Cursor / your MCP host via the donut-mcp binary shipped with the app. See the MCP page.

First request

Grab your bearer token from Settings → Integrations → Local API (see Authentication for the panel screenshot) and export it as DONUT_API_KEY (Unix shells) or $env:DONUT_API_KEY (PowerShell). Then ping the spec:

curl -sS http://127.0.0.1:10108/openapi.json \
  -H "Authorization: Bearer $DONUT_API_KEY" | jq '.info'
// Node 18+ has fetch built-in. Set DONUT_API_KEY in your environment.
const response = await fetch("http://127.0.0.1:10108/openapi.json", {
  headers: { Authorization: `Bearer ${process.env.DONUT_API_KEY}` },
});
const spec = await response.json();
console.log(spec.info);
# pip install requests
import os, requests

response = requests.get(
    "http://127.0.0.1:10108/openapi.json",
    headers={"Authorization": f"Bearer {os.environ['DONUT_API_KEY']}"},
    timeout=10,
)
response.raise_for_status()
print(response.json()["info"])
$response = Invoke-RestMethod -Uri "http://127.0.0.1:10108/openapi.json" `
    -Headers @{ Authorization = "Bearer $env:DONUT_API_KEY" }

$response.info | ConvertTo-Json

Expected response shape:

{
  "title": "donutbrowser",
  "description": "Simple Yet Powerful Anti-Detect Browser",
  "version": "0.24.2"
}