Overview
Vaults are encrypted containers for storing sensitive data. Unlike Sparks (which are ephemeral and read-once), Vaults provide persistent storage that you can access repeatedly.
Key Concepts
| Term | Description |
|---|---|
| Vault | An encrypted container that holds multiple Ingots |
| Ingot | An individual encrypted file or data blob stored in a Vault |
| Standard Ingot | A file-based ingot (PDF, image, document, etc.) |
| Structured Ingot | A key/value data store (up to 10,000 keys) for structured data like PII fields |
| VMK | Vault Master Key. The secret key required to access vault contents. |
| VAT | Vault Access Token. A temporary session token for vault operations. |
| DVAK | Delegated Vault Access Key. A revocable credential that unseals a vault in place of the VMK. |
| Sealed | Vault state where contents are encrypted and inaccessible |
| Unsealed | Vault state where contents can be read/written (requires active VAT) |
The Vault Master Key (VMK) is only shown once when you create a vault. SparkVault does not store the VMK and cannot recover it if lost. The one sanctioned delegation path is a DVAK issued while you still hold the VMK: a DVAK can unseal the vault later without it.
Always store VMKs in a secure password manager or hardware security module (HSM).
Vault Lifecycle
Working with vaults follows this flow:
- Create: Create a vault and receive the VMK (save it securely!)
- Unseal: Provide the VMK to get a temporary VAT (1-hour default, up to 24 hours)
- Read/Write: Use the VAT to create, read, update, or delete Ingots
- Seal: (Optional) Manually seal to invalidate all VATs, or let them expire
# 1. Create a vault
curl -X POST https://api.sparkvault.com/v1/vaults \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"name": "Production Secrets"}'
# Returns: vault_id and vmk (SAVE THE VMK!)
# 2. Unseal the vault to get a VAT
curl -X POST https://api.sparkvault.com/v1/vaults/{vault_id}/unseal \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"vmk": "YOUR_VMK_HERE"}'
# Returns: vat (valid for 1 hour by default, up to 24 hours)
# 3. Create an ingot (upload data)
curl -X POST https://api.sparkvault.com/v1/vaults/{vault_id}/ingots \
-H "X-API-Key: sv_live_xxx" \
-H "X-Vault-Access-Token: YOUR_VAT" \
-H "Content-Type: application/json" \
-d '{"name": "config.json", "size_bytes": 1024}'
# Returns: forge_url for upload
# 4. Upload file to Forge with tus protocol
# Use the ISTK from forge_url as X-ISTK when creating the tus upload session
Create Vault
/v1/vaults
Create a new encrypted vault. Returns the Vault Master Key (VMK) which is required to access the vault. The VMK is only shown once.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Required | Human-readable vault name. Max 200 characters. Must be unique within the account (uniqueness is case-insensitive); a duplicate returns 409 CONFLICT. |
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Unique vault identifier (vlt_...) |
name |
string | Vault name |
vmk |
string | Vault Master Key. SAVE THIS! Never shown again. |
vmk_warning |
string | Warning message about VMK security |
created_at |
integer | Unix timestamp of creation |
Example
Requestcurl -X POST https://api.sparkvault.com/v1/vaults \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"name": "Production Secrets"}'
{
"data": {
"vault_id": "vlt_abc123def456...",
"name": "Production Secrets",
"vmk": "X9k2P8mQ7vH5nL3wR6tY...",
"vmk_warning": "SAVE THIS KEY! SparkVault cannot recover it if lost. Store securely.",
"created_at": 1702000000
}
}
The VMK is shown only once in the response. If you lose it, all data in the vault is permanently inaccessible. Store it immediately in a secure location.
List Vaults
/v1/vaults
List all vaults in your account. Results are paginated.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
integer | Optional | Maximum number of vaults to return (max 500).Default: 100 |
cursor |
string | Optional | Signed pagination cursor from a previous response (next_cursor). |
status |
string | Optional | Filter by stored vault status (e.g. active). Note this is the stored status, not the displayed sealed/unsealed value. |
Response
| Field | Type | Description |
|---|---|---|
vaults |
array | Array of vault objects |
vaults[].vault_id |
string | Vault identifier |
vaults[].name |
string | Vault name |
vaults[].status |
string | Vault status. Active vaults display as sealed in list view. Use Get Vault for live sealed/unsealed status. |
vaults[].ingot_count |
integer | Number of ingots in vault |
vaults[].storage_bytes |
integer | Total storage used in bytes |
vaults[].total_access_count |
integer | Total ingot accesses recorded for the vault |
vaults[].total_bandwidth_bytes |
integer | Total transfer bandwidth recorded for the vault, in bytes |
vaults[].created_at |
integer | Creation timestamp |
count |
integer | Number of vaults in this page |
has_more |
boolean | Whether more pages are available |
next_cursor |
string | Cursor for the next page (present when has_more is true) |
Get Vault
/v1/vaults/{vault_id}
Get details about a specific vault.
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
name |
string | Vault name |
description |
string | Vault description |
status |
string | sealed or unsealed, derived from whether any VAT session is currently active |
ingot_count |
integer | Number of ingots |
storage_bytes |
integer | Total storage used |
created_at |
integer | Creation timestamp |
created_by_user_id |
string | User who created the vault |
last_unsealed_at |
integer | Unix timestamp of the most recent unseal (null if never unsealed) |
unseal_count |
integer | Number of times the vault has been unsealed |
Update Vault
/v1/vaults/{vault_id}
Update vault metadata (name and/or description). At least one field is required.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Optional | New vault name. Max 200 characters; must be unique within the account (case-insensitive); a duplicate returns 409 CONFLICT. |
description |
string | Optional | New vault description. Max 1000 characters. Pass null to clear. |
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
name |
string | Vault name |
description |
string | Vault description |
updated_at |
integer | Update timestamp |
Unseal Vault
/v1/vaults/{vault_id}/unseal
Unseal a vault by providing the VMK (or a DVAK). Returns a Vault Access Token (VAT) for accessing ingots. The VAT is valid for 1 hour by default, configurable up to 24 hours.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
vmk |
string | Required | The Vault Master Key from vault creation, or a DVAK token (prefix dvak_) issued for this vault. With a DVAK, the API recovers the VMK server-side; the resulting VAT inherits the DVAK's access level (read or read_write). Direct VMK unseal yields a full read+write VAT. |
ttl_seconds |
integer | Optional | VAT lifetime in seconds (default: 3600, max: 86400) |
Response
| Field | Type | Description |
|---|---|---|
vat |
string | Vault Access Token for ingot operations |
vault_id |
string | Vault identifier |
issued_at |
integer | Unix timestamp when VAT was issued |
expires_at |
integer | Unix timestamp when VAT expires |
ttl_seconds |
integer | VAT lifetime in seconds |
warning |
string | Security reminder about VAT usage |
Example
Requestcurl -X POST https://api.sparkvault.com/v1/vaults/vlt_abc123/unseal \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"vmk": "X9k2P8mQ7vH5nL3wR6tY..."}'
{
"data": {
"vat": "vat_xyz789...",
"vault_id": "vlt_abc123def456...",
"issued_at": 1702000000,
"expires_at": 1702003600,
"ttl_seconds": 3600,
"warning": "Store this VAT securely. Required for all Ingot operations until expiration."
}
}
Include the VAT in the X-Vault-Access-Token header for all ingot operations. You can request new VATs at any time; previous VATs remain valid until they expire.
Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED |
The provided DVAK is invalid or has been revoked |
| 403 | FORBIDDEN |
The DVAK is not authorized for the requesting user |
| 412 | PRECONDITION_FAILED |
Invalid VMK: the provided VMK is incorrect for this vault |
Delegated Vault Access Keys (DVAKs)
DVAKs let vault admins delegate unseal access without sharing the VMK. A DVAK is used
in place of the VMK in the Unseal Vault request body: the API
recovers the VMK server-side and mints a VAT whose access level (read or
read_write) is inherited from the DVAK. The full DVAK token is shown
once at creation; afterwards only its last 4 characters are visible.
| Type | Description |
|---|---|
| user | Issued to a specific team member; usable only by that user |
| nhi | Issued to a Non-Human Identity (bot, AI agent, service), labelled with a free-text description |
| system | Internal keys minted automatically for vault features (sharing, upload portal, upload widget), never created through this endpoint |
All DVAK management operations require the admin role; non-admin callers receive 403 FORBIDDEN. Creating a DVAK requires the VMK, which is verified against the vault.
Create DVAK
/v1/vaults/{vault_id}/dvaks
Create a User or NHI DVAK for a vault. Requires the VMK. The full DVAK token is returned once and never shown again.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
vmk |
string | Required | The Vault Master Key, verified before the DVAK is issued |
dvak_type |
string | Optional | user or nhiDefault: user |
authorized_user_id |
string | Optional | User authorized to use this DVAK. Required when dvak_type is user; the user must belong to your account. |
nhi_description |
string | Optional | What the non-human identity uses the key for. Required when dvak_type is nhi. |
access_level |
string | Optional | read or read_write. Issuers on a Viewer (read-only) seat can only mint read DVAKs.Default: read_write |
Response
| Field | Type | Description |
|---|---|---|
dvak_token |
string | The full DVAK token (dvak_...). Shown only once. |
dvak_type |
string | user or nhi |
authorized_user_id |
string | Authorized user (user DVAKs; null for NHI) |
authorized_user_email |
string | Authorized user's email (user DVAKs; null for NHI) |
nhi_description |
string | NHI description (null for user DVAKs) |
last_4_chars |
string | Last 4 characters of the token, used to identify and revoke the DVAK |
created_at |
integer | Creation timestamp |
warning |
string | Reminder that the token is not shown again |
Example: create a DVAK, then unseal with it
Request# Issue a read-only DVAK to a teammate
curl -X POST https://api.sparkvault.com/v1/vaults/vlt_abc123/dvaks \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"vmk": "X9k2P8mQ7vH5nL3wR6tY...", "dvak_type": "user", "authorized_user_id": "usr_def456", "access_level": "read"}'
# The teammate unseals with the DVAK instead of the VMK
curl -X POST https://api.sparkvault.com/v1/vaults/vlt_abc123/unseal \
-H "X-API-Key: sv_live_yyy" \
-H "Content-Type: application/json" \
-d '{"vmk": "dvak_kQ8n...w2Xz"}'
List DVAKs
/v1/vaults/{vault_id}/dvaks
List DVAKs for a vault. Full tokens are never returned, only the last 4 characters.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
integer | Optional | Maximum items to return (max 100)Default: 25 |
cursor |
string | Optional | Pagination cursor from a previous response |
status |
string | Optional | Filter by status: active or revoked |
Response
| Field | Type | Description |
|---|---|---|
dvaks |
array | Array of DVAK objects |
dvaks[].last_4_chars |
string | Last 4 characters of the token |
dvaks[].dvak_type |
string | user, nhi, or system |
dvaks[].authorized_user_id |
string | Authorized user (user DVAKs) |
dvaks[].authorized_user_email |
string | Authorized user's email (user DVAKs) |
dvaks[].system_purpose |
string | Feature a system DVAK serves (sharing, upload_portal, upload_widget) |
dvaks[].nhi_description |
string | NHI description (NHI DVAKs) |
dvaks[].status |
string | active or revoked |
dvaks[].created_at |
integer | Creation timestamp |
dvaks[].last_used_at |
integer | Timestamp of most recent use |
dvaks[].use_count |
integer | Number of times the DVAK has been used |
has_more |
boolean | Whether more pages are available |
cursor |
string | Cursor for the next page |
Revoke DVAK
/v1/vaults/{vault_id}/dvaks/{last4}
Revoke a DVAK by its last 4 characters. A revoked DVAK can no longer unseal the vault.
Response
| Field | Type | Description |
|---|---|---|
last_4_chars |
string | Last 4 characters of the revoked DVAK |
status |
string | Always revoked |
revoked_at |
integer | Revocation timestamp |
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR |
DVAK is already revoked, or last4 is not exactly 4 characters |
| 404 | NOT_FOUND |
No DVAK with those last 4 characters exists for this vault |
Seal Vault
/v1/vaults/{vault_id}/seal
Manually seal a vault, immediately invalidating all active VATs. This is optional. Vaults automatically seal when all VATs expire.
Manual sealing is typically only needed for emergency revocation if you believe a VAT has been compromised. Normal usage should let VATs expire naturally.
Example
Requestcurl -X POST https://api.sparkvault.com/v1/vaults/vlt_abc123/seal \
-H "X-API-Key: sv_live_xxx"
(204 No Content)
Delete Vault
/v1/vaults/{vault_id}
Delete a vault and all its contents. Deletion is asynchronous: the API returns 202 Accepted and a cascade worker removes ingots, folders, audit logs, DVAKs, SparkLinks, and stored objects in phases. This action is irreversible.
Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Confirm-Name |
string | Required | Must match the vault name exactly (case-sensitive) to confirm deletion. A mismatch returns 400 VALIDATION_ERROR. |
Response (202 Accepted)
| Field | Type | Description |
|---|---|---|
message |
string | Confirmation that the deletion cascade has been enqueued |
vault_id |
string | Vault identifier |
started_at |
integer | Unix timestamp when the deletion cascade started |
Deleting a vault permanently destroys all encrypted data. This cannot be undone. The X-Confirm-Name header is required as a safety measure.
Repeating the DELETE while a deletion cascade is already in progress returns 202 again with the original started_at. It does not restart the cascade. The vault disappears from list and get responses as soon as deletion begins.
Example
Requestcurl -X DELETE https://api.sparkvault.com/v1/vaults/vlt_abc123 \
-H "X-API-Key: sv_live_xxx" \
-H "X-Confirm-Name: Production Secrets"
{
"data": {
"message": "Vault deletion enqueued; cascade will run asynchronously",
"vault_id": "vlt_abc123def456...",
"started_at": 1702000000
}
}
Ingot Operations
Once a vault is unsealed, you can create, read, update, and delete Ingots (encrypted data objects). SparkVault supports two types of ingots:
| Type | Description | Use Case |
|---|---|---|
| Standard Ingots | File-based encrypted storage (PDF, images, documents, etc.) | Store any file up to 5 TB |
| Structured Ingots | Key/value data store (up to 10,000 keys) | PII fields, credentials, structured sensitive data |
See the Ingots API Documentation for complete details on creating, reading, updating, and deleting ingots.
Folders
Folders provide hierarchical organization within a vault. All folder operations require an
unsealed vault: include a valid VAT in the X-Vault-Access-Token header. A
read-only VAT (minted from a read DVAK) can list and read folders but cannot
create, modify, or delete them (403 FORBIDDEN).
- Folder names: max 255 characters; names starting with
_are reserved for system folders. - Duplicate names within the same parent return
409 CONFLICT. - Maximum nesting depth: 20 levels (enforced across the whole subtree when moving folders).
- System folders cannot be modified, deleted, or used as parents.
Create Folder
/v1/vaults/{vault_id}/folders
Create a folder in a vault. Omit parent_id to create at the root.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Required | Folder name (max 255 characters; cannot start with _) |
parent_id |
string | Optional | Parent folder ID (fld_...). Omit for a root-level folder. |
Response
| Field | Type | Description |
|---|---|---|
folder_id |
string | Unique folder identifier (fld_...) |
name |
string | Folder name |
parent_id |
string | Parent folder ID (null at root) |
pinned |
boolean | Whether the folder is pinned |
created_at |
integer | Creation timestamp |
List Folders
/v1/vaults/{vault_id}/folders
List every folder in the vault as a flat array (build the tree client-side from parent_id).
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
include_system |
boolean | Optional | Set to true to include system foldersDefault: false |
Response
| Field | Type | Description |
|---|---|---|
folders |
array | All folders in the vault, pinned first. Each item: folder_id, name, parent_id, pinned, created_at, updated_at. |
Get Folder
/v1/vaults/{vault_id}/folders/{folder_id}
Get folder details, including its breadcrumb path and subfolder count.
Response
| Field | Type | Description |
|---|---|---|
folder_id |
string | Folder identifier |
name |
string | Folder name |
parent_id |
string | Parent folder ID (null at root) |
pinned |
boolean | Whether the folder is pinned |
created_at |
integer | Creation timestamp |
updated_at |
integer | Last update timestamp |
breadcrumb |
array | Path from the vault root: { folder_id, name } entries, starting with Root (folder_id: null) |
subfolder_count |
integer | Number of direct subfolders |
Update Folder
/v1/vaults/{vault_id}/folders/{folder_id}
Rename, move, or pin/unpin a folder. Returns the updated folder.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Optional | New folder name (same rules as create) |
parent_id |
string | Optional | New parent folder ID; null moves the folder to the root. A folder cannot be moved into its own subtree or into a system folder, and the move must keep every descendant within the 20-level depth limit. |
pinned |
boolean | Optional | Pin or unpin the folder (pinned folders sort first) |
Delete Folder
/v1/vaults/{vault_id}/folders/{folder_id}
Delete a folder and everything inside it, recursively. Deletion is asynchronous: returns 202 Accepted with { message, folder_id, started_at }, and repeating the call while the cascade is in progress returns 202 idempotently.
List Folder Contents
/v1/vaults/{vault_id}/contents
List the subfolders and ingots inside a folder. Omit folder_id to list the vault root.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | Optional | Folder to list. Omit for the vault root. |
include_system |
boolean | Optional | Set to true to include system foldersDefault: false |
sort_by |
string | Optional | Ingot sort column: name, size, content_type, access_count, bandwidth, or createdDefault: created |
sort_order |
string | Optional | asc or descDefault: desc |
Response
| Field | Type | Description |
|---|---|---|
folder |
object | The current folder (folder_id, name, parent_id), null at the root |
breadcrumb |
array | Path from the vault root: { folder_id, name } entries, starting with Root |
folders |
array | Direct subfolders, pinned first |
ingots |
array | Ingots in this folder, sorted per sort_by/sort_order |
Vault Sharing
Vault sharing is the vault-level switch for secure public ingot sharing. Enabling it creates a system DVAK stored encrypted on SparkVault servers, so shared ingots can be decrypted for recipients without your SVMK or AMK. Per-ingot sharing controls (visibility, invitations) are documented on the SparkLinks API.
Get Sharing Configuration
/v1/vaults/{vault_id}/sharing
Get the sharing configuration for a vault.
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
public_sharing_enabled |
boolean | Whether sharing is enabled |
all_ingots_public |
boolean | Whether every ingot in the vault is shareable (vs. per-ingot opt-in) |
session_length_seconds |
integer | Recipient session length in seconds (null when sharing is disabled) |
enabled_at |
integer | Timestamp sharing was enabled (null when disabled) |
Enable Sharing
/v1/vaults/{vault_id}/sharing/enable
Enable secure ingot sharing for a vault. Requires the VMK, unless an upload portal or widget system DVAK is already active. In that case the API recovers and verifies the VMK server-side.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
vmk |
string | Optional | The Vault Master Key. Required unless an upload portal/widget channel with an active system DVAK is already enabled on the vault. |
all_ingots_public |
boolean | Optional | Make every ingot in the vault shareableDefault: false |
session_length_seconds |
integer | Optional | Recipient session length in seconds (min 60, max 86400)Default: 3600 |
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
public_sharing_enabled |
boolean | Always true |
all_ingots_public |
boolean | Effective all-ingots setting |
session_length_seconds |
integer | Effective session length |
enabled_at |
integer | Timestamp sharing was enabled |
security_notice |
string | Reminder that sharing uses a server-held encrypted DVAK |
Enabling sharing stores a delegated vault access key (DVAK) encrypted on SparkVault servers so shared ingots can be decrypted for recipients. Disable sharing to delete this key. Enabling when sharing is already active returns 400 VALIDATION_ERROR.
Update Sharing Configuration
/v1/vaults/{vault_id}/sharing
Update all_ingots_public and/or session_length_seconds without re-entering the VMK. Sharing must already be enabled.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
all_ingots_public |
boolean | Optional | Make every ingot in the vault shareable |
session_length_seconds |
integer | Optional | Recipient session length in seconds (min 60, max 86400) |
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
public_sharing_enabled |
boolean | Always true |
all_ingots_public |
boolean | Effective all-ingots setting |
session_length_seconds |
integer | Effective session length |
updated_at |
integer | Update timestamp |
Disable Sharing
/v1/vaults/{vault_id}/sharing/disable
Disable secure ingot sharing. Revokes every SparkLink for the vault's ingots and deletes the sharing system DVAK.
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
public_sharing_enabled |
boolean | Always false |
disabled_at |
integer | Timestamp sharing was disabled |
shares_revoked |
integer | Number of SparkLinks deleted |
Upload Portal & Widget
Each vault has two optional public upload channels: the hosted Upload Portal
(a page at files.sv for external users) and the embeddable Upload
Widget (drop-zone in your own site via the JavaScript SDK). Enabling a channel mints
its own system DVAK; encryption keys are
derived server-side and only the ISTK reaches the browser. The VMK and VAK never leave the
server. Public uploaders can add files but cannot retrieve them.
To embed the widget, see the JavaScript SDK guide: Use Case: Accept Secure File Uploads.
Get Upload Configuration
/v1/vaults/{vault_id}/upload
Get the upload configuration for a vault: both channels plus the shared settings.
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
upload_portal_enabled |
boolean | Whether the hosted portal is enabled |
upload_portal_enabled_at |
integer | Timestamp the portal was enabled (null when disabled) |
upload_widget_enabled |
boolean | Whether the embeddable widget is enabled |
upload_widget_enabled_at |
integer | Timestamp the widget was enabled (null when disabled) |
max_size_bytes |
integer | Shared per-file size limit for public uploads (null = default) |
notification_email |
string | Email notified on public uploads (null = none) |
portal_url |
string | Public portal URL (https://files.sv/in/...), present only while the portal is enabled |
Update Upload Configuration
/v1/vaults/{vault_id}/upload
Update the shared upload settings (max file size, notification email). These apply to both channels and persist even when both are disabled.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
max_size_bytes |
integer | Optional | Per-file size limit for public uploads. Min 1048576 (1 MB), max 5497558138880 (5 TB, the ingot maximum). |
notification_email |
string | Optional | Email to notify on public uploads. Pass null to clear. |
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
max_size_bytes |
integer | Effective per-file size limit |
notification_email |
string | Effective notification email |
updated_at |
integer | Update timestamp |
Enable / Disable the Upload Portal
/v1/vaults/{vault_id}/upload/portal/enable
Enable the hosted upload portal (files.sv). Requires the VMK in the request body. Returns the public portal_url.
/v1/vaults/{vault_id}/upload/portal/disable
Disable the hosted upload portal and delete its system DVAK.
Request Body (enable)
| Parameter | Type | Required | Description |
|---|---|---|---|
vmk |
string | Required | The Vault Master Key, verified before the channel's system DVAK is created |
Example
Requestcurl -X POST https://api.sparkvault.com/v1/vaults/vlt_abc123/upload/portal/enable \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"vmk": "X9k2P8mQ7vH5nL3wR6tY..."}'
{
"data": {
"vault_id": "vlt_abc123def456...",
"upload_portal_enabled": true,
"enabled_at": 1702000000,
"portal_url": "https://files.sv/in/abc123def456"
}
}
Enable / Disable the Upload Widget
/v1/vaults/{vault_id}/upload/widget/enable
Enable the embeddable SDK upload widget. Requires the VMK in the request body.
/v1/vaults/{vault_id}/upload/widget/disable
Disable the upload widget and delete its system DVAK.
Request Body (enable)
| Parameter | Type | Required | Description |
|---|---|---|---|
vmk |
string | Required | The Vault Master Key, verified before the channel's system DVAK is created |
Enabling a channel that is already enabled and healthy returns 400 VALIDATION_ERROR. If a channel is flagged enabled but its system DVAK is missing or revoked, calling enable again re-provisions the channel with a fresh DVAK. Disable responses return { vault_id, upload_<channel>_enabled: false, disabled_at }; disabling an already-disabled channel returns 400.
Access Log Retention
Configure how long access logs are retained for shared ingots in a vault. Logs count against your pooled storage (see pricing).
Get Access Log Retention
/v1/vaults/{vault_id}/access-log-retention
Get the current access log retention setting for a vault.
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
access_log_retention_seconds |
integer | Retention period in seconds |
Update Access Log Retention
/v1/vaults/{vault_id}/access-log-retention
Update the access log retention period for a vault. Existing logs are not affected. They will expire according to their original TTL.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
access_log_retention_seconds |
integer | Required | Retention period in seconds. Valid values: 0 (disabled), 86400 (24h), 604800 (7d), 2592000 (1mo), 5184000 (2mo), 7776000 (3mo, default), 15552000 (6mo), 23328000 (9mo), 31536000 (1yr), 63072000 (2yr), 94608000 (3yr) |
Response
| Field | Type | Description |
|---|---|---|
vault_id |
string | Vault identifier |
access_log_retention_seconds |
integer | New retention period in seconds |
updated_at |
integer | Update timestamp |
Example
Requestcurl -X PUT https://api.sparkvault.com/v1/vaults/vlt_abc123/access-log-retention \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"access_log_retention_seconds": 31536000}'
{
"data": {
"vault_id": "vlt_abc123def456...",
"access_log_retention_seconds": 31536000,
"updated_at": 1702000000
}
}
Valid retention periods:
0: Disabled (no logging)86400: 24 Hours604800: 7 Days2592000: 1 Month5184000: 2 Months7776000: 3 Months (Default)15552000: 6 Months23328000: 9 Months31536000: 1 Year63072000: 2 Years94608000: 3 Years
Usage
Vault operations are covered by your seat subscription. Storage and bandwidth consumption is tracked against the pool included with your plan. There are no per-operation charges. For subscription tiers and capacity blocks, see the pricing page.
| Operation | Usage |
|---|---|
| Create Vault | Included with subscription |
| Unseal/Seal Vault | Included with subscription |
| Ingot Storage | Counts against pooled storage (included) |
| Access Logs | Counts against pooled storage (included) |
For ingot transfer usage, see the Ingots API Documentation.
Error Reference
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR |
Invalid request parameters (including an X-Confirm-Name mismatch on vault deletion) |
| 401 | AUTHENTICATION_ERROR |
Invalid or missing authentication; missing, invalid, or expired VAT (X-Vault-Access-Token header required / Invalid or expired VAT) |
| 401 | UNAUTHORIZED |
Invalid or revoked DVAK presented to unseal |
| 402 | PLAN_REQUIRED |
An active subscription is required for this operation |
| 402 | QUOTA_EXCEEDED |
Pooled storage or bandwidth exhausted (resource: storage|bandwidth). Add a capacity block |
| 403 | FORBIDDEN |
VAT expired; VAT issued for a different vault or account; read-only VAT attempting a write; DVAK not authorized for this user; admin role required for DVAK management |
| 404 | NOT_FOUND |
Vault, ingot, folder, or DVAK not found |
| 409 | CONFLICT |
Vault name already exists, or duplicate folder name within the same parent |
| 412 | PRECONDITION_FAILED |
Invalid VMK: the provided VMK does not match this vault |
| 413 | PAYLOAD_TOO_LARGE |
File exceeds maximum size (5 TB) |