> Documentation index: https://docs.kiste.run/llms.txt, a list of every page in this documentation.

# Kisten

> Create, read, change and delete Kisten. In the API a Kiste is an instance, addressed by its name.

Create, read, change and delete Kisten. In the API a Kiste is an instance, addressed by its name.

## List Kisten

`GET /v1/instances`

Every Kiste of your account, newest first, in the list shape `{object, data, first_id, last_id, has_more}`.

```bash
curl -sS "https://kiste.run/v1/instances" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` OK. Body: list of [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Create a Kiste

`POST /v1/instances`

Creates a Kiste and starts it. The answer arrives once the machine accepts SSH and commands; the desktop keeps starting in the background for a few more seconds. `ssh_public_key` is the key the Kiste trusts besides your account's device keys. Without `ttl_seconds` the Kiste runs until it is stopped. Plan and account limits are checked first: `L02` (number of Kisten), `L03` (running at once), `L04` (disk), `L13` (no free capacity right now, retry later).

```bash
curl -sS -X POST "https://kiste.run/v1/instances" \
  -H "Authorization: Bearer $KISTE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"review-42","profile":"desktop","vcpu":4,"memory_mib":8192,"disk_mib":81920,"ssh_public_key":"ssh-ed25519 AAAA... you@laptop","ttl_seconds":3600}'
```

**Request body:** [CreateInstanceRequest](https://docs.kiste.run/api/schemas.md#createinstancerequest)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `auto_snapshot_seconds` | integer (int32) or null | no | How often a changed disk is checkpointed, 60–86400 seconds (default 300). Automatic checkpoints are always on; only the interval is configurable. |
| `disk_mib` | integer (int32) | yes | Disk size in MiB (default shape: 81920). |
| `environment` | string or null | no | An environment by name; its current version is applied. |
| `image` | string or null | no | A custom image by ID, slug or name; the universal image when omitted. |
| `memory_mib` | integer (int32) | yes | Memory in MiB (default shape: 8192). |
| `name` | string or null | no | Name of the new Kiste; generated when omitted. |
| `profile` | [InstanceProfile](https://docs.kiste.run/api/schemas.md#instanceprofile) | yes | Machine profile; `desktop`. |
| `ssh_public_key` | string | yes | An SSH public key the Kiste trusts, in addition to your account's device keys. |
| `ttl_seconds` | integer (int32) or null | no | Lifetime in seconds; when it ends the Kiste stops cleanly (its disk stays). Without it the Kiste runs until it is stopped. |
| `vcpu` | integer (int32) | yes | Number of vCPUs, within your account's limits (default shape: 4). |

**Responses:**

- `200` OK. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Get a Kiste

`GET /v1/instances/{name}`

One Kiste by name: its state, size, image version, lifetime, checkpoint times and whether a saved session is waiting.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS "https://kiste.run/v1/instances/review-42" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` OK. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Delete a Kiste

`DELETE /v1/instances/{name}`

Permanently deletes the Kiste and its disk. Its named snapshots stay until you delete them. Answers `202` when the deletion is still running after 20 seconds; the `instance.deleted` event marks its end.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X DELETE "https://kiste.run/v1/instances/review-42" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` Finished. Body: [MessageResponse](https://docs.kiste.run/api/schemas.md#messageresponse)
- `202` Still running; the body is the state as it is now, the end is an event. Body: [MessageResponse](https://docs.kiste.run/api/schemas.md#messageresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Stop a Kiste

`POST /v1/instances/{name}/stop`

Shuts the Kiste down; its disk stays and a stopped Kiste uses no compute. With `{"snapshot": true}` the memory is saved as well, so the next start resumes the session in about a second. Long stops answer `202` with the current state; `instance.stopped` marks the end.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X POST "https://kiste.run/v1/instances/review-42/stop" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Request body (optional):** [StopInstanceRequest](https://docs.kiste.run/api/schemas.md#stopinstancerequest)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `snapshot` | boolean | no | Preserve the running session: writes the memory snapshot so the next start resumes in about a second. Slower to stop. Without it the stop is a clean shutdown and the next start is a fresh boot. |

**Responses:**

- `200` Finished. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)
- `202` Still running; the body is the state as it is now, the end is an event. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Restart a Kiste

`POST /v1/instances/{name}/restart`

Reboots the Kiste from its own disk: files stay, processes start fresh, and a pending image update is applied. A stopped Kiste boots fresh too, and a saved session is dropped; use resume to keep it.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X POST "https://kiste.run/v1/instances/review-42/restart" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` Finished. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)
- `202` Still running; the body is the state as it is now, the end is an event. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Resume a Kiste

`POST /v1/instances/{name}/resume`

Starts a stopped Kiste. When a session was saved with `stop --snapshot` (or by a lifetime ending), it continues exactly where it was; otherwise the Kiste boots from its disk.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X POST "https://kiste.run/v1/instances/review-42/resume" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` Finished. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)
- `202` Still running; the body is the state as it is now, the end is an event. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Rename a Kiste

`POST /v1/instances/{name}/rename`

Gives the Kiste a new name, with the same rules as at creation. The host name inside the Kiste follows at its next update or cold boot. The `instance.renamed` event carries the old name in `data.previous_name`.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X POST "https://kiste.run/v1/instances/review-42/rename" \
  -H "Authorization: Bearer $KISTE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"review-43"}'
```

**Request body:** [RenameInstanceRequest](https://docs.kiste.run/api/schemas.md#renameinstancerequest)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The new Kiste name; same rules as at creation. |

**Responses:**

- `200` OK. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Update a Kiste to the newest image

`POST /v1/instances/{name}/upgrade`

Brings the Kiste onto the image version the platform currently serves, without changing whether it runs. A running Kiste reboots and its session ends; files and installed packages stay. A stopped Kiste stays stopped, its saved session is discarded, and its next start is the update. `GET /v1/runtime/image` has the release notes.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X POST "https://kiste.run/v1/instances/review-42/upgrade" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` Finished. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)
- `202` Still running; the body is the state as it is now, the end is an event. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Extend a Kiste's lifetime

`POST /v1/instances/{name}/extend`

Adds `ttl_seconds` to the Kiste's automatic stop, or sets one that far from now when it has none. When the lifetime ends the Kiste stops and keeps its disk; its session is saved when the guest answers.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X POST "https://kiste.run/v1/instances/review-42/extend" \
  -H "Authorization: Bearer $KISTE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ttl_seconds":3600}'
```

**Request body:** [ExtendInstanceRequest](https://docs.kiste.run/api/schemas.md#extendinstancerequest)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ttl_seconds` | integer (int32) | yes | Seconds added to the Kiste's deadline (or from now when it has none); at the deadline it stops cleanly. |

**Responses:**

- `200` OK. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Fork a Kiste

`POST /v1/instances/{name}/fork`

Copies the disk of a running Kiste into a new, independent Kiste, which boots fresh with its own processes. The copy keeps the source's environment and checkpoint interval but never its automatic stop: give it one with `ttl_seconds`.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS -X POST "https://kiste.run/v1/instances/review-42/fork" \
  -H "Authorization: Bearer $KISTE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"review-42-try","ttl_seconds":14400}'
```

**Request body:** [ForkInstanceRequest](https://docs.kiste.run/api/schemas.md#forkinstancerequest)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `ttl_seconds` | integer (int32) or null | no | The copy's lifetime in seconds (60 to 2592000); without it the copy has no automatic stop (it never inherits the source's deadline). |

**Responses:**

- `200` OK. Body: [InstanceResponse](https://docs.kiste.run/api/schemas.md#instanceresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Read the console log

`GET /v1/instances/{name}/logs`

The boot and console log of the Kiste. `tail` selects the last lines, at most 2000.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

**Query parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `tail` | integer | no | Number of trailing lines, at most 2000. |

```bash
curl -sS "https://kiste.run/v1/instances/review-42/logs" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` OK. Body: [LogsResponse](https://docs.kiste.run/api/schemas.md#logsresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Sample live usage

`GET /v1/instances/{name}/metrics`

One short sample from inside a running Kiste: CPU, memory, disk, load, uptime and the busiest processes. Answers `409` while the Kiste is not running and `429` past 40 samples a minute per account.

**Path parameters:**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | The Kiste's name. |

```bash
curl -sS "https://kiste.run/v1/instances/review-42/metrics" \
  -H "Authorization: Bearer $KISTE_TOKEN"
```

**Responses:**

- `200` OK. Body: [InstanceMetricsResponse](https://docs.kiste.run/api/schemas.md#instancemetricsresponse)

Errors use the [error envelope](https://docs.kiste.run/errors.md#reading-an-error).

## Related topics

- [Overview](https://docs.kiste.run/api.md)
- [Conventions](https://docs.kiste.run/api/conventions.md)
- [Commands](https://docs.kiste.run/api/commands.md)
- [Snapshots](https://docs.kiste.run/api/snapshots.md)
- [SSH and terminal](https://docs.kiste.run/api/ssh-and-terminal.md)
- [Desktop](https://docs.kiste.run/api/desktop.md)
- [Kiste Stream](https://docs.kiste.run/api/stream.md)
- [Images and environments](https://docs.kiste.run/api/images.md)
- [Events, webhooks and alerts](https://docs.kiste.run/api/events.md)
- [Account and access](https://docs.kiste.run/api/account.md)
- [Sign-in and platform](https://docs.kiste.run/api/platform.md)
- [Schemas](https://docs.kiste.run/api/schemas.md)
- Previous: [Conventions](https://docs.kiste.run/api/conventions.md)
- Next: [Commands](https://docs.kiste.run/api/commands.md)
