---
title: "Verify and decode a signed snapshot blob"
method: POST
path: "/snapshot/restore"
tags: ["snapshot"]
---

# Verify and decode a signed snapshot blob

`POST /snapshot/restore`

Accepts a base64-encoded snapshot blob previously produced by
`POST /snapshot/save`, verifies its HMAC-SHA256 signature against
`TENSOR_WASM_API_SNAPSHOT_HMAC_KEY`, and returns the
HMAC-authenticated provenance (captured tenant, instance id,
uncompressed size, wire version).

Hardening: the reader always requires a signature
(`require_signature`) so a stripped-trailer downgrade to an
unsigned v2 blob is refused;
`TENSOR_WASM_API_SNAPSHOT_REQUIRE_SIGNATURE` is the operator
surface for this posture. A 256 MiB decompression cap bounds
restore-time memory pressure.

Authorization: protected stack (bearer auth + tenant scope). After
HMAC verification recovers the snapshot's captured tenant, the
handler enforces that it equals the caller's resolved tenant — a
cross-tenant restore is `403 tenant_scope_denied`. A wrong /
missing key or a tampered blob is `403 snapshot_signature_invalid`
(a single opaque rejection, not a decode oracle).

NOTE: this verifies and decodes the snapshot *envelope*.
Reconstituting a *live running instance* from the captured memory
needs an executor restore hook that does not exist yet; requesting
that capability surfaces `501 not_implemented`.

## Headers

- `X-TensorWasm-Tenant` integer

## Request body

- SnapshotRestoreRequest — Body of `POST /snapshot/restore`. Mirrors the `tensor_wasm_api::routes::SnapshotRestoreRequest` Rust struct.
  - `snapshot_b64` string, required — Base64-encoded signed snapshot blob (standard alphabet, padded) previously returned by `POST /snapshot/save`.

## Response `200`

Snapshot signature verified; provenance returned.

- SnapshotRestoreResponse — Body of a successful `POST /snapshot/restore`. Reports the HMAC-authenticated provenance recovered from the snapshot metadata.
  - `tenant_id` integer, required — Tenant the snapshot was originally captured for.
  - `instance_id` string, required — Instance id stamped into the snapshot metadata at capture time, rendered as the `I#<n>` display form.
  - `total_uncompressed_bytes` integer, required — Total uncompressed payload bytes recorded in the metadata.
  - `version` integer, required — Snapshot wire-format version that verified (`3` for the signed envelope this gateway writes).

## Other responses

- `400` — `invalid_json` (malformed request body) or `invalid_base64` (the `snapshot_b64` field is not valid base64). Carries the native `{error:{kind,message}}` envelope.
- `401` — Missing or unrecognised bearer token
- `403` — `tenant_scope_denied` (the bearer token is not scoped to the requested tenant, or the snapshot was captured for a different tenant) or `snapshot_signature_invalid` (HMAC verification failed, the blob is unsigned, or it is malformed). Carries the native `{error:{kind,message}}` envelope.
- `413` — Request body exceeded the 64 MiB cap enforced by axum's `DefaultBodyLimit::max`. Often rendered as a bare 413 with no body when the limit is hit during streaming.
- `429` — Per-token QPS + burst exceeded. The `Retry-After` header carries the wait in integer seconds (RFC 9110 §10.2.3).
- `500` — Underlying wasmtime or host failure
- `501` — `not_implemented` — the requested capability needs executor support that is not wired yet (full live-instance snapshot / restore of linear + GPU memory). The HMAC envelope layer of the `/snapshot/*` routes is fully wired; only the live-instance reconstitution returns this. Clients should NOT retry.
- `503` — `snapshot_signing_not_configured` — the `/snapshot/*` routes are mounted but `TENSOR_WASM_API_SNAPSHOT_HMAC_KEY` is unset, so the gateway has no key to sign or verify snapshot blobs. The failure mode is configuration, not load; a client should NOT retry but surface the error to an operator who can set the key.

---

[API](https://skmtc.dev/craton-co/apis/tensorwasm-http-api.md) · [All operations](https://skmtc.dev/craton-co/apis/tensorwasm-http-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/craton-co/tensorwasm-http-api/revisions/d363e13d8640/schema)
