docs/en/api/14-ovpack.md
The OVPack API imports, exports, backs up, and restores OpenViking data.
Export a resource tree as a .ovpack file.
Packages all resources under the specified URI into a .ovpack file for backup or migration. Available to ROOT, ADMIN, and USER roles; normal URI access controls still apply.
Processing Flow:
.ovpack)Format Notes:
<root>/files/ and internal metadata under <root>/_ovpack/.<root>/_ovpack/manifest.json.entries[].path is relative to the exported root; "" means the root directory itself.size and sha256; content_sha256 covers the sorted file list of path, size, and sha256._ovpack/index_records.jsonl stores portable index scalar fields. With include_vectors=true, _ovpack/dense.f32 stores a pure-dense float32 vector snapshot plus embedding metadata; vector indexes whose VectorIndex.IndexType is hybrid do not support vector snapshot export.id, uri, account_id, created_at, updated_at, and active_count are regenerated in the target environment and are not restored from the package.Code Entry Points:
openviking/server/routers/pack.py:export_ovpack - HTTP routeropenviking/service/pack_service.py - Core service implementationcrates/ov_cli/src/handlers.rs:handle_export - CLI handlerParameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| uri | string | Yes | - | Viking URI to export |
| include_vectors | boolean | No | false | Include a pure-dense vector snapshot; hybrid index types are rejected |
Permission Requirements: ROOT, ADMIN, or USER
HTTP API
POST /api/v1/pack/export
Content-Type: application/json
curl -X POST http://localhost:1933/api/v1/pack/export \
-H "Content-Type: application/json" \
-H "X-API-Key: your-admin-key" \
-d '{
"uri": "viking://resources/my-project/",
"include_vectors": false
}' \
--output my-project.ovpack
Python SDK
import openviking as ov
client = ov.SyncHTTPClient(url="http://localhost:1933", api_key="your-admin-key")
client.initialize()
# Export to local file (HTTP SDK automatically handles download)
# Note: Export functionality is primarily used via CLI
TypeScript SDK
const outputPath = await client.exportOVPack(
"viking://resources/docs/",
"./exports/docs.ovpack",
true,
);
console.log(outputPath);
Go SDK
outPath, err := client.ExportOVPack(
ctx,
"viking://resources/my-project/",
"./exports/my-project.ovpack",
&openviking.PackOptions{IncludeVectors: false},
)
if err != nil {
return err
}
fmt.Println(outPath)
CLI
# Export resource
ov export viking://resources/my-project/ ./exports/my-project.ovpack
# Export with a dense vector snapshot
ov export viking://resources/my-project/ ./exports/my-project.ovpack --include-vectors
Response Example
This endpoint directly returns a file stream (Content-Type: application/zip), does not return a JSON envelope.
Import a .ovpack file.
Imports a .ovpack file to a specified location for restoring or migrating data. Available to ROOT, ADMIN, and USER roles; normal URI access controls still apply.
Processing Flow:
.ovpack fileon_conflictCode Entry Points:
openviking/server/routers/pack.py:import_ovpack - HTTP routeropenviking/service/pack_service.py - Core service implementationcrates/ov_cli/src/handlers.rs:handle_import - CLI handlerParameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| temp_file_id | string | Yes | - | Temporary upload file ID (obtained via temp_upload) |
| parent | string | Yes | - | Target parent URI (import to this location) |
| on_conflict | string | No | fail | Conflict policy: fail, overwrite, or skip |
| vector_mode | string | No | auto | Vector handling: auto, recompute, or require |
Permission Requirements: ROOT, ADMIN, or USER
Behavior Notes:
vectorize or force.vector_mode=auto restores a compatible dense snapshot when present, otherwise recomputes vectors. recompute always ignores package vectors. require fails unless a compatible dense snapshot is present.viking://user/{user_id}/sessions/...) and do not trigger vectorization.on_conflict=fail returns a structured 409 CONFLICT when the target root already exists.on_conflict=overwrite replaces the existing target root. on_conflict=skip keeps the existing target root and returns it without writing package contents. skip is root-level, not file-level.sha256 differs, or content_sha256 is missing or differs.format_version is not the current supported version (3) are rejected..abstract.md and .overview.md are restored as semantic sidecars. .relations.json and OVPack internals are excluded.context_type, when present in index scalar metadata, must match the final import path semantics.viking://resources/ must be imported to viking://.HTTP API
POST /api/v1/pack/import
Content-Type: application/json
# Step 1: Upload .ovpack file
TEMP_FILE_ID=$(
curl -s -X POST http://localhost:1933/api/v1/resources/temp_upload \
-H "X-API-Key: your-admin-key" \
-F "file=@./exports/my-project.ovpack" \
| jq -r '.result.temp_file_id'
)
# Step 2: Import
curl -X POST http://localhost:1933/api/v1/pack/import \
-H "Content-Type: application/json" \
-H "X-API-Key: your-admin-key" \
-d "{
\"temp_file_id\": \"$TEMP_FILE_ID\",
\"parent\": \"viking://resources/imported/\",
\"on_conflict\": \"overwrite\",
\"vector_mode\": \"auto\"
}"
Python SDK
import openviking as ov
client = ov.SyncHTTPClient(url="http://localhost:1933", api_key="your-admin-key")
client.initialize()
# Import .ovpack file (HTTP SDK automatically handles upload)
# Note: Import functionality is primarily used via CLI
TypeScript SDK
const uri = await client.importOVPack(
"./exports/docs.ovpack",
"viking://resources/",
{
onConflict: "overwrite",
vectorMode: "auto",
},
);
console.log(uri);
Go SDK
uri, err := client.ImportOVPack(
ctx,
"./exports/my-project.ovpack",
"viking://resources/imported/",
&openviking.ImportPackOptions{
OnConflict: "overwrite",
VectorMode: "auto",
},
)
if err != nil {
return err
}
fmt.Println(uri)
CLI
# Import .ovpack file
ov import ./exports/my-project.ovpack viking://resources/imported/
# Explicit conflict policy
ov import ./exports/my-project.ovpack viking://resources/imported/ --on-conflict overwrite
# Require restoring a compatible dense vector snapshot
ov import ./exports/my-project.ovpack viking://resources/imported/ --vector-mode require
Response Example
{
"status": "ok",
"result": {
"uri": "viking://resources/imported/my-project/"
},
"telemetry": {
"operation_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Conflict Error Example
{
"status": "error",
"error": {
"code": "CONFLICT",
"message": "Resource already exists at viking://resources/imported/my-project. Use on_conflict='overwrite' to replace it.",
"details": {
"resource": "viking://resources/imported/my-project"
}
}
}
Back up public scope roots as a restore-only .ovpack file. The backup includes
resources and all user/{user_id} content in the current account; sessions
are included through the user namespace under user/{user_id}/sessions. It
excludes internal runtime data such as temp and queue, as well as user
accounts and API keys. Only ROOT or ADMIN can call this endpoint. Set
include_vectors=true to include compatible
pure-dense vector snapshots; hybrid index types reject vector snapshot export.
Backup reads live files and does not provide an atomic point-in-time snapshot. Callers that require strict consistency should pause writes during the backup window.
POST /api/v1/pack/backup
curl -X POST http://localhost:1933/api/v1/pack/backup \
-H "Content-Type: application/json" \
-H "X-API-Key: your-admin-key" \
-d '{"include_vectors":false}' \
--output openviking-backup.ovpack
Go SDK:
outPath, err := client.BackupOVPack(
ctx,
"./backups/openviking.ovpack",
&openviking.PackOptions{IncludeVectors: true},
)
if err != nil {
return err
}
fmt.Println(outPath)
CLI:
ov backup ./backups/openviking.ovpack
ov backup ./backups/openviking.ovpack --include-vectors
Response
On HTTP success, the endpoint returns an application/zip byte stream instead of the standard JSON envelope:
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="openviking-backup.ovpack"
<ovpack binary body>
The Go SDK and CLI write the stream to the requested path and return or print that local path.
Restore a backup package created by backup_ovpack to the original public scope
roots. Regular import rejects backup packages. Vector handling follows
vector_mode; session files under the user namespace are restored without
vectorization. Only ROOT or ADMIN can call this endpoint, and it restores all
packaged user paths in the current account.
on_conflict=overwrite performs a merge-upsert: package paths missing from the
target are created, matching paths are overwritten, and target-only paths are
preserved. It does not delete the full viking://resources or viking://user
tree. Only added or overwritten package content has its vectors updated. skip
remains a scope-root-level skip, but the complete manifest, content checksums,
and vector metadata are validated before it can return. Corrupt backups fail
even with skip.
OVPack does not create user accounts or restore API keys. After restoring into
a new environment, create users with the same packaged user_id values and use
the API keys generated by the target environment.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| temp_file_id | string | Yes | - | Temporary upload file ID |
| on_conflict | string | No | fail | Conflict policy: fail, overwrite, or skip |
| vector_mode | string | No | auto | Vector handling: auto, recompute, or require |
POST /api/v1/pack/restore
Content-Type: application/json
TEMP_FILE_ID=$(
curl -s -X POST http://localhost:1933/api/v1/resources/temp_upload \
-H "X-API-Key: your-admin-key" \
-F "file=@./backups/openviking.ovpack" \
| jq -r '.result.temp_file_id'
)
curl -X POST http://localhost:1933/api/v1/pack/restore \
-H "Content-Type: application/json" \
-H "X-API-Key: your-admin-key" \
-d "{\"temp_file_id\":\"$TEMP_FILE_ID\",\"on_conflict\":\"overwrite\",\"vector_mode\":\"auto\"}"
Go SDK:
uri, err := client.RestoreOVPack(
ctx,
"./backups/openviking.ovpack",
&openviking.ImportPackOptions{
OnConflict: "overwrite",
VectorMode: "require",
},
)
if err != nil {
return err
}
fmt.Println(uri)
CLI:
ov restore ./backups/openviking.ovpack --on-conflict overwrite
ov restore ./backups/openviking.ovpack --on-conflict overwrite --vector-mode require
Response
{
"status": "ok",
"result": {
"uri": "viking://"
}
}
uri is the public scope root restored from the backup.