OVPack
August 14, 2026 ยท View on GitHub
The OVPack API imports, exports, backs up, and restores OpenViking data.
API Reference
export_ovpack
Export a resource tree as a .ovpack file.
1. API Implementation Overview
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:
- Verify user permissions
- Traverse resources under the specified URI
- Write content files and the OVPack manifest
- Package into zip format (
.ovpack) - Return as file stream
Format Notes:
- The exported ZIP stores user content unchanged under
<root>/files/and internal metadata under<root>/_ovpack/. - The manifest is stored at
<root>/_ovpack/manifest.json. entries[].pathis relative to the exported root;""means the root directory itself.- File entries include
sizeandsha256;content_sha256covers the sorted file list ofpath,size, andsha256. _ovpack/index_records.jsonlstores portable index scalar fields. Withinclude_vectors=true,_ovpack/dense.f32stores a pure-dense float32 vector snapshot plus embedding metadata; vector indexes whoseVectorIndex.IndexTypeis hybrid do not support vector snapshot export.- Runtime fields such as
id,uri,account_id,created_at,updated_at, andactive_countare regenerated in the target environment and are not restored from the package. - OVPack does not add package-size, file-count, or directory-depth limits; the practical limit comes from ZIP, the storage backend, and the runtime environment.
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 handler
2. Interface and Parameter Description
Parameters
| 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
3. Usage Examples
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_ovpack
Import a .ovpack file.
1. API Implementation Overview
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:
- Verify user permissions
- Parse uploaded
.ovpackfile - Validate manifest metadata, paths, file and directory sets, file sizes, and checksums
- Apply
on_conflict - Import resources to target location and rebuild vectors
Code 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 handler
2. Interface and Parameter Description
Parameters
| 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:
- The API no longer accepts
vectorizeorforce. vector_mode=autorestores a compatible dense snapshot when present, otherwise recomputes vectors.recomputealways ignores package vectors.requirefails unless a compatible dense snapshot is present.- Dense snapshot compatibility checks compare embedding provider, model, input mode, query/document parameters, and dimensions.
- Session files are part of the user namespace (
viking://user/{user_id}/sessions/...) and do not trigger vectorization. on_conflict=failreturns a structured409 CONFLICTwhen the target root already exists.on_conflict=overwritereplaces the existing target root.on_conflict=skipkeeps the existing target root and returns it without writing package contents.skipis root-level, not file-level.- Packages without a manifest are rejected by default because they cannot provide content integrity guarantees.
- Packages with manifest entries are rejected if content files or directories are missing, extra files or directories are present, file sizes differ, per-file
sha256differs, orcontent_sha256is missing or differs. - Packages whose manifest
format_versionis not the current supported version (3) are rejected. .abstract.mdand.overview.mdare restored as semantic sidecars..relations.jsonand OVPack internals are excluded.- Manifest
context_type, when present in index scalar metadata, must match the final import path semantics. - Top-level scope packages such as
viking://resources/must be imported toviking://. - OVPack does not add import package-size, file-count, or directory-depth limits; the practical limit comes from ZIP, the storage backend, and the runtime environment.
3. Usage Examples
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"
}
}
}
backup_ovpack
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_ovpack
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.
Related Documentation
- OVPack Guide - format, migration, and workflows
- Snapshots - workspace version management
- Temporary Upload - upload packages before import