> For the complete documentation index, see [llms.txt](https://docs.envector.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.envector.io/1.5.x/sdk-user-guide/advanced-user-guide/backup-restore.md).

# Backup & Restore

Backup / Restore exports and restores an entire enVector instance — **all indexes and their keys** — to and from external storage across instance boundaries, covering migration, maintenance/version upgrades, and disaster recovery.

> **Currently admin-only and system-scoped.** Backup/restore operates on the whole instance — importing the entire bundle or nothing (restoring a subset of indexes is not currently supported). Operators invoke the API over REST with `curl` / automation scripts (native gRPC clients work identically). All paths live under `/admin/` and require an **admin token** (see [Authentication](/1.5.x/operations-and-management/authentication.md)).

## Export modes

The one design-level choice at export time is `mode`, driven by the storage relationship between source and target:

| Mode                                  | What it contains                                                       | When to use                                                                                                        |
| ------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `FULL` (`EXPORT_MODE_FULL`)           | DB records **+** storage blobs embedded in the bundle (self-contained) | Storage changes or differs — cross-cloud, MinIO↔S3, provider swap, air-gapped transfer. Required across providers. |
| `REFERENCE` (`EXPORT_MODE_REFERENCE`) | DB records only; blobs keep pointing at the source storage             | Same storage reused as-is (fast path for in-place maintenance). Source and target must share the storage.          |

## Options

All scenarios share one flow; the operator's decisions reduce to a few flags:

| Flag                        | Values                     | Meaning                                                                                                                                                        |
| --------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mode`                      | `FULL` / `REFERENCE`       | See above                                                                                                                                                      |
| `overwrite`                 | `false` (default) / `true` | `false` for a fresh target. `true` restores over existing state — **destructive**, and additionally requires the `X-Confirm-Destructive: yes` header at commit |
| `skip_restore_loaded_state` | `false` (default) / `true` | `false` auto-loads any index whose `was_loaded=true` in the manifest (so you don't manually reload). `true` opts into manual loading                           |

> **`is_loaded` is restored by default.** Indexes loaded at export time auto-load after import — like a new instance launched from an AMI coming up in the prior state.

## REST API

| Operation        | Method + Path                                                                        |
| ---------------- | ------------------------------------------------------------------------------------ |
| Export bundle    | `POST /admin/export` (server-stream; pipe through `tar -xz`)                         |
| Preflight import | `POST /admin/imports` (returns `import_id`)                                          |
| Upload part      | `PUT /admin/imports/{import_id}/parts/{part_path}` (one PUT per part, parallel-safe) |
| Commit import    | `POST /admin/imports/{import_id}/commit`                                             |
| Get status       | `GET /admin/imports/{import_id}`                                                     |
| List imports     | `GET /admin/imports`                                                                 |
| Cancel import    | `DELETE /admin/imports/{import_id}`                                                  |

### Export

The server tars the bundle directory into the HTTP response body; pipe it into `tar -xz` to land the multi-part directory on disk.

```bash
mkdir -p ./bundle-2026-04-26

# FULL: blobs embedded (portable, self-contained)
curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" --data '{"mode":"EXPORT_MODE_FULL"}' \
  https://source/admin/export | tar -xz -C ./bundle-2026-04-26

# REFERENCE: lightweight, blobs stay at source
curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" --data '{"mode":"EXPORT_MODE_REFERENCE"}' \
  https://source/admin/export | tar -xz -C ./bundle-2026-04-26-ref
```

Integrity: the bundle's `manifest.json` carries `bundle_root_sha256` (concatenation of per-part sha256s), which covers the whole bundle. Each part is also verified by its own sha256 at upload time.

### Import (three-step)

Import is a **Preflight → Upload parts → Commit** workflow. The upload phase is resumable — re-running skips already-received parts (idempotent).

```bash
# Step 1 — Preflight: validate the manifest and allocate an import_id
MANIFEST=$(cat ./bundle-2026-04-26/manifest.json)
ROOT_SHA=$(echo "$MANIFEST" | jq -r .bundle_root_sha256)

PREFLIGHT=$(curl -sS -X POST 'https://target/admin/imports' \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
  --data "$(jq -n --arg m "$(echo "$MANIFEST" | base64 -w0)" --arg sha "$ROOT_SHA" \
    '{manifest_json:$m, overwrite:false, expected_root_sha256:$sha}')")

# Re-importing the same bundle short-circuits safely:
[ "$(echo "$PREFLIGHT" | jq -r .already_done)" = "true" ] && { echo "Already imported"; exit 0; }
IMPORT_ID=$(echo "$PREFLIGHT" | jq -r .import_id)

# Step 2 — Upload every part (parallel; excludes manifest.json, sent in preflight)
cd ./bundle-2026-04-26
find . -type f ! -name manifest.json | sed 's|^\./||' | xargs -P 8 -I {} bash -c '
  P="{}"; SHA=$(sha256sum "$P" | cut -d" " -f1); SIZE=$(stat -c%s "$P")
  curl -sS -X PUT \
    "https://target/admin/imports/'"$IMPORT_ID"'/parts/${P}?expectedSha256=${SHA}&expectedSize=${SIZE}" \
    -H "Authorization: Bearer '"$ADMIN_TOKEN"'" \
    -H "Content-Type: application/octet-stream" --data-binary @"$P"'

# Step 3 — Commit (runs the DB transaction + status flip)
curl -sS -X POST "https://target/admin/imports/$IMPORT_ID/commit" \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
  --data '{"skip_restore_loaded_state": false, "skip_verify_blobs": false}' | jq .
```

**Destructive restore:** set `"overwrite": true` in the preflight body and add `-H "X-Confirm-Destructive: yes"` on the commit call.

Poll `GET /admin/imports/{import_id}` for status. Global concurrent imports are limited to 1 (enforced at preflight), and export ↔ import-commit are serialized instance-wide.

## Notes

* Export drains and then blocks inserts across all indexes during quiesce; **search remains available**.
* Storage backup is always a **full snapshot** (no incremental backups).
* The keys included in a bundle are the **public keys** (evaluation / encryption) referenced by the bundled indexes. There is no keys-only or metadata-only mode.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.envector.io/1.5.x/sdk-user-guide/advanced-user-guide/backup-restore.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
