> ## Documentation Index
> Fetch the complete documentation index at: https://docs-preview.webcompute.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API

> Use Webcompute over HTTP when a platform, worker, or non-TypeScript service owns browser orchestration.

Use the REST API when your platform owns orchestration over HTTP or when another language controls the workflow.

The Python package is currently a stub. Python services should call the REST API directly until the Python SDK ships the TypeScript SDK surface.

## Authentication

```bash theme={null}
curl https://api.webcompute.dev/v1/browsers \
  -H "Authorization: Bearer $WEBCOMPUTE_API_KEY"
```

`/health` is public. Browser, file, download, recording, and execution endpoints require authentication.

## Minimal lifecycle

The shell example uses `jq` to extract the browser ID from the create response. Browser lifecycle create and delete requests require an `Idempotency-Key` header.

Create a browser:

```bash theme={null}
BROWSER_JSON=$(curl -sS -X POST https://api.webcompute.dev/v1/browsers \
  -H "Authorization: Bearer $WEBCOMPUTE_API_KEY" \
  -H "Idempotency-Key: browser-create-$(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"recording":true,"policy":{"allowedDomains":["example.com"]}}')
```

Run an exact browser-code step against it:

```bash theme={null}
BROWSER_ID=$(printf '%s' "$BROWSER_JSON" | jq -r '.id // .browser.id')

curl -sS -X POST "https://api.webcompute.dev/v1/browsers/$BROWSER_ID/playwright/execute" \
  -H "Authorization: Bearer $WEBCOMPUTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "await page.goto(\"https://example.com\"); return { title: await page.title(), url: page.url() };",
    "capture": { "status": true, "observation": { "kind": "aria", "includeOn": "always" } }
  }'
```

Clean up:

```bash theme={null}
curl -sS -X DELETE "https://api.webcompute.dev/v1/browsers/$BROWSER_ID" \
  -H "Authorization: Bearer $WEBCOMPUTE_API_KEY" \
  -H "Idempotency-Key: browser-close-$(uuidgen)"
```

The API reference covers status, advanced browser-code execution, files, downloads, dialogs, permissions, recordings, screenshots, PDFs, proxy fields, and cleanup.

## Python over HTTP

```python theme={null}
import json
import os
import uuid
import urllib.request

API_KEY = os.environ["WEBCOMPUTE_API_KEY"]
BASE_URL = "https://api.webcompute.dev"


def request(method, path, body=None, idempotency_key=None):
    data = None if body is None else json.dumps(body).encode("utf-8")
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }
    if idempotency_key:
        headers["Idempotency-Key"] = idempotency_key
    req = urllib.request.Request(
        f"{BASE_URL}{path}",
        data=data,
        method=method,
        headers=headers,
    )
    with urllib.request.urlopen(req, timeout=60) as response:
        payload = response.read()
        return json.loads(payload) if payload else None


created = request("POST", "/v1/browsers", {
    "recording": True,
    "policy": {"allowedDomains": ["example.com"]},
}, idempotency_key=f"browser-create-{uuid.uuid4()}")
browser_id = created.get("id") or created["browser"]["id"]

try:
    result = request("POST", f"/v1/browsers/{browser_id}/playwright/execute", {
        "code": "await page.goto('https://example.com'); return await page.title();",
        "capture": {"status": True, "observation": {"kind": "aria", "includeOn": "always"}},
    })
    print(result["result"])
finally:
    request("DELETE", f"/v1/browsers/{browser_id}", idempotency_key=f"browser-close-{uuid.uuid4()}")
```

## When to prefer the SDK

Use the TypeScript SDK when your app is written in TypeScript and can call `web.agent()` directly. Use REST when the integration boundary is HTTP.

Reference: [API reference](/api-reference/overview), [TypeScript SDK reference](/reference/sdk-reference), [proxy reference](/reference/proxy-reference), and [policy reference](/reference/policy-reference).
