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
- End or seal: (Optional) End your own session when you are done, seal the vault to end every session at once, or let the VATs 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 | Vaults per page, at most 500; a larger value reads as 500 (Pagination).Default: 100 |
cursor |
string | Optional | Sealed 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[].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 with the key you hold: the Vault Master Key, or a DVAK token. 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 | Optional | The Vault Master Key from vault creation. A DVAK token presented here is accepted too, and read as a DVAK. Unsealing with the VMK yields a full read+write VAT. |
dvak_token |
string | Optional | A DVAK token (prefix dvak_) issued for this vault, exactly as the create response returned it. The API recovers the VMK server-side, and the resulting VAT inherits the DVAK's access level (read or read_write). |
ttl_seconds |
integer | Optional | VAT lifetime in seconds (default: 3600, max: 86400) |
Supply vmk or dvak_token. Never both, and never neither. A request carrying two keys, or none, is rejected with 400 VALIDATION_ERROR.
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
Request# With the Vault Master Key
curl -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..."}'
# With a DVAK token
curl -X POST https://api.sparkvault.com/v1/vaults/vlt_abc123/unseal \
-H "X-API-Key: sv_live_xxx" \
-H "Content-Type: application/json" \
-d '{"dvak_token": "dvak_kQ8n...w2Xz"}'
{
"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 |
|---|---|---|
| 400 | VALIDATION_ERROR |
Both vmk and dvak_token were sent, or neither, or dvak_token is not a well-formed token |
| 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 |
The key provided does not open this vault |
Delegated Vault Access Keys (DVAKs)
DVAKs let vault admins delegate unseal access without sharing the VMK. Send the token as
dvak_token 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 and hold a Full or View Only license (a member with no license is refused 400). |
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. A user DVAK for a View Only member is always read.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) |
access_level |
string | The level actually granted, which a View Only member's clamp may have lowered from the request. Read this rather than echoing what you sent. |
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 '{"dvak_token": "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 | DVAKs per page, at most 100; a larger value reads as 100 (Pagination)Default: 25 |
cursor |
string | Optional | Sealed pagination cursor from a previous response (next_cursor), read with the same status. |
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, messaging) |
dvaks[].nhi_description |
string | NHI description (NHI DVAKs) |
dvaks[].access_level |
string | read or read_write, the level a VAT unsealed with this key inherits; null on a key stored without one, which unseals read_write |
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 |
count |
integer | Number of DVAKs in this page |
has_more |
boolean | Whether more pages exist. With a status filter a page can hold fewer DVAKs than limit, or none, while more remain: keep paging while has_more is true |
next_cursor |
string | Cursor for the next page (present when has_more is true) |
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, and every VAT it already minted is refused from that moment, so access ends now rather than when those sessions would have expired.
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 |
End Your Session
/v1/vaults/{vault_id}/session
End your own session with the vault: the VAT in the X-Vault-Access-Token header stops working at once, and every other session of the vault (other members, devices and integrations) keeps working. Any holder of a live VAT for the vault may end it, a read-only one included, since ending a session only takes access away. This is what the SparkVault apps' Seal Vault button does.
Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Vault-Access-Token |
string | Required | The VAT whose session ends. It must be live and minted for this vault of your account. |
Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | AUTHENTICATION_ERROR |
details.reason is VAT_INVALID: no VAT, or one that opens nothing (already ended, minted by a since-revoked DVAK, or never issued). The session is already over. |
| 403 | FORBIDDEN |
details.reason is VAT_EXPIRED for an expired VAT (the session is already over). With no reason, the VAT belongs to another vault or account, and nothing ends. |
Example
Requestcurl -X DELETE https://api.sparkvault.com/v1/vaults/vlt_abc123/session \
-H "X-API-Key: sv_live_xxx" \
-H "X-Vault-Access-Token: vat_xyz789"
(204 No Content)
Seal Vault
/v1/vaults/{vault_id}/seal
Seal a vault: end every session of it at once, so every VAT minted for it, held by any member, device or integration, stops working. Opening the vault again takes its key. Requires a Full License.
Seal a vault when its access must all stop now, for example when you believe a VAT has been compromised. To end only your own session, use End Your Session; otherwise let VATs expire.
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 first ends every session of the vault (every VAT for it stops working) and removes its DVAKs and SparkLinks, then removes its audit logs, stored objects, ingots and folders in phases. This action is irreversible.
Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Confirm-Name-B64 |
string | Required | The vault name as standard base64 of its UTF-8 bytes, so any name travels in a header. It must decode to the vault name exactly (case-sensitive) to confirm deletion. A mismatch, or a value that is not base64 of UTF-8, 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-B64 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-B64: UHJvZHVjdGlvbiBTZWNyZXRz"
{
"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 Vault Master Key, which is verified before the sharing system DVAK is minted from it.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
vmk |
string | Required | The Vault Master Key. An enabled upload portal or widget does not stand in for it: that channel's system DVAK is consent to inbound uploads only. |
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. Setting all_ingots_public to true publishes every ingot, so it requires an unsealed vault: the same read-write VAT a per-ingot public share requires.
Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Vault-Access-Token |
string | Optional | A read-write VAT for this vault. Required when all_ingots_public is true: without one the request fails 401, and a read-only VAT fails 403 (VAT_READ_ONLY). |
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-B64 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, or two active DVAKs share the last 4 characters given to revoke, so the key to revoke cannot be determined |
| 412 | PRECONDITION_FAILED |
Invalid VMK: the provided VMK does not match this vault |
| 413 | PAYLOAD_TOO_LARGE |
File exceeds maximum size (5 TB) |