# Save a snapshot

> Freeze a sandbox's disk under a name, to start new sandboxes from it with from on POST /v1/sandboxes, or to share it. Paid plans only. The first day ($0.07) is charged now and returned if the save fails; later days are charged per started UTC day while you keep it. The save runs in the background: poll GET /v1/sandbox-snapshots/{snapshotId} until status is ready or failed. Not available with test-mode keys.

`POST https://api.zavu.dev/v1/sandbox-snapshots`

Freeze a sandbox's disk under a name, to start new sandboxes from it with `from` on `POST /v1/sandboxes`, or to share it. Paid plans only. The first day ($0.07) is charged now and returned if the save fails; later days are charged per started UTC day while you keep it. The save runs in the background: poll `GET /v1/sandbox-snapshots/{snapshotId}` until `status` is `ready` or `failed`. Not available with test-mode keys.

## Body

- `sandboxId` (string, required): The sandbox to save. Running: its disk as it is now. Stopped: as it was when it stopped. An ephemeral sandbox cannot be saved (`409 sandbox_ephemeral`).
- `name` (string, required): 1 to 64 letters, digits, spaces, dots, dashes or underscores.

## Responses

### 202

Accepted. The snapshot is saving.

- `snapshot` (object, required): A sandbox's disk frozen under a name. $0.07 per started UTC day while you keep it, charged from your balance; the first day at save, refunded if the save fails. At most 20 per team.
  - `id` (string, required)
  - `name` (string, required)
  - `status` (string, required): - `saving`: the disk is being captured. It cannot be started from or deleted yet. - `ready`: start sandboxes from it with `from`. - `failed`: the save did not finish; its first day was refunded. See `failureReason`. One of: `saving`, `ready`, `failed`.
  - `size` (string, required): Machine size, and its price per hour of machine time: - `small`: 2 vCPU, 4 GB RAM. $0.0225/h. - `default`: 4 vCPU, 8 GB RAM. $0.045/h. - `large`: 8 vCPU, 16 GB RAM. $0.09/h. One of: `small`, `default`, `large`.
  - `sizeBytes` (integer, nullable): Bytes on disk, once known.
  - `sourceSandboxId` (string, required): The sandbox whose disk this is.
  - `shareCode` (string, required, nullable): The code another team passes as `from` to start from this snapshot, while it is shared. Null when it is not. Treat it as a secret: whoever holds it can copy this disk.
  - `costTotal` (number, required): USD charged for it so far.
  - `failureReason` (string, nullable)
  - `createdAt` (string<date-time>, required)
  - `updatedAt` (string<date-time>, required)

### 400

Invalid name, or a test-mode key.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 401

Unauthorized.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 402

`paid_plan_required`, `insufficient_balance` or `spend_cap_reached`.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 403

`plan_limit_reached`: the team keeps 20 saved snapshots already. Delete one first.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 404

Sandbox not found, or it belongs to another project.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 409

`sandbox_not_ready`: the sandbox is not running or stopped. `sandbox_ephemeral`: its disk is never saved.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

## Example

```bash
curl -X POST "https://api.zavu.dev/v1/sandbox-snapshots" \
  -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "sandboxId": "kh7d2x9q4m1p8r3s5t6v0wabc",
  "name": "node-22-with-deps"
}'
```

```typescript
import Zavudev from "@zavudev/sdk";

const zavu = new Zavudev({ apiKey: process.env.ZAVUDEV_API_KEY });

const result = await zavu.sandboxes.snapshots.create({
  sandboxId: "kh7d2x9q4m1p8r3s5t6v0wabc",
  name: "node-22-with-deps",
});

console.log(result);
```
