Skip to main content
Version: 1.0

Sharing API

SyVault supports secure one-time sharing of individual records. A share link grants temporary, limited access to a single secret without requiring the recipient to have a SyVault account.

POST /api/share/one-time

Create a one-time share link for a record. The share payload is encrypted by the client before transmission.

curl -X POST https://vault.example.com/api/share/one-time \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"record_id": "record-uuid-1",
"record_type": 1,
"share_token": "a1b2c3d4e5f6g7h8i9j0",
"encrypted_payload": "base64-client-encrypted-payload",
"expires_in_hours": 24,
"max_access_count": 1
}'

Request fields

FieldTypeRequiredDescription
record_idstringYesUID of the record being shared.
record_typeintegerYesRecordType enum variant (1 = Login, 2 = Secure Note, etc.).
share_tokenstringYesClient-generated random token — forms the path component of the public URL. The decryption key is kept in the URL fragment and never sent to the server.
encrypted_payloadstringYesBase64 ciphertext. The record's content is re-encrypted on the client under a fresh one-time share key before upload.
expires_in_hoursintegerNoHours until the link expires. Omit for server default.
max_access_countintegerNoMaximum number of retrievals before the share is deleted. Omit for 1 (default one-time).

Response (201):

{
"id": "share-uuid-1",
"share_token": "a1b2c3d4e5f6g7h8i9j0",
"expires_at": "2026-04-06T13:00:00Z",
"max_access_count": 1,
"created_at": "2026-04-06T12:00:00Z"
}

Compose the recipient URL client-side as https://vault.example.com/share/{share_token}#{decryption_key_base64}. The fragment (after #) is never transmitted to the server — only the URL path hits GET /api/share/public/{share_token}.

Retrieve a Shared Secret

GET /api/share/public/{token}

This endpoint does not require authentication. It is the only public endpoint in the SyVault API.

curl https://vault.example.com/api/share/public/a1b2c3d4e5f6g7h8i9j0

Response (200):

{
"id": "share-uuid-1",
"encrypted_payload": "base64-client-encrypted-payload",
"created_at": "2026-04-06T12:00:00Z",
"expires_at": "2026-04-06T13:00:00Z"
}

The client decrypts encrypted_payload using the key from the URL fragment.

Response (404) — expired or used:

{
"error": "share_not_found",
"message": "This share link has expired or has already been viewed."
}

View Limits

The max_access_count counter is decremented on each successful retrieval. When it reaches zero, the share is permanently deleted from the server. Even if the expiration time has not elapsed, the share cannot be accessed again.

Listing Your Shares

Authenticated users can list their active share links:

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

Response:

{
"data": [
{
"id": "share-uuid-1",
"record_id": "record-uuid-1",
"created_at": "2026-04-06T12:00:00Z",
"expires_at": "2026-04-06T13:00:00Z",
"max_access_count": 1,
"views": 0
}
]
}

Revoking a Share

Delete a share link before it expires or is used:

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

Returns 204 No Content. The link is immediately invalid.

Security Model

  • The encrypted payload is stored on the server, but the decryption key is embedded in the URL fragment (#key=...). URL fragments are never sent to the server by browsers.
  • The server cannot decrypt shared secrets.
  • Share links are one-time by default. Even if a link is intercepted, the attacker races with the legitimate recipient — the first viewer consumes the link.
  • All share access is logged and visible in the organization audit log (Enterprise plan).

Organization Sharing

In addition to one-time share links, SyVault supports persistent sharing of records and folders with individual users or teams within your organization. Unlike one-time shares, organization shares remain active until explicitly revoked and support granular permission levels.

Permission Levels

ValueLabelDescription
0ViewGrantee can read the record or folder contents.
1View + EditGrantee can read and modify the record or folder contents.
2ManageGrantee can read, modify, and re-share the record or folder with other users or teams.

Share a Folder

POST /api/share/folder

Share an entire folder with a user or team. All current and future records in the folder are accessible to the grantee at the specified permission level.

curl -X POST https://vault.example.com/api/share/folder \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"folder_id": "folder-uuid-1",
"target_type": "team",
"target_id": "team-uuid-1",
"permission": 1
}'
FieldTypeRequiredDescription
folder_idstringYesThe UUID of the folder to share.
target_typestringYes"user" or "team".
target_idstringYesThe UUID of the target user or team.
permissionintegerYes0 (view), 1 (view + edit), or 2 (manage).

Response (201):

{
"grant_id": "grant-uuid-1",
"folder_id": "folder-uuid-1",
"target_type": "team",
"target_id": "team-uuid-1",
"permission": 1,
"created_at": "2026-04-06T12:00:00Z"
}

Share a Record

POST /api/share/record-org

Share an individual record with a user or team. This is a persistent grant, not a one-time link.

curl -X POST https://vault.example.com/api/share/record-org \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"record_id": "record-uuid-1",
"target_type": "user",
"target_id": "user-uuid-1",
"permission": 0
}'

Response (201):

{
"grant_id": "grant-uuid-2",
"record_id": "record-uuid-1",
"target_type": "user",
"target_id": "user-uuid-1",
"permission": 0,
"created_at": "2026-04-06T12:00:00Z"
}

List Folder Access Grants

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

Response (200):

{
"data": [
{
"grant_id": "grant-uuid-1",
"target_type": "team",
"target_id": "team-uuid-1",
"target_name": "Engineering",
"permission": 1,
"created_at": "2026-04-06T12:00:00Z"
}
]
}

List Record Access Grants

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

Response (200):

{
"data": [
{
"grant_id": "grant-uuid-2",
"target_type": "user",
"target_id": "user-uuid-1",
"target_name": "bob@example.com",
"permission": 0,
"created_at": "2026-04-06T12:00:00Z"
}
]
}

Revoke a Sharing Grant

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

Returns 204 No Content. The grantee loses access immediately. Any cached folder keys for the grantee are invalidated.

Organization Sharing Security Model

  • Key re-encryption. When a folder or record is shared, the server re-encrypts the folder/record DEK with the grantee's public key (or the team's shared key). The server never sees plaintext data.
  • Permission enforcement. Permissions are checked on every API call. A grantee with view permission who attempts a PUT receives 403 Forbidden.
  • Manage permission propagation. A grantee with manage (level 2) can create new grants, but cannot grant a higher permission level than they hold.
  • Revocation cascades. Revoking a team grant removes access for all members of that team. Revoking a folder grant removes access to all records within it.
  • Audit logging. All grant creation, modification, and revocation events are recorded in the organization audit log.