---
title: "Create a snapshot from a VM"
method: POST
path: "/v1/snapshots"
tags: ["snapshots"]
---

# Create a snapshot from a VM

`POST /v1/snapshots`

Captures a VM's state into a customer-visible snapshot.
Supported on `running` and `paused` VMs; returns 201 Created
with the new snapshot in both cases. On a paused VM, repeated
calls within the same pause cycle are idempotent: the second
call returns the same snapshot record without modification.

## Request body

- CreateSnapshotRequest
  - `vmId` string, required
  - `name` string — Snapshot name (trimmed + whitespace-collapsed, max 64 runes; longer values are truncated server-side). Auto-generated as `snapshot-<8-char-vmId-prefix>` if empty.

## Response `201`

Snapshot created

- Snapshot
  - `id` string, required
  - `name` string, required
  - `orgId` string, required
  - `vmId` string, required
  - `firewall` FirewallPolicy
    - `mode` string, required — Firewall mode. Known values: `open` (allow all inbound traffic), `restricted` (deny by default; only rules listed in `ingress` are allowed). Additional values may be introduced in future server versions.
    - `ingress` FirewallRule[]
      - `protocol` string, required — IP protocol. Known values: `tcp`, `udp`. Additional values may be introduced in future server versions.
      - `portStart` integer, required — Start of port range (inclusive). Required.
      - `portEnd` integer — End of port range (inclusive). Omit for single-port rules.
      - `sourceCidrs` string[] — Allowed source CIDRs in IPv6 notation (e.g. `2001:db8::/32`). Omit or empty to allow any source. IPv4 CIDRs are rejected.
      - `description` string
  - `metadata` Metadata — Free-form string→string map. Server-enforced limits: up to 256 keys, key length 1–256 bytes, value length ≤4096 bytes, total JSON encoding ≤65536 bytes.
  - `envVars` EnvVars — Environment variable string→string map injected into the VM at boot. Keys must be 1–256 bytes and match shell-variable name (`[A-Za-z_][A-Za-z0-9_]*`); values may not contain newline, carriage return, or null bytes. Total JSON encoding ≤65536 bytes.
  - `services` SnapshotService[] — Captured service registrations from the source VM at snapshot time.
    - `name` string, required
    - `port` integer, required
    - `h2c` boolean
  - `status` string, required — Snapshot lifecycle status. Known values: `creating`, `ready`, `error`. Additional values may be introduced in future server versions.
  - `createdAt` string, date-time, required

## Other responses

- `400` — Invalid request
- `401` — Missing or invalid credentials
- `403` — Snapshot quota exceeded
- `404` — Source VM not found
- `409` — Source VM is in a non-snapshottable state (provisioning, pausing, resuming, error, deleting), or the paused VM already has a snapshot with a different name.
- `500` — Internal server error
- `502` — Upstream service error

## Changes

- **2026-05-09** `480d9714a7a5` — 2 info
  - added the optional property `envVars` to the response with the `201` status
  - added the optional property `services` to the response with the `201` status
- **2026-04-22** `fdb53b5a79b3` — 4 breaking, 13 info
  - the `firewall/ingress/items/description` response property's maxLength was unset from `256` for the response status `201`
  - the `name` response property's maxLength was unset from `64` for the response status `201`
  - the `id` response's property type/format changed from `string`/`uuid` to `string`/`` for status `201`
  - the `vmId` response's property type/format changed from `string`/`uuid` to `string`/`` for status `201`
  - …13 more

[Change history](https://skmtc.dev/fastvm-org/apis/fastvm-api/changes/v1/snapshots/post.md)

---

[API](https://skmtc.dev/fastvm-org/apis/fastvm-api.md) · [All operations](https://skmtc.dev/fastvm-org/apis/fastvm-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/fastvm-org/fastvm-api/revisions/480d9714a7a5/schema)
