# Create a computer

> Create a computer in the `workspace` given, with a generated `name` like `bright-anchovy` when omitted.

> Nevia is in beta and open to selected teams. Public launch in Dec 2026. The CLI installs with `curl -fsSL https://get.nevia.cloud | sh`, and the MCP server is at https://api.nevia.cloud/mcp. A person signs in once in the browser.
> Setup, sign-in and requesting access: [SKILL.md](https://nevia.cloud/SKILL.md). When Nevia fits and when it doesn't: [why.md](https://nevia.cloud/why.md).

> For the complete documentation index, see [llms.txt](https://nevia.cloud/llms.txt). This page's HTML version: https://nevia.cloud/docs/reference/api/computers/createComputer

`POST https://api.nevia.cloud/v1/computers`

## Authorization

- `bearerAuth`: HTTP bearer in the Authorization header

Send the token in the `Authorization: Bearer <token>` header. See [Authenticate](https://nevia.cloud/docs/reference/api.md#authenticate).

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string | yes | Retry key. A retry with the same key and body replays the first response. Length `1 <= length <= 255`. |

## Request body

Content type: `application/json`, required

Schema: `ComputerCreateRequest`

Settings for a new computer

| Field | Type | Required | Description |
|---|---|---|---|
| `workspace` | string | yes | Workspace id: 27 lowercase letters and digits. Match `^[A-Za-z0-9_-]{1,64}$`. |
| `name` | string | no | Unique within the workspace per resource kind. Match `^[a-z0-9]([a-z0-9-]*[a-z0-9])?$`. Length `1 <= length <= 63`. |
| `image` | string | no | Image ref from `GET /v1/images` (default: platform image). |
| `ports` | array<PortMapping> | no | Port mappings, each with a unique `published`. Items `items <= 16`. |
| `env` | object | no | Env vars stored on the computer and used by every exec and session. Values can use `{{secrets.NAME}}` or `{{variables.NAME}}` templates. [Computer environment variables](https://nevia.cloud/docs/reference/computer-env.md). |
| `protected` | boolean | no | Default `false`. |
| `from_checkpoint` | string | no | Checkpoint id: 27 lowercase letters and digits. Match `^[A-Za-z0-9_-]{1,64}$`. |

## Behavior

With `from_checkpoint`, the machine restores the checkpoint's snapshot with its image, env and ports. The platform gives each port mapping an HTTPS listener on its assigned hostname. It sets `url` and `ports[].url` once the computer is `ready`.

The API stores `env` and does not send it to the machine. Each exec applies it. The computer's startup process does not see it. Values may be templates: `{{secrets.NAME}}` and `{{variables.NAME}}` name entries in the workspace. Templates resolve by name at each exec, so a secret's value never reaches the control plane. Branches and restores keep the stored env. `PATCH` changes it.

The `computer.create` operation finishes in the `200` response. If the machine does not come up in the short wait, the response is `202`, and the operation keeps running.

## Example request

### cURL

```bash
curl -X POST "https://api.nevia.cloud/v1/computers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: 8f1c2a7e-3b4d-4c5e-9f0a-1b2c3d4e5f60" \
  -H "Content-Type: application/json" \
  -d '{
    "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
    "name": "api-staging",
    "image": "docker.io/library/python:3.13-slim",
    "ports": [
      {
        "published": 8080,
        "target": 8080
      }
    ]
  }'
```

### JavaScript

```js
const body = JSON.stringify({
  "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
  "name": "api-staging",
  "image": "docker.io/library/python:3.13-slim",
  "ports": [
    {
      "published": 8080,
      "target": 8080
    }
  ]
})

fetch("https://api.nevia.cloud/v1/computers", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.TOKEN}`,
    "Idempotency-Key": "8f1c2a7e-3b4d-4c5e-9f0a-1b2c3d4e5f60"
  },
  body
})
```

### Python

```python
import os
import requests

url = "https://api.nevia.cloud/v1/computers"
body = """{
  "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
  "name": "api-staging",
  "image": "docker.io/library/python:3.13-slim",
  "ports": [
    {
      "published": 8080,
      "target": 8080
    }
  ]
}"""
response = requests.request("POST", url, data = body, headers = {
  "Content-Type": "application/json", 
  "Authorization": f"Bearer {os.environ['TOKEN']}", 
  "Idempotency-Key": "8f1c2a7e-3b4d-4c5e-9f0a-1b2c3d4e5f60"
})

print(response.text)
```

## Responses

### 200

The computer, `ready` or `failed`, when it came up within the short wait.

Content type: `application/json`

Schema: `ComputerResponse`

| Field | Type | Required | Description |
|---|---|---|---|
| `computer` | Computer | yes | Computer running an OCI image. |
| `operations` | array<OperationId> | yes | Operations this request started. |

Example:

```json
{
  "computer": {
    "id": "01d4cnjk3xg90y576w8y6t4gdwm",
    "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
    "name": "api-staging",
    "state": "ready",
    "pending": null,
    "image": "docker.io/library/python:3.13-slim",
    "image_digest": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "ports": [
      {
        "published": 8080,
        "target": 8080,
        "protocol": "http1",
        "url": "https://01d4cnjk3xg90y576w8y6t4gdwm.machines.example:8080"
      }
    ],
    "url": "https://01d4cnjk3xg90y576w8y6t4gdwm.machines.example",
    "env_keys": [
      "LOG_LEVEL",
      "OPENAI_KEY"
    ],
    "env_vars": [
      {
        "name": "LOG_LEVEL",
        "source": "literal",
        "missing": false
      },
      {
        "name": "OPENAI_KEY",
        "source": "secret",
        "missing": false
      }
    ],
    "generation": 1,
    "protected": false,
    "parent": null,
    "from_checkpoint": null,
    "error": null,
    "created_at": "2026-09-10T12:34:56Z",
    "last_started_at": "2026-09-10T12:35:12Z",
    "last_active_at": "2026-09-10T12:40:03Z",
    "deleted_at": null
  },
  "operations": [
    "01d4cnjm89yk0r3xtv80dy0x7by"
  ]
}
```

### 202

The computer in `creating`, when it did not come up in time.

Content type: `application/json`

Schema: `ComputerResponse`

| Field | Type | Required | Description |
|---|---|---|---|
| `computer` | Computer | yes | Computer running an OCI image. |
| `operations` | array<OperationId> | yes | Operations this request started. |

Example:

```json
{
  "computer": {
    "id": "01d4cnjk3xg90y576w8y6t4gdwm",
    "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
    "name": "api-staging",
    "state": "ready",
    "pending": null,
    "image": "docker.io/library/python:3.13-slim",
    "image_digest": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "ports": [
      {
        "published": 8080,
        "target": 8080,
        "protocol": "http1",
        "url": "https://01d4cnjk3xg90y576w8y6t4gdwm.machines.example:8080"
      }
    ],
    "url": "https://01d4cnjk3xg90y576w8y6t4gdwm.machines.example",
    "env_keys": [
      "LOG_LEVEL",
      "OPENAI_KEY"
    ],
    "env_vars": [
      {
        "name": "LOG_LEVEL",
        "source": "literal",
        "missing": false
      },
      {
        "name": "OPENAI_KEY",
        "source": "secret",
        "missing": false
      }
    ],
    "generation": 1,
    "protected": false,
    "parent": null,
    "from_checkpoint": null,
    "error": null,
    "created_at": "2026-09-10T12:34:56Z",
    "last_started_at": "2026-09-10T12:35:12Z",
    "last_active_at": "2026-09-10T12:40:03Z",
    "deleted_at": null
  },
  "operations": [
    "01d4cnjm89yk0r3xtv80dy0x7by"
  ]
}
```

### 400

`validation_failed`: malformed body, unknown field, or invalid id or name. Fix `details.field` and retry. `validation_failed`: `env` names a secret or variable that does not exist in the workspace.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `validation_failed: malformed body, unknown field, or invalid id or name. Fix \`details.field\` and retry`:

```json
{
  "error": {
    "code": "validation_failed",
    "message": "Unknown field `colour` in the request body. Remove it; request bodies are strict.",
    "details": {
      "field": "colour",
      "in": "body"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

Example `validation_failed: \`env\` names a secret or variable that does not exist in the workspace`:

```json
{
  "error": {
    "code": "validation_failed",
    "message": "Invalid `env.OPENAI_KEY` in the request body: secret `OPENAI_KEY` does not exist in workspace 01d4cnjjq40hnnh0nwmkg35nv2h. List them with GET /v1/secrets?workspace=01d4cnjjq40hnnh0nwmkg35nv2h.",
    "details": {
      "field": "env.OPENAI_KEY",
      "in": "body"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 401

`unauthorized`: the credential is missing, malformed, expired, or revoked. Send a valid bearer token.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `unauthorized`:

```json
{
  "error": {
    "code": "unauthorized",
    "message": "Missing credential. Send `Authorization: Bearer <token>` with an access token.",
    "details": {},
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 403

`forbidden`: the `env` references a secret or variable the caller may not reference. Secrets need the `editor` role or higher in the workspace, variables any role.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `forbidden`:

```json
{
  "error": {
    "code": "forbidden",
    "message": "Referencing workspace secrets needs workspace#edit on workspace 01d4cnjjq40hnnh0nwmkg35nv2h. Ask a workspace admin to change your role.",
    "details": {
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
      "permission": "workspace#edit"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 404

`not_found`: the workspace or the `from_checkpoint` checkpoint does not exist, or the caller cannot see it. Both return the same response.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `not_found`:

```json
{
  "error": {
    "code": "not_found",
    "message": "Checkpoint 01d4cnjkwhftngfp8vkmp723mhv was not found. List a computer's checkpoints with GET /v1/computers/{cmp}/checkpoints.",
    "details": {
      "checkpoint": "01d4cnjkwhftngfp8vkmp723mhv"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 409

`invalid_state`: `from_checkpoint` names a checkpoint that is not `ready`. `name_conflict`: `name` is taken in the workspace. `limit_exceeded`: the beta cap on live computers is reached. `idempotency_conflict`: the `Idempotency-Key` was already used with a different body.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `invalid_state`:

```json
{
  "error": {
    "code": "invalid_state",
    "message": "Checkpoint 01d4cnjkwhftngfp8vkmp723mhv is creating and cannot be restored from. Poll GET /v1/operations/{op} from its create until it finishes, then retry.",
    "details": {
      "checkpoint": "01d4cnjkwhftngfp8vkmp723mhv",
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
      "state": "creating"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

Example `name_conflict`:

```json
{
  "error": {
    "code": "name_conflict",
    "message": "A computer named api-staging already exists in workspace 01d4cnjjq40hnnh0nwmkg35nv2h. Pick another name, or find it with GET /v1/computers?workspace=01d4cnjjq40hnnh0nwmkg35nv2h&name=api-staging.",
    "details": {
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
      "name": "api-staging",
      "list_route": "GET /v1/computers?workspace=01d4cnjjq40hnnh0nwmkg35nv2h"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

Example `limit_exceeded`:

```json
{
  "error": {
    "code": "limit_exceeded",
    "message": "Beta limit reached: 10 of 10 computers. Delete one to create another.",
    "details": {
      "kind": "computer",
      "scope": "user",
      "count": 10,
      "limit": 10
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

Example `idempotency_conflict`:

```json
{
  "error": {
    "code": "idempotency_conflict",
    "message": "Idempotency-Key 8f1c2a7e-3b4d-4c5e-9f0a-1b2c3d4e5f60 was already used for a different POST /v1/computers request. Use a new key for a new request.",
    "details": {
      "idempotency_key": "8f1c2a7e-3b4d-4c5e-9f0a-1b2c3d4e5f60"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 422

`not_supported`: `image` is not a catalog ref or the platform default.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `not_supported`:

```json
{
  "error": {
    "code": "not_supported",
    "message": "Image `docker.io/library/nginx:1.27` is not available during the beta. Choose one from GET /v1/images.",
    "details": {
      "field": "image",
      "in": "body",
      "allowed": [
        "docker.io/library/debian:12-slim",
        "docker.io/library/python:3.13-slim",
        "docker.io/library/node:24-slim",
        "docker.io/library/golang:1.25",
        "docker.io/temporalio/temporal:1.9.1"
      ]
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 423

`operation_in_progress`: a conflicting operation runs. Retry after `Retry-After`, or poll `details.operation_id` for completion.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `operation_in_progress`:

```json
{
  "error": {
    "code": "operation_in_progress",
    "message": "Computer 01d4cnjk3xg90y576w8y6t4gdwm has an operation in progress. Poll GET /v1/operations/01d4cnjm89yk0r3xtv80dy0x7by until it finishes, then retry.",
    "details": {
      "computer": "01d4cnjk3xg90y576w8y6t4gdwm",
      "operation_id": "01d4cnjm89yk0r3xtv80dy0x7by",
      "retry_after_seconds": 2
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 429

`rate_limited`: slow down. Retry after `Retry-After`.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `rate_limited`:

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Retry after 2 seconds.",
    "details": {
      "retry_after_seconds": 2
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 500

`request_failed`, or the failed action's own code, such as `creation_failed`, `authorization_failed` or `command_execution_failed`. Quote `request_id` when reporting. The diagnostic stays in server logs.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `request_failed`:

```json
{
  "error": {
    "code": "request_failed",
    "message": "request failed",
    "details": {},
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 503

The action is temporarily unavailable, named by its code (`creation_failed`, `wake_failed`, ...). Wait at least `Retry-After` seconds (60 by default). `details.retryable` says whether repeating the request is safe. Keep the original `Idempotency-Key`. Signing in again does not help.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

| Field | Type | Required | Description |
|---|---|---|---|
| `error` | Error | yes |  |

Example `creation_failed`:

```json
{
  "error": {
    "code": "creation_failed",
    "message": "The computer could not be created. Try again later, and quote request_id if it persists.",
    "details": {
      "retryable": true
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```
