# Computers

Source: https://heaven.dev/docs/computers

A Computer is a persistent Linux machine with root access. It runs in a pool and shares the pool's CPU and memory.

Read Computers with `GET /v1/computer/`, and create and delete them with `/create` and `/delete`. Change one with `POST /v1/computer/modify`, naming the `computer` and one `action`. Each section below is one read or action.

> **Several at once.** `start`, `stop`, `restart`, `pause`, `resume`, `move`, `tag`, `comment`, `transfer`, `share add`, `share remove`, `snapshot create` and `snapshot delete` take `computers` instead of `computer`. Heaven checks every name first, so a typo changes nothing. The response is HTTP 200 with one result per Computer, either an operation or an error, even when some fail. Each Computer counts against the [rate limit](https://heaven.dev/docs/errors#rate-limits).

## Read

### List or get Computers

`GET /v1/computer/`

Lists the Computers you can see, or returns one Computer with its recent operations and every part of it you can read.

The parts of one Computer are `access`, `domains`, `ports`, `mail` and `snapshots`.

#### Query

- `computer` string: Read this Computer, its recent operations and everything you can read of it.
- `pattern` string: Only names matching this pattern, such as web-*.
- `group` string: Group the list by pool, tag, access, or (with `organization`) user.
- `organization` string: Act in this organization (its name or ID) instead of your personal account.

#### Each Computer in the list

- `id`, `name` string: Its ID and name.
- `pool`, `pool_id` string: Its pool's name (when the pool is in an account you belong to) and ID.
- `state` string: `creating`, `preparing_image`, `starting`, `running`, `checking`, `degraded`, `restarting`, `resetting`, `stopping`, `stopped`, `paused`, `failed`, `image_failed`, `held`, `deleting` or `unknown`.
- `state_message` string: The state in a sentence, with the next step when there is one. Show this to people rather than working it out from `status`.
- `access` string: Your role on it: `owner`, `admin`, `root` or `web`.
- `ssh_dest` string: The address for `ssh` and `scp`, such as `my-site@heaven.dev`.
- `url` string: Its website: `https://my-site.heaven.dev`.
- `size` object: `vcpus`, `memory_mib` and `disk_bytes`.
- `image`, `tags`: The image it was made from, and its tags.
- `memory_message` string: Where its memory is now, such as "Asleep, 40 MB in RAM; the first request takes a moment." Present only while it's running and was measured recently.
- `processors_message` string: How many of its vCPUs it can use while its server is busy. Absent otherwise.

When you read one Computer with `computer`, the response's `computer` is its whole view:

- its record, `computer`, with `id`, `name`, `pool_id`, `image`, `tags`, `comment`, its network address and its creation time;
- `owner_id`, `account_id`, `status`, `disk` and `usage`;
- `ssh_dest` and its parts, `ssh_host` (port 22) and `ssh_user`;
- `tier`, which says where its memory is: `active`, `idle` or `asleep`.

- An API key needs `view` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

200 The list:

```json
{
  "version": 1,
  "data": {
    "computers": [
      {
        "id": "7cd4a3ec-7411-402c-b74b-43f6d7587ae7",
        "name": "my-site",
        "pool": "web",
        "pool_id": "pool-832036a4f8a142bf",
        "state": "running",
        "state_message": "Running.",
        "memory_message": "Asleep, 40 MB in RAM; the first request takes a moment.",
        "access": "owner",
        "ssh_dest": "my-site@heaven.dev",
        "url": "https://my-site.heaven.dev",
        "size": { "vcpus": 2, "memory_mib": 4096, "disk_bytes": 20000000000 },
        "image": "heaven-ubuntu",
        "tags": ["web"]
      }
    ]
  }
}
```

200 One Computer: `?computer=my-site`:

```json
{
  "version": 1,
  "data": {
    "computer": {
      "computer": { "id": "7cd4a3ec-…", "name": "my-site", … },
      "owner_id": "a308210e-005c-43ba-b452-db81b4034d90",
      "account_id": "ee225ef4-b631-45d3-b876-49f542ed0809",
      "access": "owner",
      "state": "running",
      "state_message": "Running.",
      "ssh_dest": "my-site@heaven.dev",
      "ssh_host": "heaven.dev",
      "ssh_user": "my-site",
      "url": "https://my-site.heaven.dev",
      …
    },
    "operations": [
      {
        "id": "7bbd53b7-8a68-4f61-a03f-db54072e591d",
        "kind": "restart",
        "state": "complete",
        "created_at": "2026-11-01T23:25:02Z",
        "completed_at": "2026-11-01T23:25:19Z"
      }
    ],
    "access": {…},
    "domains": [],
    "ports": {…},
    "mail": {
      "receiving_enabled": true,
      "reply_policy": "all",
      "sending_suspended": false
    },
    "snapshots": {…}
  }
}
```

### Read usage

`GET /v1/computer/?view=usage`

Returns a Computer's CPU, memory, disk and network use over 24 hours, 7 days or 30 days.

#### Query

- `computer` string *required*: A Computer: its name or ID.
- `range` string: The span of history: 24h (the default), 7d or 30d.
- `resolution` string: A point every minute (1m), five minutes (5m) or hour (1h), over any `range`; it wins over `points`. Without it, 24h has a point every 5 minutes and 7d and 30d one an hour.
- `points` string: At most this many points in the series, but never fewer than one a day: its intervals are merged into the narrowest step that fits (a minute up to a day), so 30d returns 30 points for any N below 30. Without it or `resolution`, 24h has a point every 5 minutes and 7d and 30d one an hour; MCP tools ask for 24.

- An API key needs `usage` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?computer=my-site&view=usage' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Read the boot console

`GET /v1/computer/?view=logs`

Returns a Computer's boot console, for the current boot or the one before.

#### Query

- `computer` string *required*: A Computer: its name or ID.
- `previous` boolean: The boot before the current one.

- An API key needs `logs` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?computer=my-site&view=logs' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Open the browser terminal

`GET /v1/computer/?view=terminal`

Returns a link to a Computer's terminal in the browser.

The link is in `url`. It opens only in a browser signed in to Heaven. Programs use [exec](https://heaven.dev/docs/exec) or SSH instead.

#### Query

- `computer` string *required*: A Computer: its name or ID.

- An API key needs `terminal` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?computer=my-site&view=terminal' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Open the desktop

`GET /v1/computer/?view=desktop`

Returns a link to a Computer's desktop in the browser. Only its owner and people with root access can open it.

#### Query

- `computer` string *required*: A Computer: its name or ID.

- An API key needs `desktop` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?computer=my-site&view=desktop' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Read who has access

`GET /v1/computer/?view=access`

Returns who can reach a Computer and its website.

The response lists its shares, invitations, links, domains and ports, and says whether its website is public.

#### Query

- `computer` string *required*: A Computer: its name or ID.

- An API key needs `access` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?computer=my-site&view=access' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

## Create and delete

### Create a Computer

`POST /v1/computer/create`

Creates a Computer in a pool from an image, or as a copy of a Computer or one of its snapshots.

A Computer uses its pool's CPU, memory and storage, so you don't need to size it. It returns an operation at once, and the Computer is ready when its `state` is `running`.

#### Body

- `name` string: Its name, which becomes `NAME.heaven.dev`. Without one, Heaven picks a free adjective-noun name, such as `swift-otter`. The answer's `name` says which.

- `pool` string: The pool it runs in. Required unless you have exactly one.

- `image` string: Any OCI image, such as `debian:12` or `ghcr.io/you/app:latest`. Defaults to Heaven's Ubuntu.

- `registry_auth` string: `USERNAME:PASSWORD` for a private image's registry.

- `integrations` string[]: Integrations to attach to it.

- `github` object

  `{"repo": "OWNER/REPO"}` clones that repository into the home directory at first boot, before your setup script. It uses a [GitHub integration](https://heaven.dev/docs/integrations#github) you can attach that reaches OWNER. If the clone keeps failing for a minute, setup stops there, but the Computer stays.

  - `repo` string *required*: A GitHub repository (OWNER/REPO) to clone into the Computer, through your GitHub integration.

- `setup_script` string: A script run once at first boot, up to 10 KiB. Without one, your [default](https://heaven.dev/docs/account#defaults) runs. A [pool's setup script](https://heaven.dev/docs/pools#defaults) runs first either way.

- `env` string[]: Environment variables for the setup script, such as `["PORT=8000"]`.

- `tags` string[]: Tags to group, filter and attach integrations by.

- `comment` string: A note for people.

- `cpu` string: vCPUs of its own, within its pool's, as `resize` gives. Without it, the Computer can use the whole pool.

- `memory` string: Memory of its own, such as `8GiB`, within its pool's. Without it, the Computer can use the whole pool.

- `disk` string: A disk of its own, such as 20GB, up to the pool's storage. By default, it shares the pool's storage, or takes the pool's default disk.

- `copy` object

  `{"computer": "NAME"}` copies a Computer's disk. Add `"snapshot"` to copy one of its snapshots instead. A copy takes no `image`, `setup_script`, `env`, `tags` or `comment`. Copying a disk needs root access or ownership. Copying a snapshot needs ownership, or a pool snapshot shared with you. The copy must be made in a pool on the source's server, or it's refused (`conflict`). A copy from a shared snapshot names your `pool` and keeps none of the source's tags.

  - `computer` string *required*: Make a copy of this Computer (or, with `snapshot`, of one of its snapshots).
  - `snapshot` string: Copy this snapshot of it.

- `copy_tags` boolean: Whether a copy keeps the source's tags. Defaults to `true`.

- `organization` string: Act in this organization (its name or ID) instead of your personal account.

- `wait` boolean or string: Wait until it finishes and return how it ended: `true` waits up to 10m, a duration such as `2m` waits that long.

- An API key needs `create` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/create \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{
    "name": "my-site",
    "pool": "web",
    "setup_script": "apt-get install -y nginx",
    "tags": ["web"]
  }'
```

200:

```json
{
  "version": 1,
  "data": {
    "request_id": "f4515dc8-125c-45d4-9000-fcb344896108",
    "operation": {
      "id": "8540e6f2-9f39-4d39-89b5-eeac80d0ac97",
      "kind": "create",
      "computer_id": "0098166a-9908-43ab-967b-4111c45c3b33",
      "revision": 1,
      "state": "accepted"
    },
    "name": "my-site",
    "ssh_dest": "my-site@heaven.dev",
    "url": "https://my-site.heaven.dev"
  }
}
```

Copy a snapshot:

```json
{"name": "my-site-test", "copy": {"computer": "my-site", "snapshot": "before-upgrade"}}
```

### Delete Computers

`POST /v1/computer/delete`

Deletes Computers with their disks and snapshots, at once. Heaven's operators can restore one from backups for 7 days.

You can't undo a delete yourself. Heaven checks every name before anything is deleted, so a typo deletes nothing. Each Computer gets its own result, either an operation or an error.

#### Body

- `computers` string[] *required*: The Computers to delete, by name or ID, any number. Use `computer` to name just one.

- An API key needs `delete` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/delete \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"computers": ["my-site", "my-api"]}'
```

200:

```json
{
  "version": 1,
  "data": {
    "request_id": "05576c57-a681-4949-b029-47b5cf175489",
    "results": [
      {
        "computer": { "id": "7cd4a3ec-…", "name": "my-site" },
        "operation": {
          "id": "95ea2943-c2d2-4468-97c4-80c56fe47337",
          "kind": "delete",
          "state": "accepted"
        }
      }
    ]
  }
}
```

## Power

**Paused Computers.** `start` doesn't continue a paused Computer. It returns `conflict` and suggests `resume`. While a Computer is paused, `move`, `resize`, `snapshot restore`, [`exec`](https://heaven.dev/docs/exec) with its downloads and uploads, and the browser terminal are refused the same way. Its clock stands still until it resumes. `stop` and `restart` still work.

`pause_reason` says why it's paused: `requested`, `storage_limit`, `host_storage_full`, `disk_error` or `host`. If its server loses its memory, the operation fails with `memory_lost`, the Computer reads `stopped`, and `start` boots it fresh.

### Start a Computer

`POST /v1/computer/modify` with `"action": "start"`

Starts a stopped Computer. A running one is left as it is.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `wait` boolean or string: Wait until it finishes and return how it ended: `true` waits up to 10m, a duration such as `2m` waits that long.

- An API key needs `start` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "start", "computer": "my-site"}'
```

### Stop a Computer

`POST /v1/computer/modify` with `"action": "stop"`

Shuts a Computer down and keeps it off. Its disk, address and settings stay.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `wait` boolean or string: Wait until it finishes and return how it ended: `true` waits up to 10m, a duration such as `2m` waits that long.

- An API key needs `stop` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "stop", "computer": "my-site"}'
```

### Restart a Computer

`POST /v1/computer/modify` with `"action": "restart"`

Restarts a Computer, or starts a stopped one. Its disk and settings stay.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `wait` boolean or string: Wait until it finishes and return how it ended: `true` waits up to 10m, a duration such as `2m` waits that long.

- An API key needs `restart` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "restart", "computer": "my-site"}'
```

200:

```json
{
  "version": 1,
  "data": {
    "request_id": "c44821a3-a72c-44d6-bf5e-c388d18265c3",
    "operation": {
      "id": "7bbd53b7-8a68-4f61-a03f-db54072e591d",
      "kind": "restart",
      "computer_id": "7cd4a3ec-7411-402c-b74b-43f6d7587ae7",
      "revision": 2,
      "state": "accepted"
    }
  }
}
```

Restart several:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "restart", "computers": ["my-site", "my-shop"]}'
```

200:

```json
{
  "version": 1,
  "data": {
    "results": [
      {
        "computer": {"id": "8f2a8286-7123-4a64-874f-23a1c2bc61a0", "name": "my-site"},
        "operation": {"id": "dd4ccc4f-6ff5-44a8-8812-3142d067ba6f", "kind": "restart", "state": "accepted", …}
      },
      {
        "computer": {"id": "0d4e03b1-862f-4012-b14d-d7ffda5273c4", "name": "my-shop"},
        "operation": {"id": "8fa85d89-f289-404e-91c9-a1a14dab1fcc", "kind": "restart", "state": "accepted", …}
      }
    ],
    "request_id": "f42ab1d8-0af8-4418-abfc-6d85f07b4a62"
  }
}
```

### Pause a Computer

`POST /v1/computer/modify` with `"action": "pause"`

Freezes a Computer where it is, keeping its memory and processes.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.

- An API key needs `pause` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "pause", "computer": "my-site"}'
```

### Resume a Computer

`POST /v1/computer/modify` with `"action": "resume"`

Continues a paused Computer where it was, in the same boot.

Its memory and processes come back as they were, within milliseconds.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.

- An API key needs `resume` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "resume", "computer": "my-site"}'
```

### Reinstall a Computer

`POST /v1/computer/modify` with `"action": "reset"`

Replaces a Computer's disk with a fresh one from its image and runs its setup again. Without `yes`, it only shows what would be erased.

With a new `setup_script`, the pool's current script runs first. Without one, the setup it was created with runs again.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `image` string: Reinstall from this image instead of its own.
- `setup_script` string: Run this setup script instead of its own; it becomes its own, which later resets run. Or - to read it from standard input. Treated as a secret and never included in errors.
- `yes` boolean: Confirm. Without it nothing changes, and the response says what would happen.
- `wait` boolean or string: Wait until it finishes and return how it ended: `true` waits up to 10m, a duration such as `2m` waits that long.

- An API key needs `reset` in its commands.
- A key whose commands allow it must also allow `delete`.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "reset", "computer": "my-site"}'
```

## Name, pool and size

### Rename a Computer

`POST /v1/computer/modify` with `"action": "rename"`

Gives a Computer a new name. Its address, SSH login and mail address follow at once; its ID and disk stay.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `name` string *required*: Its new name.

- An API key needs `rename` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "rename", "computer": "my-site", "name": "my-shop"}'
```

### Move a Computer

`POST /v1/computer/modify` with `"action": "move"`

Moves a Computer to another of your pools on the same server. A running one restarts there.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `pool` string *required*: The pool to move it to, on the same server.
- `yes` boolean: Confirm. Without it nothing changes, and the response says what would happen.

- An API key needs `move` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "move", "computer": "my-site", "pool": "web-2"}'
```

### Resize a Computer

`POST /v1/computer/modify` with `"action": "resize"`

Gives a Computer its own vCPUs, memory or a larger disk, within its pool's, or returns it to sharing the pool's.

The Computer doesn't restart.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `cpu` string: vCPUs of its own, within its pool's, or pool to use the pool's again.
- `memory` string: Memory of its own, such as 8GiB, within its pool's, or pool to use the pool's again.
- `disk` string: A larger disk of its own, such as 50GB, up to the pool's storage; a disk only grows.
- `wait` boolean or string: Wait until it finishes and return how it ended: `true` waits up to 10m, a duration such as `2m` waits that long.

- An API key needs `resize` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "resize", "computer": "my-site", "memory": "8GB"}'
```

### Tag a Computer

`POST /v1/computer/modify` with `"action": "tag"`

Adds tags to a Computer, or takes them off.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `tags` string[]: Tags to add; commas also separate them.
- `remove` string[]: A tag to take off.

- An API key needs `tag` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "tag", "computer": "my-site", "tags": ["web"]}'
```

### Comment on a Computer

`POST /v1/computer/modify` with `"action": "comment"`

Replaces a Computer's comment. An empty one clears it.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `comment` string *required*: The new comment, one line of at most 200 bytes; an empty one clears it.

- An API key needs `comment` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "comment", "computer": "my-site", "comment": "COMMENT"}'
```

## Snapshots

A snapshot saves the disk as it is, while the Computer keeps running. Snapshots live on the same server, so they're an undo button, not a backup. To keep a copy elsewhere, [export the disk](https://heaven.dev/docs/exec#export).

If copies were made from a snapshot you delete, Heaven keeps it until those copies are deleted, and it counts toward its pool's storage. `?view=snapshots` lists it with `kept_by_computers`, and `kept_by_other_copies` counts copies in other accounts.

### List snapshots

`GET /v1/computer/?view=snapshots`

Lists the snapshots of all your Computers or of one, or returns everything about one snapshot.

#### Query

- `computer` string: Only this Computer's snapshots.
- `snapshot` string: Read this snapshot in full.
- `sort` string: Sort by size instead of newest first.

- An API key needs `snapshot view` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?view=snapshots' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Snapshot a Computer

`POST /v1/computer/modify` with `"action": "snapshot create"`

Saves a Computer's disk as it is now. A snapshot expires after 7 days unless you set another expiry.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `name` string: The snapshot's name: letters, digits and hyphens. Defaults to the time.
- `note` string: A note, one line of at most 200 bytes; an empty one clears it.
- `expires` string: How long it is kept: 1d to 365d, or never (default 7d).

- An API key needs `snapshot create` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "snapshot create", "computer": "my-site"}'
```

### Change a snapshot

`POST /v1/computer/modify` with `"action": "snapshot edit"`

Renames a snapshot or changes its note or expiry.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `snapshot` string *required*: A snapshot: its name or ID.
- `name` string: A new name for the snapshot.
- `note` string: A note, one line of at most 200 bytes; an empty one clears it.
- `expires` string: How long it is kept: 1d to 365d, or never (default 7d).

- An API key needs `snapshot edit` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "snapshot edit", "computer": "my-site", "snapshot": "before-upgrade"}'
```

### Restore a snapshot

`POST /v1/computer/modify` with `"action": "snapshot restore"`

Returns a Computer's disk to a snapshot and starts it.

The current disk is saved first, so a restore can be undone.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `snapshot` string *required*: A snapshot: its name or ID.

- An API key needs `snapshot restore` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "snapshot restore", "computer": "my-site", "snapshot": "before-upgrade"}'
```

### Delete snapshots

`POST /v1/computer/modify` with `"action": "snapshot delete"`

Deletes one or more snapshots.

You can delete up to 100 at once.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `snapshots` string[] *required*: The snapshots to delete: names or IDs.

- An API key needs `snapshot delete` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "snapshot delete", "computer": "my-site", "snapshots": ["before-upgrade"]}'
```

## Sharing

Share a Computer with people by email or ID, with a `team` of your organization, or with the whole organization (`whole_organization: true`). A role decides what they get:

- **`web`** (the default): the website only.
- **`root`**: the website, plus SSH, the terminal, `exec` and files.
- **`admin`**: everything `root` gets, plus the owner's changes, including `delete` and `reset`. It excludes transferring, sharing, `website` and support access.

A team's admins own the Computers the team owns. The organization's billing owner and admins own the organization's Computers. Other members reach those only through a share, or as the team's `member-access` setting allows.

### Share a Computer

`POST /v1/computer/modify` with `"action": "share add"`

Gives people, a team or the whole organization access to a Computer, as web, root or admin.

Someone without an account gets an invitation, valid for 30 days, that their first sign-in accepts. The response is the share as it now stands.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `users` string[]: A person: email address or user ID.
- `team` string: One of your organization's teams.
- `whole_organization` boolean: Everyone in your organization.
- `role` string: web (the default: the website only), root (SSH and the website) or admin (also manage it).
- `commands` string[]: Management commands on top of the role, such as `restart` or `domain add`. It can't include `exec`, `terminal`, `logs`, `export`, `transfer`, sharing, `website` or `grant-support-root`.
- `message` string: Text sent with the email invitation, at most 500 bytes.

- API keys you create can't run it. Use a sign-in key or SSH.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "share add", "computer": "my-site", "users": ["ada@example.com"], "role": "root"}'
```

### Stop sharing a Computer

`POST /v1/computer/modify` with `"action": "share remove"`

Removes someone's access, or lowers their role.

With `role`, they keep that lesser role instead of losing access.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `users` string[]: A person: email address or user ID.
- `team` string: A team it is shared with.
- `whole_organization` boolean: Everyone in your organization.
- `role` string: Leave them this lesser role instead of nothing.

- An API key needs `share remove` in its commands.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "share remove", "computer": "my-site"}'
```

### Create a share link

`POST /v1/computer/modify` with `"action": "share link add"`

Creates a link that gives web access to a Computer.

The link is shown once, as `url`.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `label` string: A label to recognize it by.
- `expires` string: How long the link works: up to 365d, or never (default 30d).
- `max_uses` string: How many people can claim it.

- API keys you create can't run it. Use a sign-in key or SSH.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "share link add", "computer": "my-site"}'
```

### Remove a share link

`POST /v1/computer/modify` with `"action": "share link remove"`

Removes a link that gives web access to a Computer.

Nobody new can claim the link. People who already claimed it keep access until you remove them with `share remove`.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `link` string *required*: The link's ID (see `access`).

- An API key needs `share link remove` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "share link remove", "computer": "my-site", "link": "LINK"}'
```

### Transfer a Computer

`POST /v1/computer/modify` with `"action": "transfer"`

Gives a Computer in your organization to a member, a team or the organization itself. Its shares are cleared, unless `keep_shares` keeps those the new owner could make.

#### Body

- `computer` string: A Computer: its name or ID.
- `computers` string[]: Several Computers at once, instead of `computer`.
- `user` string: The member who gets it.
- `team` string: The team that gets it.
- `whole_organization` boolean: The organization itself gets it.
- `keep_shares` boolean: Keep shares with people, teams and the organization that the new owner could make themselves; without it, shares are cleared.
- `pool` string: A pool: its name or ID.

- API keys you create can't run it. Use a sign-in key or SSH.
- Give `computers` instead of `computer` to act on several at once.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "transfer", "computer": "my-site"}'
```

### Give support root access

`POST /v1/computer/modify` with `"action": "grant-support-root"`

Gives Heaven's operators root access to a Computer, or takes it back.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `state` string *required*: on gives Heaven's operators root access, and off takes it away.

- An API key needs `grant-support-root` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "grant-support-root", "computer": "my-site", "state": "STATE"}'
```

## Website, domains and ports

Every Computer serves a website at `https://NAME.heaven.dev`, from the port its image exposes. The website is private, open only to people with access, until you make it public.

To give a Computer one of your [static addresses](https://heaven.dev/docs/account#static-addresses) (not offered yet) for all its traffic in and out, use `ip attach` with `computer`. `ip detach` takes it off.

### Set who reaches the website

`POST /v1/computer/modify` with `"action": "website"`

Makes a Computer's website public or private, and sets the port it is served from. With neither, returns the current settings.

It returns the website's settings: `computer`, `url`, `public`, `port`, and `default_port`, which is the port the image exposes.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `public` boolean: With `true`, anyone can visit. With `false`, only people with access can.
- `port` string: The port the website is served from. `0` goes back to the image's port.

- An API key needs `website` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "website", "computer": "my-site"}'
```

200 With `"public": true`:

```json
{
  "version": 1,
  "data": {
    "updated": true,
    "computer": "my-site",
    "url": "https://my-site.heaven.dev/",
    "public": true,
    "port": 0,
    "default_port": 8080
  }
}
```

### List domains

`GET /v1/computer/?view=domains`

Lists the verified website domains of all your Computers, or of one.

#### Query

- `computer` string: A Computer: its name or ID.

- An API key needs `domain view` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?view=domains' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Add a domain

`POST /v1/computer/modify` with `"action": "domain add"`

Serves a Computer's website at your own domain. The domain's DNS must point at the Computer and have its verification record.

Before you add the domain, point its DNS at `NAME.heaven.dev`, and add a `_heaven.DOMAIN` TXT record holding `heaven=COMPUTER_ID`. If a record is missing, the error names it.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `domain` string *required*: A domain name you control, such as www.example.com.
- `wildcard` boolean: Also serve every name under the domain (*.DOMAIN).

- An API key needs `domain add` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "domain add", "computer": "my-site", "domain": "shop.example.com"}'
```

### Remove a domain

`POST /v1/computer/modify` with `"action": "domain remove"`

Stops serving a Computer's website at one of your domains.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `domain` string *required*: A domain name you control, such as www.example.com.

- An API key needs `domain remove` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "domain remove", "computer": "my-site", "domain": "shop.example.com"}'
```

### List public ports

`GET /v1/computer/?view=ports`

Lists the public TCP ports of all your Computers or of one, and each pool's allowance.

#### Query

- `computer` string: A Computer: its name or ID.

- An API key needs `port view` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?view=ports' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Publish a port

`POST /v1/computer/modify` with `"action": "port add"`

Publishes one of a Computer's TCP ports to the internet, at a public port Heaven picks.

It returns the public port as `address`: `ADDRESS:PORT` on a static address, or `NAME.heaven.dev:PORT` otherwise.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `guest_port` string *required*: The Computer's TCP port to publish.

- API keys you create can't run it. Use a sign-in key or SSH.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "port add", "computer": "my-site", "guest_port": "GUEST_PORT"}'
```

### Close a port

`POST /v1/computer/modify` with `"action": "port remove"`

Closes a public TCP port. Name either the public port or the Computer's port.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `port` string *required*: The public port, or the Computer's port it publishes.

- An API key needs `port remove` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "port remove", "computer": "my-site", "port": "PORT"}'
```

## Email

### Read mail settings

`GET /v1/computer/?view=mail`

Returns whether a Computer receives mail, and whom it can send mail to.

#### Query

- `computer` string *required*: A Computer: its name or ID.

- An API key needs `mail view` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?computer=my-site&view=mail' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```

### Set mail

`POST /v1/computer/modify` with `"action": "mail"`

Turns receiving mail at the Computer's address on or off, and sets whom the Computer can send mail to.

A Computer receives mail at `NAME.heaven.dev`. It sends mail from inside itself through Heaven's mail API, with no credential:

Inside the Computer:

```sh
curl http://169.254.169.254/gateway/email/send \
  -H 'Content-Type: application/json' -H 'Idempotency-Key: build-123' \
  -d '{"to":"alex@example.com","subject":"Build complete","body":"All green."}'
curl http://169.254.169.254/gateway/email/status/OPERATION_ID
```

Sending returns an operation ID once the message is accepted. If the response is lost, send it again with the same `Idempotency-Key`, never a new one. The message's status goes from `queued` through `provider_accepted` to `delivered`, or ends as `refused`, `expired` or `unknown`. `reply_policy` decides whom the Computer can send to, and mail to anyone else is refused.

#### Body

- `computer` string *required*: A Computer: its name or ID.
- `state` string: With on, receive mail at NAME@ the domain. With off, refuse mail, and permanently delete its reply threads and unsubscribe everyone allowed to write to it.
- `reply_policy` string: Whom the Computer can send mail to: `all` (the default: its owner, team members, those given access, and people who wrote to it while it receives mail), `known` (its owner, team members and those given access), `owner` (its owner only) or `none` (it sends no mail).
- `yes` boolean: Confirm turning mail off when that deletes reply threads or subscriptions. Without it, off changes nothing and says what it would remove.

- An API key needs `mail` in its commands.

Request:

```sh
curl https://heaven.dev/v1/computer/modify \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"action": "mail", "computer": "my-site"}'
```

### Read a message's delivery

`GET /v1/computer/?operation=…`

Returns whether a message a Computer sent was delivered, using the ID returned when it was sent.

#### Query

- `computer` string *required*: A Computer: its name or ID.
- `operation` string *required*: The ID returned when the Computer sent it.

- An API key needs `mail status` in its commands.

Request:

```sh
curl 'https://heaven.dev/v1/computer/?computer=my-site&operation=OPERATION' \
  -H "Authorization: Bearer $HEAVEN_API_KEY"
```
