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

# Computers API

> Create cloud computers and browsers over REST: run commands, read and write files, browse, then destroy.

The Computers API lets you create cloud computers and browsers from code, on demand, for your own users and agents. Two resources, one sentence: computers run your code; browsers browse; a browser can optionally run on one of your computers.

All endpoints live on `https://api.kazzle.app` and accept a `kzl_` API key in the `Authorization` header. See [API keys](/platform/api-keys) for how to create one. The examples below read the key from the `KAZZLE_API_KEY` environment variable:

```bash theme={"theme":"material-theme-darker"}
export KAZZLE_API_KEY=kzl_your_api_key_here
```

Running computers and browsers bill per minute against your space credits. Creates and wakes fail when the space is out of credits. See [Billing](/platform/billing).

## Create a computer

```bash theme={"theme":"material-theme-darker"}
curl -X POST https://api.kazzle.app/computers \
  -H "Authorization: Bearer $KAZZLE_API_KEY"
```

```json theme={"theme":"material-theme-darker"}
{ "id": "8b2d5f1e-4c9a-4f5e-9d2b-1a7c3e6f0a42", "state": "offline" }
```

The `state` is the connection state: `offline` right after create, `online` once the computer is up. The computer boots with a persistent disk. Files, installed packages, and tools survive stop and wake. `GET /computers` lists the computers in your space; all list endpoints return `{ "items": [...], "total": n }`.

## Wake it

An idle computer suspends. Wake it before use; wakes resume from a snapshot and take seconds.

```bash theme={"theme":"material-theme-darker"}
curl -X POST https://api.kazzle.app/computers/8b2d5f1e-4c9a-4f5e-9d2b-1a7c3e6f0a42/wake \
  -H "Authorization: Bearer $KAZZLE_API_KEY"
```

## Run a command

`POST /exec` runs one command and streams the result as server-sent events: `stdout` with the output, then `exit` with the exit code. Output from stderr arrives merged into the `stdout` events. Use `curl -N` to keep the stream open.

```bash theme={"theme":"material-theme-darker"}
curl -N -X POST https://api.kazzle.app/computers/8b2d5f1e-4c9a-4f5e-9d2b-1a7c3e6f0a42/exec \
  -H "Authorization: Bearer $KAZZLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"command": "python3 -V"}'
```

```
event: stdout
data: {"text": "Python 3.12.3\n"}

event: exit
data: {"code": 0}
```

Optional body fields tune the run: `cwd`, `shell`, `env`, and `timeout_ms` (the command is killed when it elapses). All request and response fields across the API are snake\_case.

For long-running processes (dev servers, watchers) use `/terminals` instead: `POST /computers/{id}/terminals` opens a PTY session and returns its `session_id` for the write, read, ctrl, wait, and kill endpoints. See the [API Reference](/api-reference) for terminal and desktop endpoints.

## Read and write files

```bash theme={"theme":"material-theme-darker"}
curl -X POST https://api.kazzle.app/computers/8b2d5f1e-4c9a-4f5e-9d2b-1a7c3e6f0a42/fs/write \
  -H "Authorization: Bearer $KAZZLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path": "app/hello.txt", "content": "hello from the API\n"}'
```

```bash theme={"theme":"material-theme-darker"}
curl -X POST https://api.kazzle.app/computers/8b2d5f1e-4c9a-4f5e-9d2b-1a7c3e6f0a42/fs/read \
  -H "Authorization: Bearer $KAZZLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path": "app/hello.txt"}'
```

Reads are capped at 2 MB. Binary files come back base64 with an `"encoding": "base64"` field.

`/fs` also supports `delete`, `move` and `copy` (body `{"from": "...", "to": "..."}`), `grep` (returns `{"matches": [...]}`), and `glob` (returns `{"files": [...]}`).

## Open a browser

Browsers are their own resource, not tied to a computer count. One computer can use many browsers; a hundred computers can share none.

| How              | Request                                | Use for                                             |
| ---------------- | -------------------------------------- | --------------------------------------------------- |
| Stealth          | `POST /browsers` with an empty body    | The real web. Anti-bot fingerprint and proxies.     |
| On your computer | `POST /browsers` with `computer_id`    | That computer's own pages: app previews, localhost. |
| With a profile   | Either of the above, plus `profile_id` | Staying logged in. Cookies and logins persist.      |

```bash theme={"theme":"material-theme-darker"}
# Stealth cloud browser
curl -X POST https://api.kazzle.app/browsers \
  -H "Authorization: Bearer $KAZZLE_API_KEY"

# Built-in browser on your computer
curl -X POST https://api.kazzle.app/browsers \
  -H "Authorization: Bearer $KAZZLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"computer_id": "8b2d5f1e-4c9a-4f5e-9d2b-1a7c3e6f0a42"}'

# Stealth, reusing a saved profile
curl -X POST https://api.kazzle.app/browsers \
  -H "Authorization: Bearer $KAZZLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"profile_id": "c7e2a5b8-9f1d-4c6e-8a3b-2d5f7e0c4a91"}'
```

Create returns the browser, its first tab, and a `live_view_url` you can open to watch it:

```json theme={"theme":"material-theme-darker"}
{
  "id": "f3a9c8d1-2b6e-4a7f-8c1d-5e9b0f4a2c73",
  "tab_id": "1d4e7a92-6c3b-48f5-b2e8-9a0c5d7f1e64",
  "computer_id": null,
  "provider": "kernel",
  "url": "about:blank",
  "live_view_url": "https://..."
}
```

`GET /browsers/{id}` returns the same state and `live_view_url` again later. Get the profile with `POST /browsers/profiles`: it ensures the profile rather than creating a new one each time. It creates the profile only if missing, returns `"created": false` when it already exists, and today keeps one durable profile per browser backend. Profiles outlive browser sessions and are shared across them.

## Drive a tab

Actions are tab-scoped. Navigate, then screenshot:

```bash theme={"theme":"material-theme-darker"}
curl -X POST https://api.kazzle.app/browsers/f3a9c8d1-2b6e-4a7f-8c1d-5e9b0f4a2c73/tabs/1d4e7a92-6c3b-48f5-b2e8-9a0c5d7f1e64/nav \
  -H "Authorization: Bearer $KAZZLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
```

```bash theme={"theme":"material-theme-darker"}
curl -X POST https://api.kazzle.app/browsers/f3a9c8d1-2b6e-4a7f-8c1d-5e9b0f4a2c73/tabs/1d4e7a92-6c3b-48f5-b2e8-9a0c5d7f1e64/screenshot \
  -H "Authorization: Bearer $KAZZLE_API_KEY" \
  --output page.png
```

Tabs support around 40 actions: `click`, `type`, `eval`, and more. `POST /browsers/{id}/tabs` opens another tab and returns its id as the top-level `tab_id`. The full list is in the [API Reference](/api-reference).

## Destroy

Close the browser when you are done browsing. Destroy the computer to stop billing and delete its disk; this is permanent.

```bash theme={"theme":"material-theme-darker"}
curl -X DELETE https://api.kazzle.app/browsers/f3a9c8d1-2b6e-4a7f-8c1d-5e9b0f4a2c73 \
  -H "Authorization: Bearer $KAZZLE_API_KEY"

curl -X DELETE https://api.kazzle.app/computers/8b2d5f1e-4c9a-4f5e-9d2b-1a7c3e6f0a42 \
  -H "Authorization: Bearer $KAZZLE_API_KEY"
```

Prefer `POST /computers/{id}/stop` if you want the files back later; stopped computers keep their disk and wake in seconds.

## A computer per user, driven by an agent

Everything above is one `curl` per call. In code, the typed `kazzle` client wraps the same endpoints: `npm install kazzle`, then `new Kazzle()` reads `KAZZLE_API_KEY` from the environment. Inside a deployed Kazzle app, import it as `@kazzle/app/sdk` instead; the key is injected there and scopes every call to the app's space.

Give each of your users their own cloud computer, keep its id on their record, and let an agent drive it with tools that call the client. The loop below hands the model two tools, `run_command` and `browse`, and runs until the model stops asking for tool calls.

```ts theme={"theme":"material-theme-darker"}
import { Kazzle } from 'kazzle';

const kazzle = new Kazzle(); // reads KAZZLE_API_KEY

// One computer per user, provisioned once and reused.
async function computerForUser(user: { id: string; computerId?: string }): Promise<string> {
  if (user.computerId) {
    await kazzle.computers.wake(user.computerId);
    return user.computerId;
  }
  const computer = await kazzle.computers.create();
  await kazzle.computers.wake(computer.id);
  await saveComputerId(user.id, computer.id); // your storage
  return computer.id;
}

// The tools the agent can call. Each one drives this user's computer or browser.
async function runTool(computerId: string, name: string, args: Record<string, string>): Promise<string> {
  if (name === 'run_command') {
    const res = await kazzle.computers.exec(computerId, { command: args.command }).text();
    return `exit ${res.exitCode}\n${res.text}`;
  }
  if (name === 'browse') {
    const browser = await kazzle.browsers.create({ computerId });
    await browser.nav(args.url);
    const png = await browser.screenshot();
    await browser.close();
    return `screenshot: ${png.byteLength} bytes`;
  }
  throw new Error(`unknown tool ${name}`);
}

// Agent loop: the model asks for tool calls, you run them, you feed results back.
async function handleUserGoal(user: { id: string; computerId?: string }, goal: string): Promise<string> {
  const computerId = await computerForUser(user);
  const messages = [{ role: 'user', content: goal }];
  while (true) {
    const step = await yourModel(messages); // your own LLM call
    if (!step.toolCalls?.length) return step.text;
    for (const call of step.toolCalls) {
      const result = await runTool(computerId, call.name, call.args);
      messages.push({ role: 'tool', toolCallId: call.id, content: result });
    }
  }
}
```

`kazzle.browsers.create()` with no `computerId` opens a stealth cloud browser for the real web instead of the browser on that computer. Reuse a saved profile with `create({ profileId })` so logins persist between runs.

## Endpoints

| Endpoint                              | What it does                                            |
| ------------------------------------- | ------------------------------------------------------- |
| `POST /computers` · `GET /computers`  | Create · list                                           |
| `POST /computers/{id}/wake` · `/stop` | Resume · suspend (disk kept)                            |
| `DELETE /computers/{id}`              | Destroy the computer and its disk                       |
| `POST /computers/{id}/exec`           | One command, SSE stream                                 |
| `POST /computers/{id}/fs/*`           | `read` `write` `delete` `move` `copy` `grep` `glob`     |
| `/computers/{id}/terminals`           | Persistent shell sessions (create returns `session_id`) |
| `/computers/{id}/desktop/*`           | Screen capture, input, apps, windows                    |
| `POST /browsers` · `GET /browsers`    | Open a browser (stealth or on a computer) · list        |
| `GET /browsers/{id}`                  | State and `live_view_url`                               |
| `DELETE /browsers/{id}`               | Close the browser                                       |
| `/browsers/{id}/tabs/{tid}/*`         | `nav` `click` `type` `screenshot` `eval` and more       |
| `/browsers/profiles`                  | Ensure · list · delete saved logins and cookies         |

## See also

* [API Reference](/api-reference) - full request and response schemas for every endpoint
* [API keys](/platform/api-keys) - creating and using `kzl_` keys
* [Computers and terminals](/code/computers) - how the AI uses computers inside Kazzle
* [Billing](/platform/billing) - credits and per-minute pricing
