# Machines

GET /v1/agents/machines

Lists the computers on your account.

## Request

```bash
curl -s "$SAI_API_URL/v1/agents/machines" \
  -H "Authorization: Bearer $SAI_API_KEY"
```

## Response

```json
{
  "machines": [
    {
      "machineId": "m_9c1e",
      "name": "Sai cloud computer",
      "updatedAt": 1789990000000,
      "status": "hibernated",
      "canWake": true,
      "kind": "cloud",
      "online": true
    },
    {
      "machineId": "m_7f2a",
      "name": "Work Desktop",
      "updatedAt": 1790000000000,
      "status": "active",
      "canWake": false,
      "kind": "own",
      "online": true
    }
  ]
}
```

| Field       | Notes                                                                                                 |
| ----------- | ----------------------------------------------------------------------------------------------------- |
| `machineId` | Pass as `machineId` on other calls.                                                                   |
| `name`      | The name shown in the Sai app. Absent when the computer has none.                                     |
| `updatedAt` | Unix time in milliseconds of the last status update.                                                  |
| `status`    | The raw machine status string. Absent when unknown. Prefer `online`.                                  |
| `canWake`   | Whether `POST /wake` applies to this computer.                                                        |
| `kind`      | `cloud` (hosted by Simular) or `own` (your desktop app).                                              |
| `online`    | `true` when the computer is `active`, `hibernated` (a message wakes it), or its agent reports online. |

Rows are sorted by name.

## Free accounts

A free account whose computer is not claimed right now sees one synthetic row:

```json
{
  "machines": [
    {
      "machineId": "free-3fA9kQ2xYz",
      "name": "Sai cloud computer (free)",
      "updatedAt": 0,
      "canWake": false,
      "kind": "cloud",
      "online": false
    }
  ]
}
```

`online: false` means the first message will claim and start the computer, which takes about two minutes. While it is claimed, the row is a normal one with the same `machineId`.

> **Note**
>
> `kind`, `online` and the free-account row are available from October 1.

## Create a computer

```
POST /v1/agents/machines
```

Creates a Windows cloud computer for a paid account. It needs a signed-in session: the portal's **Create a cloud computer** button in the [Playground](https://platform.simular.ai/playground) calls it. An API key cannot create a computer, because a computer costs money and is created with the account owner's own checks (plan, payment method, quota, one creation at a time).

Body (optional):

```json
{ "name": "Work PC" }
```

Response `202`:

```json
{
  "taskId": "3f1c…",
  "message": "Creating your computer. It appears in GET /v1/agents/machines within a few minutes."
}
```

Poll `GET /v1/agents/machines` until the new computer is listed with `online: true`, usually within a few minutes.

| Status | `error`                         | When                                                                                       |
| ------ | ------------------------------- | ------------------------------------------------------------------------------------------ |
| `403`  | `session_required`              | Called with an API key. The body carries `createUrl`, the portal page to send the user to. |
| `409`  | `free_plan_computer`            | Free plan. Its computer is the pooled one, started by the first task.                      |
| `429`  | `busy`, or a rate-limit message | A creation is already in progress, or more than 3 in an hour.                              |
| `403`  | `not_billable`                  | The account cannot pay for a computer right now.                                           |

## Live screen

```
POST /v1/agents/machines/:machineId/live
```

Returns a view-only stream of one of your computers' screens: what the [live view](/documentation/coding-agents/live-view) shows. The stream uses [Apache Guacamole](https://guacamole.apache.org/); connect `websocketUrl` with its JavaScript client (`Guacamole.WebSocketTunnel` + `Guacamole.Client`) and draw nothing back.

```bash
curl -s -X POST "$SAI_API_URL/v1/agents/machines/m_9c1e/live" \
  -H "Authorization: Bearer $SAI_API_KEY"
```

Response `200`:

```json
{
  "machineId": "m_9c1e",
  "websocketUrl": "wss://proxy.vm.api.simular.cloud/guacamole/websocket-tunnel?token=…",
  "width": 1920,
  "height": 1080
}
```

`websocketUrl` carries a session token for that computer. Hand it only to your viewer, and get a new one when the stream ends. Split the query string off the URL and pass it to `client.connect()`, because Guacamole appends it itself.

| Status | `error`               | When                                                                         |
| ------ | --------------------- | ---------------------------------------------------------------------------- |
| `404`  |                       | The computer is not yours. A free account may use its own `free-…` computer. |
| `409`  | `machine_not_running` | The computer is asleep or starting. Retry while a task runs.                 |
| `502`  | `live_unavailable`    | The stream could not be set up. Retry later.                                 |
| `429`  |                       | More than 120 requests in an hour.                                           |
