> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixpeek.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Backup and Restore

> Snapshot a namespace, check the snapshot, and restore it beside the source, to a point in time, or in place

A snapshot captures a namespace's configuration, documents, vectors and a manifest of its bucket objects. You restore a snapshot into a new namespace beside the source, or over the source itself.

Every call takes your API key in `Authorization: Bearer`. The path names the source namespace by id or name.

## Take a snapshot

```python Python theme={null}
import os, requests

BASE = "https://api.mixpeek.com/v1/namespaces/my-namespace"
H = {"Authorization": f"Bearer {os.environ['MIXPEEK_API_KEY']}"}

snap = requests.post(f"{BASE}/snapshots", headers=H, json={"copy_s3_objects": True}).json()
snapshot_id = snap["snapshot_id"]
```

```javascript JavaScript theme={null}
const BASE = "https://api.mixpeek.com/v1/namespaces/my-namespace";
const H = {
  Authorization: `Bearer ${process.env.MIXPEEK_API_KEY}`,
  "Content-Type": "application/json",
};

const snap = await fetch(`${BASE}/snapshots`, {
  method: "POST",
  headers: H,
  body: JSON.stringify({ copy_s3_objects: true }),
}).then((r) => r.json());
const snapshotId = snap.snapshot_id;
```

```bash cURL theme={null}
curl -X POST "https://api.mixpeek.com/v1/namespaces/my-namespace/snapshots" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"copy_s3_objects": true}'
```

`copy_s3_objects` copies the bucket objects into the snapshot. Without it, the snapshot lists the objects and a restore reads them from the bucket. Set it if you might delete the namespace and restore it later.

The snapshot runs in the background. `GET /v1/namespaces/{namespace}/snapshots/{snapshot_id}` shows its status.

## Check that it can restore

```python Python theme={null}
report = requests.get(f"{BASE}/snapshots/{snapshot_id}/verify", headers=H, params={"deep": "true"}).json()
```

```javascript JavaScript theme={null}
const report = await fetch(`${BASE}/snapshots/${snapshotId}/verify?deep=true`, { headers: H }).then((r) => r.json());
```

```bash cURL theme={null}
curl "https://api.mixpeek.com/v1/namespaces/my-namespace/snapshots/$SNAPSHOT_ID/verify?deep=true" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY"
```

Verify reads the snapshot and changes nothing. It lists what a restore would drop: a missing collection dump, unreachable vectors, or objects that are gone. `deep=true` also opens every collection dump and checks it is complete. After a restore from the snapshot, verify also returns that restore's report.

## Restore beside the source

Name a new namespace in `target_namespace_name`. The source keeps running and is not touched.

```python Python theme={null}
task = requests.post(
    f"{BASE}/snapshots/{snapshot_id}/restore",
    headers=H,
    json={"target_namespace_name": "my-namespace-restored"},
).json()
```

```javascript JavaScript theme={null}
const task = await fetch(`${BASE}/snapshots/${snapshotId}/restore`, {
  method: "POST",
  headers: H,
  body: JSON.stringify({ target_namespace_name: "my-namespace-restored" }),
}).then((r) => r.json());
```

```bash cURL theme={null}
curl -X POST "https://api.mixpeek.com/v1/namespaces/my-namespace/snapshots/$SNAPSHOT_ID/restore" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_namespace_name": "my-namespace-restored"}'
```

The response returns a `task_id`. Poll `GET /v1/tasks/{task_id}` until the task completes.

The restored namespace gets new ids, so it never collides with the source. History and telemetry stay with the source: tasks, retriever executions and interactions are not copied.

## Restore to a point in time

`restore_point` restores the namespace as it was at an instant or at a WAL sequence number. It needs `target_namespace_name`.

```python Python theme={null}
requests.post(
    f"{BASE}/snapshots/{snapshot_id}/restore",
    headers=H,
    json={"target_namespace_name": "my-namespace-at-1800", "restore_point": "2026-10-01T18:00:00Z"},
)
```

```javascript JavaScript theme={null}
await fetch(`${BASE}/snapshots/${snapshotId}/restore`, {
  method: "POST",
  headers: H,
  body: JSON.stringify({
    target_namespace_name: "my-namespace-at-1800",
    restore_point: "2026-10-01T18:00:00Z",
  }),
});
```

```bash cURL theme={null}
curl -X POST "https://api.mixpeek.com/v1/namespaces/my-namespace/snapshots/$SNAPSHOT_ID/restore" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_namespace_name": "my-namespace-at-1800", "restore_point": "2026-10-01T18:00:00Z"}'
```

An instant is an RFC 3339 timestamp. Pick a snapshot taken at or before the point, because the restore replays forward from it.

For an instant, the configuration comes back as it was at that instant: the namespace's settings, its buckets, collections and retrievers. Mixpeek records every change to them. A retriever you edited after the snapshot, and edited again after the instant, restores with the value it had at the instant. For a WAL sequence number, the configuration is the snapshot's.

The configuration history keeps 31 days. It starts when the namespace is created, or at its first snapshot for a namespace created earlier. An instant the history cannot rebuild exactly is refused, and the error says why:

* `below_config_window`: the instant is before the history starts. The error names the oldest instant you can use.
* `config_history_gap`: a change to the named row was not recorded, so its state after its last recorded change is unknown. The next snapshot of the namespace records the row's current state. Instants after that snapshot restore; instants inside the gap stay refused.

The vectors and payloads come from the write-ahead log, replayed to the point. A restore can reach any point from the vector store's most recent checkpoint up to its newest durable write. A point outside that range is refused, and the error names the oldest and newest instants you can restore to now.

## Restore onto an isolated shard

`"isolated": true` puts the restored copy on a temporary vector shard of its own. It needs `target_namespace_name`. Use it to check or measure a restore without load on the shared shard.

* The isolated shard stops after six hours. Deleting the copy's namespace stops it sooner.
* One isolated copy runs at a time. A second request is refused, and the error names the namespace that holds it.

## Restore in place

Leave out `target_namespace_name` and set `confirm_in_place`. The snapshot's data replaces the namespace's current data.

```python Python theme={null}
requests.post(f"{BASE}/snapshots/{snapshot_id}/restore", headers=H, json={"confirm_in_place": True})
```

```javascript JavaScript theme={null}
await fetch(`${BASE}/snapshots/${snapshotId}/restore`, {
  method: "POST",
  headers: H,
  body: JSON.stringify({ confirm_in_place: true }),
});
```

```bash cURL theme={null}
curl -X POST "https://api.mixpeek.com/v1/namespaces/my-namespace/snapshots/$SNAPSHOT_ID/restore" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"confirm_in_place": true}'
```

The current data is deleted. The namespace is read-only from when the restore is accepted until it finishes. A write in that window gets a 409 that asks you to retry later.

A request without `confirm_in_place` is refused. To switch over with no read-only window, restore beside the source and point your traffic at the new namespace.

## Related

* [Namespaces](https://docs.mixpeek.com/docs/vector-store/namespaces.md)
* [Restore From Snapshot (API reference)](https://docs.mixpeek.com/docs/api-reference/namespace-snapshots/restore-from-snapshot.md)
* [Verify Snapshot Restore Readiness (API reference)](https://docs.mixpeek.com/docs/api-reference/namespace-snapshots/verify-snapshot-restore-readiness.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.