# Restore a checkpoint

> Restore a checkpoint as a new computer with its captured image, env, ports, size, memory and `/data`.

> 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/checkpoints/restoreComputerCheckpoint

`POST https://api.nevia.cloud/v1/computers/{cmp}/checkpoints/{chk}/restore`

## 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 |
|---|---|---|---|---|
| `cmp` | path | string | yes | Computer id: 27 lowercase letters and digits. Match `^[A-Za-z0-9_-]{1,64}$`. |
| `chk` | path | string | yes | Checkpoint id: 27 lowercase letters and digits. Match `^[A-Za-z0-9_-]{1,64}$`. |
| `Idempotency-Key` | header | string | no | Optional retry key, kept 24 hours. Length `1 <= length <= 255`. |

## Request body

Content type: `application/json`

Schema: `CheckpointRestoreRequest`

| Field | Type | Required | Description |
|---|---|---|---|
| `name` | string | no | Unique within the workspace per resource kind. Match `^[a-z0-9]([a-z0-9-]*[a-z0-9])?$`. Length `1 <= length <= 63`. |

## Behavior

It works like `POST /v1/computers` with `from_checkpoint`, addressed through the checkpoint.

The guest resumes from memory, so processes running at capture keep their env. The stored env is the checkpoint's, resolved by name at each exec of the new computer. A secret or variable deleted since capture fails those execs without blocking the restore.

The `checkpoint.restore` operation finishes before a 200 response. For a 202 response, poll the operation until it finishes.

## Example request

### cURL

```bash
curl -X POST "https://api.nevia.cloud/v1/computers/01d4cnjk3xg90y576w8y6t4gdwm/checkpoints/01d4cnjkwhftngfp8vkmp723mhv/restore" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "api-rollback"
  }'
```

### JavaScript

```js
const body = JSON.stringify({
  "name": "api-rollback"
})

fetch("https://api.nevia.cloud/v1/computers/01d4cnjk3xg90y576w8y6t4gdwm/checkpoints/01d4cnjkwhftngfp8vkmp723mhv/restore", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.TOKEN}`
  },
  body
})
```

### Python

```python
import os
import requests

url = "https://api.nevia.cloud/v1/computers/01d4cnjk3xg90y576w8y6t4gdwm/checkpoints/01d4cnjkwhftngfp8vkmp723mhv/restore"
body = """{
  "name": "api-rollback"
}"""
response = requests.request("POST", url, data = body, headers = {
  "Content-Type": "application/json", 
  "Authorization": f"Bearer {os.environ['TOKEN']}"
})

print(response.text)
```

## Responses

### 200

The new computer, `ready` or `failed`, when the machine 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 new computer in `creating`, when the short wait ran out first.

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.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

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

Example `validation_failed`:

```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"
  }
}
```

### 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 checkpoint's env references a secret and you are not an `editor` or `admin` in the workspace, or a variable and you are not a member.

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 checkpoint does not exist, or you 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`: the checkpoint is not `ready`. `name_conflict`: a computer in the workspace already has the name you sent. `limit_exceeded`: you already hold the beta limit of computers. `invalid_state`: the platform refuses the restore in the checkpoint's current state. `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: the checkpoint is not \`ready\``:

```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-rollback already exists in workspace 01d4cnjjq40hnnh0nwmkg35nv2h. Pick another name, or find it with GET /v1/computers?workspace=01d4cnjjq40hnnh0nwmkg35nv2h&name=api-rollback.",
    "details": {
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
      "name": "api-rollback",
      "list_route": "GET /v1/computers?workspace=01d4cnjjq40hnnh0nwmkg35nv2h"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

Example `limit_exceeded`:

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

Example `invalid_state: the platform refuses the restore in the checkpoint's current state`:

```json
{
  "error": {
    "code": "invalid_state",
    "message": "Computer 01d4cnjk3xg90y576w8y6t4gdwm cannot be restored right now. Check its state with GET /v1/computers/01d4cnjk3xg90y576w8y6t4gdwm and retry.",
    "details": {
      "computer": "01d4cnjk3xg90y576w8y6t4gdwm",
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h"
    },
    "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/{cmp}/checkpoints/{chk}/restore request. Use a new key for a new request.",
    "details": {
      "idempotency_key": "8f1c2a7e-3b4d-4c5e-9f0a-1b2c3d4e5f60"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

### 422

`not_supported`: the workspace has no capacity left for a computer. `not_supported`: the platform does not support restoring the checkpoint.

Content type: `application/json`

Schema: `ErrorEnvelope`

Body of every error response

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

Example `not_supported: the workspace has no capacity left for a computer`:

```json
{
  "error": {
    "code": "not_supported",
    "message": "Workspace 01d4cnjjq40hnnh0nwmkg35nv2h has no capacity left for computer 01d4cnjk3xg90y576w8y6t4gdwm. Quote request_id when reporting.",
    "details": {
      "computer": "01d4cnjk3xg90y576w8y6t4gdwm",
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h"
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```

Example `not_supported: the platform does not support restoring the checkpoint`:

```json
{
  "error": {
    "code": "not_supported",
    "message": "This request is not supported for computer 01d4cnjk3xg90y576w8y6t4gdwm. Quote request_id when reporting.",
    "details": {
      "computer": "01d4cnjk3xg90y576w8y6t4gdwm",
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h"
    },
    "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

`creation_failed`: 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. `restore_failed`: the platform is unreachable, or refuses the API, while the computer is restored.

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"
  }
}
```

Example `restore_failed`:

```json
{
  "error": {
    "code": "restore_failed",
    "message": "Computer 01d4cnjk3xg90y576w8y6t4gdwm could not be restored.",
    "details": {
      "computer": "01d4cnjk3xg90y576w8y6t4gdwm",
      "workspace": "01d4cnjjq40hnnh0nwmkg35nv2h",
      "retryable": false
    },
    "request_id": "req_01j9k3m2p7q4r8s1"
  }
}
```
