Skip to main content
Version: 1.0

Vaults & Records API

The vaults and records API is the core data layer of SyVault. All record payloads are encrypted client-side before transmission; the server stores and returns opaque ciphertext.

Authentication​

All endpoints require a valid access token in the Authorization header:

Authorization: Bearer <access_token>

Vaults​

List vaults​

Returns all vaults the authenticated user has access to. When Travel Mode is active, vaults not marked as safe-for-travel are excluded from the response.

GET /api/vaults
curl https://vault.example.com/api/vaults \
-H "Authorization: Bearer $TOKEN"

Response:

{
"data": [
{
"id": "vault-uuid-1",
"name": "Personal",
"type": "personal",
"created_at": "2025-08-15T10:30:00Z",
"updated_at": "2026-04-05T14:22:00Z",
"record_count": 47,
"safe_for_travel": true
},
{
"id": "vault-uuid-2",
"name": "Work",
"type": "shared",
"created_at": "2025-09-01T08:00:00Z",
"updated_at": "2026-04-04T09:15:00Z",
"record_count": 132,
"safe_for_travel": false
}
]
}

Create a vault​

POST /api/vaults
curl -X POST https://vault.example.com/api/vaults \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Side Project",
"type": "personal",
"encrypted_key": "base64-vault-encryption-key"
}'

Response (201):

{
"id": "vault-uuid-3",
"name": "Side Project",
"type": "personal",
"created_at": "2026-04-06T12:00:00Z",
"record_count": 0,
"safe_for_travel": false
}

Delete a vault​

DELETE /api/vaults/{id}
curl -X DELETE https://vault.example.com/api/vaults/vault-uuid-3 \
-H "Authorization: Bearer $TOKEN"

Returns 204 No Content on success. All records inside the vault are permanently deleted.

Records​

List records in a vault​

GET /api/vaults/{id}/records
curl https://vault.example.com/api/vaults/vault-uuid-1/records \
-H "Authorization: Bearer $TOKEN"

Response:

{
"data": [
{
"id": "record-uuid-1",
"vault_id": "vault-uuid-1",
"type": "login",
"encrypted_data": "base64-encrypted-payload",
"created_at": "2025-10-01T12:00:00Z",
"updated_at": "2026-04-01T08:30:00Z"
},
{
"id": "record-uuid-2",
"vault_id": "vault-uuid-1",
"type": "secure_note",
"encrypted_data": "base64-encrypted-payload",
"created_at": "2025-11-15T09:00:00Z",
"updated_at": "2025-11-15T09:00:00Z"
}
]
}

The encrypted_data field contains the AES-256-GCM encrypted JSON payload. The client decrypts it using the vault's encryption key.

Create a record​

POST /api/vaults/{id}/records
curl -X POST https://vault.example.com/api/vaults/vault-uuid-1/records \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "login",
"encrypted_data": "base64-encrypted-payload"
}'

The encrypted_data must be encrypted client-side before sending. A typical decrypted payload looks like:

{
"name": "GitHub",
"username": "alice",
"password": "hunter2",
"uri": "https://github.com/login",
"notes": "Personal account",
"totp_secret": "JBSWY3DPEHPK3PXP"
}

Response (201):

{
"id": "record-uuid-new",
"vault_id": "vault-uuid-1",
"type": "login",
"encrypted_data": "base64-encrypted-payload",
"created_at": "2026-04-06T12:05:00Z",
"updated_at": "2026-04-06T12:05:00Z"
}

Update a record​

PUT /api/vaults/{id}/records/{rid}
curl -X PUT https://vault.example.com/api/vaults/vault-uuid-1/records/record-uuid-1 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "login",
"encrypted_data": "base64-updated-encrypted-payload"
}'

Returns the updated record with a new updated_at timestamp.

Delete a record​

DELETE /api/vaults/{id}/records/{rid}
curl -X DELETE https://vault.example.com/api/vaults/vault-uuid-1/records/record-uuid-1 \
-H "Authorization: Bearer $TOKEN"

Returns 204 No Content.

Batch import​

Import up to 1000 records in a single request. Useful for migrations from other password managers.

POST /api/vaults/{id}/import
curl -X POST https://vault.example.com/api/vaults/vault-uuid-1/import \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"records": [
{
"type": "login",
"encrypted_data": "base64-encrypted-1"
},
{
"type": "login",
"encrypted_data": "base64-encrypted-2"
}
]
}'

Response (201):

{
"imported": 2,
"failed": 0,
"records": [
{"id": "record-uuid-a", "type": "login"},
{"id": "record-uuid-b", "type": "login"}
]
}

The maximum batch size is 1000 records. Requests exceeding this limit receive a 413 Payload Too Large response.

Error Responses​

StatusMeaning
400Invalid request body or missing fields
401Missing or expired access token
403No access to the specified vault
404Vault or record not found
413Import batch exceeds 1000 records
429Rate limited