> ## Documentation Index
> Fetch the complete documentation index at: https://microsanbox-staging-toks-cloud-snapshot-contracts.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Snapshots

> Rust SDK - Snapshot API reference

Capture a stopped sandbox's writable upper layer, then list it or boot a fresh
sandbox from it through the active backend. Local snapshots are self-describing,
content-addressed artifacts on disk; cloud snapshots use managed storage or the
organization's host volume. See [Snapshots](/sandboxes/snapshots) for concepts
and walkthroughs; this page is the Rust SDK reference.

<Note>
  Snapshots are **disk-only** today and capture a sandbox that is stopped or
  crashed. `list_dir`, `reindex`, `save`/`save_to`, `load`, and `verify` remain
  on the shared `Snapshot` API, but currently return
  `MicrosandboxError::Unsupported` with the cloud backend.
</Note>

## Static methods

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">builder()</span>

```rust theme={null}
fn builder(name: impl Into<String>) -> SnapshotBuilder
```

Start configuring a new snapshot named `name`. Locally, the default destination
is `~/.microsandbox/snapshots/<name>/`; in cloud, the default is managed object
storage. [`dest_dir()`](#dest_dir) selects a local parent directory or a path on
the organization's host volume. The source sandbox is set with
[`from_sandbox()`](#from_sandbox), which is required.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Bare snapshot name. Must not be empty, contain <code>/</code>, or start with <code>.</code>.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotbuilder">SnapshotBuilder</a></div>
    <div className="msb-param-desc">Builder for configuring the snapshot.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::builder("baseline")
      .from_sandbox("api")
      .create()
      .await?;
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">create()</span>

```rust theme={null}
async fn create(config: SnapshotConfig) -> MicrosandboxResult<Snapshot>
```

Create a snapshot from a stopped sandbox through the active backend. Locally,
this atomically writes the artifact and updates the rebuildable local index. In
cloud, it starts a snapshot operation and waits for the managed or host-volume
snapshot to become available. Most callers use the [builder](#snapshotbuilder)'s
[`create()`](#create).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>config</code><a className="msb-type" href="#snapshotconfig">SnapshotConfig</a></div>
    <div className="msb-param-desc">Name, source sandbox, labels, and integrity flag.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The created artifact handle.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::create(
      Snapshot::builder("baseline").from_sandbox("api").build()?
  ).await?;
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">open()</span>

```rust theme={null}
async fn open(path_or_name: impl AsRef<str>) -> MicrosandboxResult<Snapshot>
```

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::open("baseline").await?;
  println!("{}", snap.manifest().image.reference);
  ```
</Accordion>

Open an existing snapshot by a backend-relative string. Locally, bare names
resolve under the default snapshot directory and other values are artifact
paths. In cloud, bare values identify managed snapshots and path-like values
identify host-volume artifacts. Prefer `open_ref()` when a typed
[`SnapshotReference`](#snapshotreference) is already available.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path\_or\_name</code><span className="msb-type">impl AsRef\<str></span></div>
    <div className="msb-param-desc">Bare snapshot name or filesystem path to an artifact directory.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The opened artifact handle.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">open\_ref()</span>

```rust theme={null}
async fn open_ref(reference: impl Into<SnapshotReference>) -> MicrosandboxResult<Snapshot>
```

Open a snapshot from an explicit [`SnapshotReference`](#snapshotreference).
Use this when passing through a reference returned by another SDK operation;
it preserves whether the backend should resolve the value as an identifier or
a path.

```rust theme={null}
let snap = Snapshot::open_ref(SnapshotReference::Id(snapshot_id)).await?;
```

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">get()</span>

```rust theme={null}
async fn get(name_or_digest: &str) -> MicrosandboxResult<SnapshotHandle>
```

<Accordion title="Example">
  ```rust theme={null}
  let h = Snapshot::get("after-pip-install").await?;
  println!("{} from {}", h.digest(), h.image_ref());
  ```
</Accordion>

Look up a lightweight [`SnapshotHandle`](#snapshothandle) using the active
backend: the local index locally, or the managed snapshot API in cloud.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name\_or\_digest</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Public identifier understood by the active backend (for example a local name/digest or cloud snapshot ID).</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle">SnapshotHandle</a></div>
    <div className="msb-param-desc">Handle backed by the matching index row.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">list()</span>

```rust theme={null}
async fn list() -> MicrosandboxResult<Vec<SnapshotHandle>>
```

<Accordion title="Example">
  ```rust theme={null}
  for h in Snapshot::list().await? {
      println!("{:?} - {}", h.name(), h.digest());
  }
  ```
</Accordion>

List snapshots from the active backend. Locally this uses the local index;
in cloud it paginates through managed snapshots. Host-volume artifacts are not
included automatically.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle">Vec\<SnapshotHandle></a></div>
    <div className="msb-param-desc">Indexed snapshot handles, ordered by creation time descending.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">list\_dir()</span>

```rust theme={null}
async fn list_dir(dir: impl AsRef<Path>) -> MicrosandboxResult<Vec<Snapshot>>
```

Walk a directory and parse each subdirectory's manifest. Does not touch the index. Skips entries that don't look like snapshot artifacts (no `snapshot.json`) and malformed artifacts.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dir</code><span className="msb-type">impl AsRef\<Path></span></div>
    <div className="msb-param-desc">Directory to scan for artifacts.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Vec\<Snapshot></a></div>
    <div className="msb-param-desc">One handle per valid artifact found.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">remove()</span>

```rust theme={null}
async fn remove(path_or_name: &str, force: bool) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  Snapshot::remove("after-pip-install", false).await?;
  ```
</Accordion>

Remove a snapshot artifact (by digest, name, or path) and its index row. Refuses if the snapshot has indexed children unless `force` is set. The artifact directory is deleted on success and the parent's child count is decremented.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path\_or\_name</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Snapshot digest, name, or artifact path.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>true</code>, remove even if the snapshot has indexed children.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">remove\_ref()</span>

```rust theme={null}
async fn remove_ref(
    reference: impl Into<SnapshotReference>,
    force: bool,
) -> MicrosandboxResult<()>
```

Remove a snapshot using an explicit backend-neutral reference. Prefer this
over [`remove()`](#snapshotremove) when the value came from
`Snapshot::reference()` or `SnapshotHandle::reference()`.

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">reindex()</span>

```rust theme={null}
async fn reindex(dir: impl AsRef<Path>) -> MicrosandboxResult<usize>
```

Rebuild the local index from the artifacts in `dir`. Upserts an index row for every artifact found, then recomputes parent-edge child counts in one pass so the cache stays honest about the current set of artifacts.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dir</code><span className="msb-type">impl AsRef\<Path></span></div>
    <div className="msb-param-desc">Directory of artifacts to index.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">usize</span></div>
    <div className="msb-param-desc">Number of artifacts indexed.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  let n = Snapshot::reindex("/data/snapshots").await?;
  println!("indexed {n} snapshots");
  ```
</Accordion>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">reindex\_default()</span>

```rust theme={null}
async fn reindex_default() -> MicrosandboxResult<usize>
```

Rebuild the local snapshot index from the configured default snapshot
directory. This is equivalent to [`reindex()`](#snapshotreindex) with the
local backend's configured store and returns `MicrosandboxError::Unsupported`
on backends without a rebuildable artifact index.

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">save()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>

```rust theme={null}
async fn save(name_or_path: &str, out: &Path, opts: SaveOpts) -> MicrosandboxResult<()>
```

Bundle a snapshot into a `.tar.zst` archive (or plain `.tar`) at `out`. Recorded payload integrity is preserved but not executed implicitly; call [`verify()`](#snap-verify) when an independent content scan is part of your workflow. See [`SaveOpts`](#saveopts) to also include ancestors and the OCI image cache.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name\_or\_path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Snapshot name or artifact path to save.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>out</code><span className="msb-type">\&Path</span></div>
    <div className="msb-param-desc">Output archive path. Parent directories are created if missing.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#saveopts">SaveOpts</a></div>
    <div className="msb-param-desc">Bundling options. <code>SaveOpts::default()</code> writes the head snapshot only, zstd-compressed.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  use microsandbox::snapshot::SaveOpts;
  use std::path::Path;

  Snapshot::save(
      "baseline",
      Path::new("/tmp/baseline.tar.zst"),
      SaveOpts { with_parents: true, with_image: true, ..Default::default() },
  ).await?;
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">load()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>

```rust theme={null}
async fn load(archive_path: &Path, dest: Option<&Path>) -> MicrosandboxResult<SnapshotHandle>
```

<Accordion title="Example">
  ```rust theme={null}
  use std::path::Path;

  let h = Snapshot::load(Path::new("/tmp/baseline.tar.zst"), None).await?;
  println!("loaded {}", h.digest());
  ```
</Accordion>

Unpack a snapshot archive (`.tar.zst` or `.tar`, detected from magic bytes) into the snapshots directory (or `dest`), routing any bundled image-cache entries into the global cache and registering everything found in the index. Structural and archive-entry checks remain mandatory, while recorded payload integrity is preserved for explicit [`verify()`](#snap-verify). Returns a handle for the head snapshot.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>archive\_path</code><span className="msb-type">\&Path</span></div>
    <div className="msb-param-desc">Archive to unpack.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>dest</code><span className="msb-type">Option\<\&Path></span></div>
    <div className="msb-param-desc">Destination directory. <code>None</code> uses the default snapshots directory.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle">SnapshotHandle</a></div>
    <div className="msb-param-desc">Handle for the head (last-listed) snapshot.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  use std::path::Path;

  let h = Snapshot::load(Path::new("/tmp/baseline.tar.zst"), None).await?;
  println!("loaded {}", h.digest());
  ```
</Accordion>

***

## Instance methods

Methods on an opened [`Snapshot`](#snapshotopen) artifact.

#### <span className="msb-recv">snap.</span><span className="msb-hn">digest()</span>

```rust theme={null}
fn digest(&self) -> &str
```

Canonical content digest of this snapshot's manifest (`sha256:hex`). This is the snapshot's identity.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Manifest digest in <code>sha256:hex</code> form.</div>
  </div>
</div>

#### <span className="msb-recv">snap.</span><span className="msb-hn">reference()</span>

```rust theme={null}
fn reference(&self) -> SnapshotReference
```

Return the stable, backend-neutral reference accepted by
`SandboxBuilder::from_snapshot_ref()`, `Snapshot::open_ref()`, and
`Snapshot::remove_ref()`. It contains either an identifier or a path in the
selected backend's namespace; callers can pass it through without inspecting
which storage implementation produced it.

#### <span className="msb-recv">snap.</span><span className="msb-hn">manifest()</span>

```rust theme={null}
fn manifest(&self) -> &Manifest
```

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::open("baseline").await?;
  let m = snap.manifest();
  println!("{} @ {}", m.image.reference, m.image.manifest_digest);
  ```
</Accordion>

The parsed [`Manifest`](#manifest): schema, format, fstype, image reference, parent, creation time, labels, and upper-layer metadata.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#manifest">\&Manifest</a></div>
    <div className="msb-param-desc">Parsed snapshot manifest.</div>
  </div>
</div>

#### <span className="msb-recv">snap.</span><span className="msb-hn">size\_bytes()</span>

```rust theme={null}
fn size_bytes(&self) -> Option<u64>
```

Backend-reported stored payload size. This is the apparent upper-file size for
local and host-volume artifacts, and the stored archive size for managed cloud
snapshots.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">u64</span></div>
    <div className="msb-param-desc">Upper-layer apparent size in bytes.</div>
  </div>
</div>

#### <span className="msb-recv">snap.</span><span className="msb-hn">path()</span>

```rust theme={null}
fn path(&self) -> MicrosandboxResult<&Path>
```

Return the local artifact directory. Cloud snapshots return
`MicrosandboxError::Unsupported` because managed and host-volume artifacts are
not paths on the client host. Use `reference()` for backend-neutral restore and
lifecycle operations.

#### <span className="msb-recv">snap.</span><span className="msb-hn">save\_to()</span>

```rust theme={null}
async fn save_to(&self, out: &Path, opts: SaveOpts) -> MicrosandboxResult<()>
```

Bundle this snapshot into an archive using the backend retained when it was
created or opened. This avoids re-resolving its reference through the current
default backend. Artifact archives are currently local-only; other backends
return `MicrosandboxError::Unsupported`.

#### <span className="msb-recv">snap.</span><span className="msb-hn">verify()</span>

```rust theme={null}
async fn verify(&self) -> MicrosandboxResult<SnapshotVerifyReport>
```

<Accordion title="Example">
  ```rust theme={null}
  use microsandbox::snapshot::UpperVerifyStatus;

  let snap = Snapshot::open("baseline").await?;
  match snap.verify().await?.upper {
      UpperVerifyStatus::Verified { algorithm, .. } => println!("ok via {algorithm}"),
      UpperVerifyStatus::NotRecorded => println!("no integrity hash recorded"),
  }
  ```
</Accordion>

Recompute the upper layer's recorded content integrity and compare it against the descriptor. Current BLAKE3 Merkle integrity skips known all-hole subtrees and hashes allocated leaves in batches. Released SHA algorithms retain their exact verifier and may still cost O(logical size). Returns `NotRecorded` without reading payload contents when the descriptor has `integrity: null`; errors with `SnapshotIntegrity` on mismatch. The cloud backend currently returns `MicrosandboxError::Unsupported`.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotverifyreport">SnapshotVerifyReport</a></div>
    <div className="msb-param-desc">Digest, path, and upper-layer verification status.</div>
  </div>
</div>

## SnapshotHandle methods

Accessors and lifecycle on a [`SnapshotHandle`](#snapshothandle) returned by
the active backend. Returned by [`Snapshot::get()`](#snapshotget),
[`Snapshot::list()`](#snapshotlist), and [`Snapshot::load()`](#snapshotload).

#### <span className="msb-recv">h.</span><span className="msb-hn">digest()</span>

```rust theme={null}
fn digest(&self) -> &str
```

Manifest digest (`sha256:hex`), the canonical identity.

#### <span className="msb-recv">h.</span><span className="msb-hn">name()</span>

```rust theme={null}
fn name(&self) -> Option<&str>
```

Name alias, or `None` for digest-only entries.

#### <span className="msb-recv">h.</span><span className="msb-hn">parent\_digest()</span>

```rust theme={null}
fn parent_digest(&self) -> Option<&str>
```

The parent snapshot's digest, or `None` for a root. Always `None` today; populated once chained snapshots land.

***

#### <span className="msb-recv">h.</span><span className="msb-hn">scope()</span>

<div className="msb-tags"><span className="msb-tag is-instance">instance</span></div>

```rust theme={null}
fn scope(&self) -> SnapshotScope
```

Snapshot payload scope: [`SnapshotScope::Disk`](#snapshotscope) for a disk-only snapshot, `Resumable` once resumable snapshots land. Always `Disk` today.

***

#### <span className="msb-recv">h.</span><span className="msb-hn">image\_ref()</span>

```rust theme={null}
fn image_ref(&self) -> &str
```

Image reference the snapshot was taken from.

#### <span className="msb-recv">h.</span><span className="msb-hn">format()</span>

```rust theme={null}
fn format(&self) -> SnapshotFormat
```

On-disk format of the upper layer.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotformat">SnapshotFormat</a></div>
    <div className="msb-param-desc">Upper-layer format (<code>Raw</code> today).</div>
  </div>
</div>

#### <span className="msb-recv">h.</span><span className="msb-hn">size\_bytes()</span>

```rust theme={null}
fn size_bytes(&self) -> Option<u64>
```

Backend-reported stored payload size, if known.

#### <span className="msb-recv">h.</span><span className="msb-hn">path()</span>

```rust theme={null}
fn path(&self) -> MicrosandboxResult<&Path>
```

Return the local artifact directory. Cloud snapshots return
`MicrosandboxError::Unsupported`. Use `reference()` for backend-neutral restore
and lifecycle operations.

#### <span className="msb-recv">h.</span><span className="msb-hn">created\_at()</span>

```rust theme={null}
fn created_at(&self) -> chrono::NaiveDateTime
```

Snapshot creation time, parsed from the manifest.

#### <span className="msb-recv">h.</span><span className="msb-hn">open()</span>

```rust theme={null}
async fn open(&self) -> MicrosandboxResult<Snapshot>
```

<Accordion title="Example">
  ```rust theme={null}
  let h = Snapshot::get("baseline").await?;
  let snap = h.open().await?;
  snap.verify().await?;
  ```
</Accordion>

Open the underlying snapshot metadata using the backend retained by the handle,
without requiring the caller to interpret its storage location.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The opened artifact.</div>
  </div>
</div>

#### <span className="msb-recv">h.</span><span className="msb-hn">remove()</span>

```rust theme={null}
async fn remove(&self, force: bool) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  let h = Snapshot::get("baseline").await?;
  h.remove(false).await?;
  ```
</Accordion>

Remove this snapshot through the backend retained by the handle, preserving
its identifier-versus-path reference kind.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>true</code>, remove even if the snapshot has indexed children.</div>
  </div>
</div>

#### <span className="msb-recv">h.</span><span className="msb-hn">save\_to()</span>

```rust theme={null}
async fn save_to(&self, out: &Path, opts: SaveOpts) -> MicrosandboxResult<()>
```

Bundle the referenced snapshot into an archive through the backend retained
by this handle. Artifact archives are currently local-only; other backends
return `MicrosandboxError::Unsupported`.

## Sandbox entry points

Snapshot-related methods that live on the sandbox builder and handle. See [Sandbox](/sdk/rust/sandbox) for the full sandbox API.

#### <span className="msb-recv">.</span><span className="msb-hn">from\_snapshot()</span>

```rust theme={null}
fn from_snapshot(self, path_or_name: impl Into<String>) -> Self
```

<Accordion title="Example">
  ```rust theme={null}
  let sb = Sandbox::builder("api-restored")
      .from_snapshot("after-pip-install")
      .create()
      .await?;
  ```
</Accordion>

`SandboxBuilder` setter. Boot a fresh sandbox from a snapshot artifact. The snapshot already pins the image reference and digest, so this is mutually exclusive with [`image()`](/sdk/rust/sandbox#image) and [`image_with()`](/sdk/rust/sandbox#image_with). The artifact is structurally opened at [`create()`](/sdk/rust/sandbox#create) time; persistent payload integrity is checked only through explicit [`Snapshot::verify()`](#snap-verify).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path\_or\_name</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Backend-relative snapshot name, ID, or path.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">from\_snapshot\_ref()</span>

```rust theme={null}
fn from_snapshot_ref(self, reference: impl Into<SnapshotReference>) -> Self
```

Boot from an explicit backend-neutral snapshot reference. This is the safest
way to pass a `Snapshot` or `SnapshotHandle` reference into a new sandbox
without reinterpreting an identifier as a path.

```rust theme={null}
let restored = Sandbox::builder("api-restored")
    .from_snapshot_ref(snapshot.reference())
    .create()
    .await?;
```

#### <span className="msb-recv">h.</span><span className="msb-hn">snapshot()</span>

```rust theme={null}
async fn snapshot(&self, name: &str) -> MicrosandboxResult<Snapshot>
```

`SandboxHandle` method. Snapshot this sandbox under a bare name using the
handle's backend. Local uses its default snapshot directory; cloud uses managed
storage. The sandbox must be stopped or crashed; running sandboxes are rejected
with `SnapshotSandboxRunning`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Bare snapshot name.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The created artifact handle.</div>
  </div>
</div>

#### <span className="msb-recv">h.</span><span className="msb-hn">snapshot\_to()</span>

```rust theme={null}
async fn snapshot_to(&self, path: impl AsRef<Path>) -> MicrosandboxResult<Snapshot>
```

<Accordion title="Example">
  ```rust theme={null}
  let h = Sandbox::get("api").await?;
  h.stop().await?;
  let snap = h.snapshot_to("/data/snapshots/baseline").await?;
  ```
</Accordion>

***

## SnapshotBuilder

Builder for a [`SnapshotConfig`](#snapshotconfig). Obtained via [`Snapshot::builder(name)`](#snapshotbuilder). A source sandbox is required ([`from_sandbox`](#from_sandbox)); the other setters are optional. Every setter returns `Self`, so calls chain.

```rust theme={null}
let snap = Snapshot::builder("after-pip-install")
    .from_sandbox("api")           // sandbox to capture
    .label("stage", "post-deps")
    .force()                       // overwrite if it exists
    .record_integrity()            // hash the upper layer
    .create()
    .await?;
```

***

#### <span className="msb-recv">.</span><span className="msb-hn">from\_sandbox()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```rust theme={null}
fn from_sandbox(self, source_sandbox: impl Into<String>) -> Self
```

Set the sandbox to capture. Required; [`build()`](#build) and [`create()`](#create) fail without it.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>source\_sandbox</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Name of the source sandbox. Must be stopped or crashed, and rooted on an OCI image.</div>
  </div>
</div>

***

#### <span className="msb-recv">.</span><span className="msb-hn">dest\_dir()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```rust theme={null}
fn dest_dir(self, dest_dir: impl Into<PathBuf>) -> Self
```

Create the artifact under this parent directory instead of the default snapshots store. The artifact directory is `dest_dir/<name>`; the name stays the snapshot's identity either way.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dest\_dir</code><span className="msb-type">impl Into\<PathBuf></span></div>
    <div className="msb-param-desc">Parent directory to create the artifact in (e.g. a larger volume).</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">label()</span>

```rust theme={null}
fn label(self, key: impl Into<String>, value: impl Into<String>) -> Self
```

Add a user label. Can be called multiple times. Labels are sorted by key in the manifest's canonical form.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>key</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Label key.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Label value.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">force()</span>

```rust theme={null}
fn force(self) -> Self
```

Overwrite an existing artifact with the same name. Without this, creation fails with `SnapshotAlreadyExists` if the artifact directory exists.

#### <span className="msb-recv">.</span><span className="msb-hn">record\_integrity()</span>

```rust theme={null}
fn record_integrity(self) -> Self
```

Compute and record sparse-aware BLAKE3 Merkle integrity during creation. [`verify()`](#snap-verify) checks it explicitly; ordinary open, boot, save, load, and upgrade preserve the value without adding an independent payload pass.

***

#### <span className="msb-recv">.</span><span className="msb-hn">resumable()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```rust theme={null}
fn resumable(self) -> Self
```

Request a future resumable snapshot (disk plus VM state). [`create()`](#create)
currently fails with `Unsupported`; resumable capture has not landed yet.

#### <span className="msb-recv">.</span><span className="msb-hn">build()</span>

```rust theme={null}
fn build(self) -> MicrosandboxResult<SnapshotConfig>
```

Materialize the [`SnapshotConfig`](#snapshotconfig) without creating the snapshot. Errors with `InvalidConfig` if [`from_sandbox`](#from_sandbox) was not called. For capturing, use [`create`](#create) instead; it calls `build` internally.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotconfig">SnapshotConfig</a></div>
    <div className="msb-param-desc">Validated snapshot configuration.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">create()</span>

```rust theme={null}
async fn create(self) -> MicrosandboxResult<Snapshot>
```

Build and execute the snapshot in one step. Equivalent to [`Snapshot::create(self.build()?)`](#snapshotcreate).

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The created artifact handle.</div>
  </div>
</div>

## Types

### SnapshotReference

<div className="msb-tags"><span className="msb-tag is-type">enum</span></div>

A backend-neutral snapshot locator. Obtain one from `Snapshot::reference()` or
`SnapshotHandle::reference()` and pass it to
`SandboxBuilder::from_snapshot_ref()`, `Snapshot::open_ref()`, or
`Snapshot::remove_ref()`. This preserves whether a value is an identifier or a
path without exposing the selected backend.

| Variant        | Meaning                                                              |
| -------------- | -------------------------------------------------------------------- |
| `Auto(String)` | Compatibility string interpreted automatically by the active backend |
| `Id(String)`   | Identifier resolved by the selected backend                          |
| `Path(String)` | Path in the selected backend's filesystem namespace                  |

Use `SnapshotReference::auto()`, `id()`, or `path()` to construct a reference.
`value()` returns the underlying string and `kind()` returns `auto`, `id`, or
`path`.

### SnapshotHandle

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Returned by <a href="#snapshotget">Snapshot::get()</a> · <a href="#snapshotlist">Snapshot::list()</a> · <a href="#snapshotload">Snapshot::load()</a></p>

A lightweight handle returned by the active backend. Use [`open()`](#h-open) to
read the snapshot metadata. The handle retains its backend, so `open()` and
`remove()` work without the caller interpreting its storage location.

| Method              | Type                                        | Description                                        |
| ------------------- | ------------------------------------------- | -------------------------------------------------- |
| digest()            | `&str`                                      | Manifest digest (`sha256:hex`)                     |
| name()              | `Option<&str>`                              | Name alias; `None` for digest-only entries         |
| parent\_digest()    | `Option<&str>`                              | Parent snapshot digest, or `None` for a root       |
| scope()             | [`SnapshotScope`](#snapshotscope)           | Snapshot payload scope (`Disk` today)              |
| image\_ref()        | `&str`                                      | Source image reference                             |
| format()            | [`SnapshotFormat`](#snapshotformat)         | On-disk upper format                               |
| size\_bytes()       | `Option<u64>`                               | Upper file size at index time                      |
| created\_at()       | `chrono::NaiveDateTime`                     | Creation time from the manifest                    |
| reference()         | `SnapshotReference`                         | Stable backend-neutral restore reference           |
| open()              | `Result<`[`Snapshot`](#instance-methods)`>` | Open the underlying artifact                       |
| remove(force)       | `Result<()>`                                | Remove this snapshot                               |
| save\_to(out, opts) | `Result<()>`                                | Bundle through the backend retained by this handle |

### SnapshotConfig

<p className="msb-backref">Used by <a href="#snapshotcreate">Snapshot::create()</a> · returned by <a href="#build">build()</a></p>

Inputs to create a snapshot. A type alias for `SnapshotSpec`. Usually built via [`SnapshotBuilder`](#snapshotbuilder) rather than constructed directly.

| Field             | Type                    | Description                                                                      |
| ----------------- | ----------------------- | -------------------------------------------------------------------------------- |
| name              | `String`                | Snapshot name; storage location is selected by the active backend                |
| dest\_dir         | `Option<PathBuf>`       | Local parent or cloud host-volume directory; `None` uses backend-managed storage |
| source\_sandbox   | `String`                | Name of the source sandbox; must be stopped                                      |
| labels            | `Vec<(String, String)>` | User-supplied labels                                                             |
| force             | `bool`                  | Overwrite an existing artifact with the same name                                |
| record\_integrity | `bool`                  | Compute and record upper-layer integrity at creation                             |
| resumable         | `bool`                  | Request a resumable snapshot; returns an unsupported-feature error today         |

### SnapshotFormat

<p className="msb-backref">Used by <a href="#h-format">format()</a> · <a href="#manifest">Manifest.format</a></p>

On-disk format of the captured upper layer. Today only `Raw` is produced; the variant exists so qcow2 chains drop in later without a schema migration.

| Value   | Description                                |
| ------- | ------------------------------------------ |
| `Raw`   | Raw ext4 image, sparse on disk             |
| `Qcow2` | qcow2 with optional backing chain (future) |

### SnapshotScope

<div className="msb-tags"><span className="msb-tag is-type">enum</span></div>

<p className="msb-backref">Used by <a href="#h-scope">scope()</a> · <a href="#manifest">Manifest.scope</a></p>

Snapshot payload scope. Parsing accepts every known scope so older runtimes can still list and inspect artifacts they cannot restore; create and restore paths enforce support. Re-exported as `microsandbox::snapshot::SnapshotScope`.

| Value       | Description                                                |
| ----------- | ---------------------------------------------------------- |
| `Disk`      | Disk-only snapshot; captures the writable filesystem state |
| `Resumable` | Reserved for future memory/device-state capture            |

### SaveOpts

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Used by <a href="#snapshotsave">Snapshot::save()</a> and instance <code>save\_to()</code> methods</p>

Options for [`Snapshot::save()`](#snapshotsave) and instance `save_to()` methods. Implements `Default`; `SaveOpts::default()` writes the head snapshot only, zstd-compressed.

| Field         | Type   | Description                                                                                                               |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------- |
| with\_parents | `bool` | Walk the parent chain and include each ancestor in the archive                                                            |
| with\_image   | `bool` | Bundle the OCI image artifacts (EROFS layers, fsmeta, VMDK descriptor) from the global cache so the archive boots offline |
| plain\_tar    | `bool` | Skip zstd compression and write a plain `.tar`. Default: zstd                                                             |

### SnapshotVerifyReport

<p className="msb-backref">Returned by <a href="#snap-verify">verify()</a></p>

Result of explicit snapshot verification.

| Field  | Type                                      | Description                             |
| ------ | ----------------------------------------- | --------------------------------------- |
| digest | `String`                                  | Snapshot manifest digest                |
| path   | `PathBuf`                                 | Artifact directory                      |
| upper  | [`UpperVerifyStatus`](#upperverifystatus) | Upper-layer content verification result |

### UpperVerifyStatus

<p className="msb-backref">Used by <a href="#snapshotverifyreport">SnapshotVerifyReport.upper</a></p>

Upper-layer content verification result.

| Variant       | Fields                                          | Description                                                  |
| ------------- | ----------------------------------------------- | ------------------------------------------------------------ |
| `NotRecorded` | -                                               | No content integrity descriptor was recorded in the manifest |
| `Verified`    | - `algorithm: String` <br /> - `digest: String` | Recorded integrity matched the computed digest               |

### Manifest

<p className="msb-backref">Returned by <a href="#snap-manifest">manifest()</a></p>

The snapshot artifact manifest, the source of truth for an artifact, serialized as the `snapshot.json` descriptor (`DESCRIPTOR_FILENAME`). Re-exported as `microsandbox::snapshot::Manifest`. Its SHA-256 digest over the canonical byte form is the snapshot's identity. Field order is load-bearing (it determines the canonical byte layout) and must not be reordered.

| Field           | Type                                | Description                                            |
| --------------- | ----------------------------------- | ------------------------------------------------------ |
| schema          | `u32`                               | Manifest schema version; readers reject unknown values |
| artifact        | `String`                            | Artifact kind; always `"snapshot"`                     |
| scope           | [`SnapshotScope`](#snapshotscope)   | Payload scope; only disk snapshots are created today   |
| format          | [`SnapshotFormat`](#snapshotformat) | On-disk format of the upper layer                      |
| fstype          | `String`                            | Filesystem type inside the upper (e.g. `ext4`)         |
| image           | [`ImageRef`](#imageref)             | Image the snapshot was taken from                      |
| parent          | `Option<String>`                    | Parent snapshot digest, or `None` for a root           |
| created\_at     | `String`                            | RFC 3339 creation timestamp                            |
| labels          | `BTreeMap<String, String>`          | User-supplied labels, sorted by key in canonical form  |
| upper           | [`UpperLayer`](#upperlayer)         | The captured upper layer                               |
| source\_sandbox | `Option<String>`                    | Best-effort name of the source sandbox (informational) |

### ImageRef

<p className="msb-backref">Used by <a href="#manifest">Manifest.image</a></p>

Reference to the OCI image the snapshot was taken from. Re-exported as `microsandbox::snapshot::ImageRef`.

| Field            | Type     | Description                                                           |
| ---------------- | -------- | --------------------------------------------------------------------- |
| reference        | `String` | Human-readable image reference (e.g. `docker.io/library/python:3.12`) |
| manifest\_digest | `String` | Digest of the OCI manifest, in `sha256:hex` form                      |

### UpperLayer

<p className="msb-backref">Used by <a href="#manifest">Manifest.upper</a></p>

Captured upper-layer file metadata. Re-exported as `microsandbox::snapshot::UpperLayer`.

| Field       | Type                                            | Description                                                      |
| ----------- | ----------------------------------------------- | ---------------------------------------------------------------- |
| file        | `String`                                        | Filename inside the artifact directory (e.g. `upper.ext4`)       |
| size\_bytes | `u64`                                           | Apparent size in bytes (ext4 virtual size; sparse on disk)       |
| integrity   | `Option<`[`UpperIntegrity`](#upperintegrity)`>` | Optional content integrity descriptor; `None` on local hot paths |

### UpperIntegrity

<p className="msb-backref">Used by <a href="#upperlayer">UpperLayer.integrity</a></p>

Content integrity descriptor for the captured upper layer.

| Field                | Type                        | Description                         |                                         |
| -------------------- | --------------------------- | ----------------------------------- | --------------------------------------- |
| Variant              | Serialized algorithm        | Fields                              | Purpose                                 |
| ---------            | ----------------------      | --------                            | ---------                               |
| `Sha256`             | `sha256`                    | `digest`                            | Exact released compatibility            |
| `SparseSha256V1`     | `msb-sparse-sha256-v1`      | `digest`                            | Exact released sparse-SHA compatibility |
| `FileMerkleBlake3V1` | `msb-file-merkle-blake3-v1` | `root`, `logical_size`, `leaf_size` | Current opt-in sparse-aware integrity   |
