---
title: "List immutability snapshots for a passport."
method: GET
path: "/api/v1/passports/{id}/snapshots"
tags: ["Passports"]
---

# List immutability snapshots for a passport.

`GET /api/v1/passports/{id}/snapshots`

## Request

- Base URL: `https://app.tracepass.eu`
- URL: `https://app.tracepass.eu/api/v1/passports/{id}/snapshots`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://app.tracepass.eu/api/oauth/authorize`, token URL `https://app.tracepass.eu/api/oauth/token`, scopes: `passports:read`)

Returns a paginated list of **immutability snapshots** for a
passport, newest first. Each entry re-verifies the stored
content hash so an at-rest tamper is visible (`hashValid: false`)
rather than silently trusted.

A snapshot is written on publish and after **every change** to a
non-draft (published, suspended, expired or archived) passport —
field values, statuses, translations, parties, status transitions,
supplier answers, AI writes, restores — whenever what the passport
asserts actually changed (EN 18221:2026 4.2). Changes made
outside the API are captured too, within a day. Passports that
predate snapshots start with a `baseline` snapshot.

**Point in time:** `?at=<ISO 8601>` returns the single snapshot
valid at that instant — the `SnapshotDetail` shape plus
`validFrom` and `validUntil` (null while current) — instead of
the list. 404 when `at` predates the passport's first snapshot.

Read-only; counts as one v1 passport read against the daily cap.

## Query parameters

- `page` integer
- `limit` integer
- `at` string, date-time

## Response `200`

Paginated snapshot list, or with `?at=` the snapshot valid then (`SnapshotDetail` plus `validFrom` / `validUntil`).

- SnapshotList: Paginated list of passport snapshots.
  - `entries` SnapshotEntry[], required
    - `id` string, required: The snapshot's TracePass id (MongoDB ObjectId hex).
    - `version` integer, required: The passport version counter at the time of this snapshot.
    - `reason` 'published' | 'republished' | 'manual' | 'field_edit' | 'status_change' | 'parties' | 'supplier' | 'ai' | 'restore' | 'system' | 'baseline', required: Why this snapshot was taken.
    - `actor` string: Who caused the change, when known: `user:<id>`, `apikey:<prefix>`, `oauth:<clientId>`, `supplier:<requestId>` or `system:<job>`.
    - `snapshotAt` string, date-time, required: When the snapshot was taken (ISO 8601).
    - `contentHash` string, required: SHA-256 hex digest of the canonical JSON-LD archived at snapshot time. Re-verified on every read — if the stored document was tampered with at rest, `hashValid` is false.
    - `hashValid` boolean, required: True when the freshly-computed sha256(jsonLd) matches the stored `contentHash`. False indicates at-rest tampering.
    - `restorable` boolean, required: True when the snapshot carries `rawFields` and can drive a field-level restore. Snapshots taken before `rawFields` was captured are evidence-only (permanently `restorable: false`).
    - `fieldCount` integer, nullable, required: Number of fields captured in `rawFields`, or `null` for pre-`rawFields` snapshots.
  - `total` integer, required: Total snapshots matching the query across all pages.
  - `page` integer, required: Current page number (1-based).
  - `limit` integer, required: Page size used for this response.
  - `totalPages` integer, required: Total number of pages at the current limit.

## Other responses

- `401`: Missing or invalid API key.
- `404`: Resource doesn't exist or is in a different workspace.
- `429`: Daily v1 write or passport-read budget exhausted. Resets at 00:00 UTC.

---

[API](https://skmtc.dev/tracepass/apis/tracepass-api.md) · [All operations](https://skmtc.dev/tracepass/apis/tracepass-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tracepass/apis/tracepass-api/revisions/60ddeb25638b?raw)
