# Snapshots (/api-v2/snapshots)



A snapshot compiles the ordered logical state for a branch head and pins it: the branch version it was taken at, the prompt-compiler revision, and the ordered block manifest. That lets a response be replayed later against a stable logical-state definition, independent of tokenizer and engine. Snapshots are prefixed `snp_`. See [snapshots](/concepts/snapshots).

All requests require a bearer API key. See [authentication](/api-reference/authentication).

## Create a snapshot [#create-a-snapshot]

`POST /v2/sessions/{session_id}/branches/{branch_id}/snapshots`

Pins the current logical state of a branch head.

<ParamField path="session_id" type="string">
  The session the branch belongs to.
</ParamField>

<ParamField path="branch_id" type="string">
  The branch to snapshot. The snapshot records the branch's current `version`.
</ParamField>

<ParamField body="prompt_compiler_revision" type="string" default="pc_1">
  The prompt-compiler revision the snapshot pins against.
</ParamField>

<ParamField body="ordered_block_manifest" type="array">
  The ordered list of logical blocks that make up the compiled state. Stored exactly as supplied. Defaults to an empty list.
</ParamField>

```bash
curl https://api.zumik.ai/v2/sessions/ses_01jy7n7w2z9pcu7a5q2gh8askm/branches/br_01jy7n7w30ardv8b6r3jk9btln/snapshots \
  -H "Authorization: Bearer $ZUMIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt_compiler_revision": "pc_1",
    "ordered_block_manifest": ["blk_policy", "blk_history", "evt_01jy7naa12b3c4d5e6f7g8h9jk"]
  }'
```

```json
{
  "id": "snp_01jy7ncd67e8f9g0h1j2k3l4mn",
  "object": "snapshot",
  "session_id": "ses_01jy7n7w2z9pcu7a5q2gh8askm",
  "branch_id": "br_01jy7n7w30ardv8b6r3jk9btln",
  "branch_version": 1,
  "prompt_compiler_revision": "pc_1",
  "ordered_block_manifest": ["blk_policy", "blk_history", "evt_01jy7naa12b3c4d5e6f7g8h9jk"],
  "created_at": "2026-06-15T16:10:44Z"
}
```

<ResponseField name="id" type="string">
  Opaque snapshot id, prefixed `snp_`.
</ResponseField>

<ResponseField name="object" type="string">
  Always `snapshot`.
</ResponseField>

<ResponseField name="session_id" type="string">
  The owning session.
</ResponseField>

<ResponseField name="branch_id" type="string">
  The branch the snapshot was taken from.
</ResponseField>

<ResponseField name="branch_version" type="integer">
  The branch version at snapshot time.
</ResponseField>

<ResponseField name="prompt_compiler_revision" type="string">
  The pinned compiler revision.
</ResponseField>

<ResponseField name="ordered_block_manifest" type="array">
  The ordered blocks, exactly as supplied.
</ResponseField>

<ResponseField name="created_at" type="string">
  RFC 3339 creation timestamp.
</ResponseField>

## Retrieve a snapshot [#retrieve-a-snapshot]

`GET /v2/snapshots/{snapshot_id}`

Snapshots are fetched by id at the top level, not under their session path.

<ParamField path="snapshot_id" type="string">
  The snapshot id to fetch.
</ParamField>

```bash
curl https://api.zumik.ai/v2/snapshots/snp_01jy7ncd67e8f9g0h1j2k3l4mn \
  -H "Authorization: Bearer $ZUMIK_API_KEY"
```

Returns the same snapshot object as create. Ownership is enforced through the snapshot's session: a snapshot whose session belongs to another project returns `404`.

## Compact a branch [#compact-a-branch]

`POST /v2/sessions/{session_id}/branches/{branch_id}/compact`

Fold a branch's older turns into a model-generated summary while keeping the most recent turns verbatim. The summary is persisted as a [`compaction_summary` artifact](/api-v2/artifacts), a `checkpoint` [event](/api-v2/branches) referencing it is appended under optimistic concurrency, and a compacted snapshot is pinned (the summary block followed by the retained tail).

Compaction is **additive, not destructive**: the original events stay on the branch, so you recover the pre-compaction state by forking a branch from before the checkpoint. The summary is a real model call, so this is budget-gated like inference; with no gateway configured it degrades to a deterministic summary. api-core does not retain raw payloads, so you supply the turns to compact.

<ParamField body="expected_version" type="integer">
  The branch version you expect, for optimistic concurrency. A mismatch returns `branch_version_conflict`.
</ParamField>

<ParamField body="expected_head_event_id" type="string">
  The branch head you expect, checked alongside `expected_version`.
</ParamField>

<ParamField body="turns" type="array">
  The ordered turns on the branch to compact, each `{ "role": "...", "content": "..." }`.
</ParamField>

<ParamField body="keep_recent_turns" type="integer" default="4">
  How many of the most recent turns to keep verbatim (the tail).
</ParamField>

<ParamField body="trigger_min_tokens" type="integer" default="2000">
  Skip compaction (no-op) when the context is below this many approximate tokens.
</ParamField>

<ParamField body="model" type="string">
  The model to summarize with. Defaults to `auto.cheapest`.
</ParamField>

```json
{
  "object": "branch.compaction",
  "compacted": true,
  "session_id": "ses_01jy...",
  "branch_id": "br_01jy...",
  "summary_artifact": { "id": "art_01jy...", "artifact_type": "compaction_summary" },
  "checkpoint_event": { "id": "evt_01jy...", "event_type": "checkpoint", "payload_ref": "art_01jy..." },
  "snapshot": { "id": "snp_01jy...", "ordered_block_manifest": ["art_01jy...", "retained_turn_9", "retained_turn_10", "retained_turn_11"] },
  "retention": {
    "summarized_turns": 9,
    "retained_turns": 3,
    "original_tokens": 4200,
    "summary_tokens": 410,
    "reduction_pct": 90.2,
    "summary_live": true
  },
  "recovery": "Original events are retained (append-only); fork a branch from before the checkpoint event to recover the pre-compaction state.",
  "model": "gemini/gemini-2.0-flash"
}
```

<ResponseField name="compacted" type="boolean">
  `false` when the context was below the trigger or had fewer turns than the tail (a no-op with a `reason`); `true` otherwise.
</ResponseField>

<ResponseField name="summary_artifact" type="object">
  The persisted `compaction_summary` artifact.
</ResponseField>

<ResponseField name="checkpoint_event" type="object">
  The `checkpoint` event appended to the branch, referencing the summary artifact.
</ResponseField>

<ResponseField name="snapshot" type="object">
  The compacted snapshot: the summary block followed by stable labels for the retained tail.
</ResponseField>

<ResponseField name="retention" type="object">
  Counts and token reduction for the compaction.
</ResponseField>

<ResponseField name="recovery" type="string">
  How to recover the pre-compaction state.
</ResponseField>

## Errors [#errors]

| Status | Code                      | When                                                                |
| ------ | ------------------------- | ------------------------------------------------------------------- |
| 401    | `invalid_api_key`         | Missing or invalid API key.                                         |
| 404    | `invalid_request_error`   | The session, branch, or snapshot does not exist in this project.    |
| 409    | `branch_version_conflict` | The branch moved since `expected_version`/`expected_head_event_id`. |
| 429    | `quota_exceeded`          | The account is out of budget for the compaction model call.         |

See the full table on [errors](/api-reference/errors).
