UnveilPass

API Documentation

v1 Back to App

Quick Start

UnveilPass is a zero-knowledge password manager. All vault data is encrypted client-side. The API returns and accepts only ciphertext — you must derive keys and encrypt/decrypt on your end.

Zero-Knowledge Architecture: The server never sees your plaintext passwords. All entries returned by the API are AES-256-GCM encrypted. Your client must derive the vault key from the master password using Argon2id, then decrypt locally.

Authenticate with an API Key

# Step 1: Get your salt
curl -X POST https://unveilpass.com:8444/api/auth/api-key/init \
  -H "Content-Type: application/json" \
  -d '{"api_key": "uvp_your_key_here"}'

# Response: {"salt": "base64_salt_value"}

# Step 2: Derive auth_key from master password + salt using Argon2id
# (time=3, mem=64MB, parallelism=4, hashLen=64)
# auth_key = first 32 bytes of the hash, base64-encoded

# Step 3: Login with API key + auth_key
curl -X POST https://unveilpass.com:8444/api/auth/api-key \
  -H "Content-Type: application/json" \
  -d '{"api_key": "uvp_your_key_here", "auth_key": "base64_derived_key"}'

# Response: {"token": "jwt_token", "encrypted_vault_key": "...", ...}

# Step 4: Use the JWT token for all subsequent requests
curl https://unveilpass.com:8444/api/vault \
  -H "Authorization: Bearer YOUR_TOKEN"
The encrypted_vault_key returned at login must be unwrapped with your KEK (derived via HKDF-SHA256 from the Argon2id hash). This vault key is then used to encrypt and decrypt all vault entries.

Authentication

UnveilPass supports two authentication methods. Both return a JWT token used as Authorization: Bearer <token> for all API calls.

Method 1: Email Login

The standard two-step email login flow:

POST /api/auth/login/init Get user salt

Request Body

{
  "email": "user@example.com"
}

Response

{
  "salt": "base64_encoded_salt"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/auth/login/init \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'
POST /api/auth/login Login with email + auth key

Request Body

{
  "email": "user@example.com",
  "auth_key": "base64_derived_auth_key",
  "device_token": "optional_device_token",
  "verification_code": "optional_6_digit_code"
}

Response

{
  "token": "jwt_token",
  "encrypted_vault_key": "iv:ciphertext",
  "encrypted_private_key": "iv:ciphertext",
  "public_key": "base64_public_key"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "auth_key": "base64_key"}'

Method 2: API Key Login

API keys provide a streamlined login for CLI tools, scripts, and CI/CD pipelines. No device trust or TOTP required.

POST /api/auth/api-key/init Get salt via API key

Request Body

{
  "api_key": "uvp_your_key_here"
}

Response

{
  "salt": "base64_encoded_salt"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/auth/api-key/init \
  -H "Content-Type: application/json" \
  -d '{"api_key": "uvp_your_key_here"}'
POST /api/auth/api-key Login with API key + auth key

Request Body

{
  "api_key": "uvp_your_key_here",
  "auth_key": "base64_derived_auth_key"
}

Response

{
  "token": "jwt_token",
  "encrypted_vault_key": "iv:ciphertext",
  "encrypted_private_key": "iv:ciphertext",
  "public_key": "base64_public_key"
}
API key login bypasses device trust and TOTP verification. The auth_key is still required because the server must verify your master password knowledge before releasing your encrypted vault key.

curl Example

curl -X POST https://unveilpass.com:8444/api/auth/api-key \
  -H "Content-Type: application/json" \
  -d '{"api_key": "uvp_your_key_here", "auth_key": "base64_key"}'

API Key Management

Manage API keys for programmatic access. Keys are prefixed with uvp_ and can be generated from Settings in the web UI or via the API.

GET /api/auth/api-keys List all API keys

Response

[
  {
    "id": 1,
    "name": "CI/CD Pipeline",
    "prefix": "uvp_abc1",
    "created_at": "2026-03-28T10:00:00Z",
    "last_used_at": "2026-03-28T14:30:00Z",
    "revoked": false
  }
]

curl Example

curl https://unveilpass.com:8444/api/auth/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/auth/api-keys Create a new API key

Request Body

{
  "name": "CI/CD Pipeline"
}

Response

{
  "id": 2,
  "name": "CI/CD Pipeline",
  "api_key": "uvp_a1b2c3d4e5f6g7h8i9j0..."
}
The full API key is only returned once at creation time. Store it securely. If lost, revoke the key and create a new one.

curl Example

curl -X POST https://unveilpass.com:8444/api/auth/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "CI/CD Pipeline"}'
DELETE /api/auth/api-keys/{id} Revoke an API key

Response

{
  "message": "API key revoked"
}

curl Example

curl -X DELETE https://unveilpass.com:8444/api/auth/api-keys/2 \
  -H "Authorization: Bearer YOUR_TOKEN"

Vault

Vault entries store encrypted credentials. All encrypted_data fields contain AES-256-GCM ciphertext that must be decrypted client-side with the vault key.

GET /api/vault List all vault entries

Response

[
  {
    "id": 1,
    "encrypted_data": "base64_ciphertext",
    "iv": "base64_iv",
    "created_at": "2026-03-28T10:00:00Z",
    "updated_at": "2026-03-28T14:30:00Z"
  }
]

After decryption, each entry contains: site, username, password, notes, folder, favorite, totp_secret, urls.

curl Example

curl https://unveilpass.com:8444/api/vault \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/vault Create a vault entry

Request Body

{
  "encrypted_data": "base64_ciphertext",
  "iv": "base64_iv",
  "expires_at": "2027-01-01T00:00:00Z"
}

Response

{
  "id": 2,
  "encrypted_data": "base64_ciphertext",
  "iv": "base64_iv",
  "created_at": "2026-03-28T15:00:00Z",
  "updated_at": "2026-03-28T15:00:00Z"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/vault \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
GET /api/vault/{id} Get a single vault entry

Response

{
  "id": 1,
  "encrypted_data": "base64_ciphertext",
  "iv": "base64_iv",
  "created_at": "2026-03-28T10:00:00Z",
  "updated_at": "2026-03-28T14:30:00Z"
}

curl Example

curl https://unveilpass.com:8444/api/vault/1 \
  -H "Authorization: Bearer YOUR_TOKEN"
PUT /api/vault/{id} Update a vault entry

Request Body

{
  "encrypted_data": "base64_new_ciphertext",
  "iv": "base64_new_iv"
}

Response

{
  "id": 1,
  "encrypted_data": "base64_new_ciphertext",
  "iv": "base64_new_iv",
  "updated_at": "2026-03-28T16:00:00Z"
}

curl Example

curl -X PUT https://unveilpass.com:8444/api/vault/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
DELETE /api/vault/{id} Delete a vault entry

Response

{
  "message": "Entry deleted"
}

curl Example

curl -X DELETE https://unveilpass.com:8444/api/vault/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Secure Notes

Encrypted notes stored in the vault. All content is AES-256-GCM encrypted client-side.

GET /api/notes List all notes

Response

[
  {
    "id": 1,
    "encrypted_data": "base64_ciphertext",
    "iv": "base64_iv",
    "created_at": "2026-03-28T10:00:00Z",
    "updated_at": "2026-03-28T14:30:00Z"
  }
]

curl Example

curl https://unveilpass.com:8444/api/notes \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/notes Create a note

Request Body

{
  "encrypted_data": "base64_ciphertext",
  "iv": "base64_iv"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/notes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
GET /api/notes/{id} Get a single note

curl Example

curl https://unveilpass.com:8444/api/notes/1 \
  -H "Authorization: Bearer YOUR_TOKEN"
PUT /api/notes/{id} Update a note

Request Body

{
  "encrypted_data": "base64_new_ciphertext",
  "iv": "base64_new_iv"
}

curl Example

curl -X PUT https://unveilpass.com:8444/api/notes/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
DELETE /api/notes/{id} Delete a note

curl Example

curl -X DELETE https://unveilpass.com:8444/api/notes/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Contacts

Manage trusted contacts for vault sharing and emergency access.

GET /api/contacts List all contacts

Response

[
  {
    "id": 1,
    "contact_user_id": 5,
    "email_hash": "sha256_hash",
    "status": "accepted",
    "public_key": "base64_public_key",
    "created_at": "2026-03-28T10:00:00Z"
  }
]

curl Example

curl https://unveilpass.com:8444/api/contacts \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/contacts Invite a contact

Request Body

{
  "email": "friend@example.com"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/contacts \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email": "friend@example.com"}'
PUT /api/contacts/{id} Update a contact

curl Example

curl -X PUT https://unveilpass.com:8444/api/contacts/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
DELETE /api/contacts/{id} Remove a contact

curl Example

curl -X DELETE https://unveilpass.com:8444/api/contacts/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Shares

Share vault entries with contacts using X25519 ECDH key exchange. Supports one-way and two-way sync modes with optional TTL.

GET /api/shares List incoming shares

Response

[
  {
    "id": 1,
    "entry_id": 10,
    "owner_user_id": 2,
    "encrypted_data": "base64_ciphertext",
    "iv": "base64_iv",
    "sync_mode": "two_way",
    "permission": "read_write",
    "expires_at": "2026-04-28T10:00:00Z",
    "version": 3
  }
]

curl Example

curl https://unveilpass.com:8444/api/shares \
  -H "Authorization: Bearer YOUR_TOKEN"
GET /api/shares/outgoing List outgoing shares

curl Example

curl https://unveilpass.com:8444/api/shares/outgoing \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/shares Create a share

Request Body

{
  "entry_id": 10,
  "recipient_user_id": 5,
  "encrypted_data": "base64_ciphertext",
  "iv": "base64_iv",
  "permission": "read_write",
  "sync_mode": "two_way",
  "ttl": "7d"
}
The encrypted_data must be encrypted with a shared key derived via X25519 ECDH between your private key and the recipient's public key, then HKDF with info string "unveilvault-share".

curl Example

curl -X POST https://unveilpass.com:8444/api/shares \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"entry_id": 10, "recipient_user_id": 5, "encrypted_data": "...", "iv": "...", "permission": "read_write", "sync_mode": "two_way"}'
PUT /api/shares/{id} Update a share

Request Body

{
  "encrypted_data": "base64_new_ciphertext",
  "iv": "base64_new_iv"
}

curl Example

curl -X PUT https://unveilpass.com:8444/api/shares/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
DELETE /api/shares/{id} Delete a share

curl Example

curl -X DELETE https://unveilpass.com:8444/api/shares/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Teams

Team vaults use a shared Team Key encrypted per-member via ECDH. Team entries are encrypted with the Team Key rather than individual vault keys.

GET /api/teams List your teams

Response

[
  {
    "id": 1,
    "name": "Engineering",
    "role": "owner",
    "encrypted_team_key": "iv:ciphertext",
    "member_count": 5,
    "created_at": "2026-03-01T10:00:00Z"
  }
]

curl Example

curl https://unveilpass.com:8444/api/teams \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/teams Create a team

Request Body

{
  "name": "Engineering",
  "encrypted_team_key": "iv:ciphertext"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/teams \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Engineering", "encrypted_team_key": "..."}'
DELETE /api/teams/{id} Delete a team

curl Example

curl -X DELETE https://unveilpass.com:8444/api/teams/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Team Members

GET /api/teams/{id}/members List team members

Response

[
  {
    "id": 1,
    "user_id": 3,
    "role": "member",
    "status": "accepted"
  }
]

curl Example

curl https://unveilpass.com:8444/api/teams/1/members \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/teams/{id}/members Invite a member

Request Body

{
  "user_id": 5,
  "role": "member",
  "encrypted_team_key": "iv:ciphertext"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/teams/1/members \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"user_id": 5, "role": "member", "encrypted_team_key": "..."}'
DELETE /api/teams/{id}/members/{memberId} Remove a member

curl Example

curl -X DELETE https://unveilpass.com:8444/api/teams/1/members/5 \
  -H "Authorization: Bearer YOUR_TOKEN"

Team Vault Entries

GET /api/teams/{id}/vault List team vault entries

curl Example

curl https://unveilpass.com:8444/api/teams/1/vault \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/teams/{id}/vault Create team vault entry

Request Body

{
  "encrypted_data": "base64_ciphertext",
  "iv": "base64_iv",
  "permission": "read_write"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/teams/1/vault \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "...", "permission": "read_write"}'
PUT /api/teams/{id}/vault/{entryId} Update team vault entry

curl Example

curl -X PUT https://unveilpass.com:8444/api/teams/1/vault/5 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
DELETE /api/teams/{id}/vault/{entryId} Delete team vault entry

curl Example

curl -X DELETE https://unveilpass.com:8444/api/teams/1/vault/5 \
  -H "Authorization: Bearer YOUR_TOKEN"

Team Notes

GET /api/teams/{id}/notes List team notes

curl Example

curl https://unveilpass.com:8444/api/teams/1/notes \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/teams/{id}/notes Create team note

Request Body

{
  "encrypted_data": "base64_ciphertext",
  "iv": "base64_iv"
}

curl Example

curl -X POST https://unveilpass.com:8444/api/teams/1/notes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
PUT /api/teams/{id}/notes/{noteId} Update team note

curl Example

curl -X PUT https://unveilpass.com:8444/api/teams/1/notes/3 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"encrypted_data": "...", "iv": "..."}'
DELETE /api/teams/{id}/notes/{noteId} Delete team note

curl Example

curl -X DELETE https://unveilpass.com:8444/api/teams/1/notes/3 \
  -H "Authorization: Bearer YOUR_TOKEN"

CryptoLink — Encrypted File Transfer

Send files with end-to-end encryption. Files are encrypted client-side (AES-256-GCM) before upload. The decryption key is never sent to the server — it stays in the URL fragment. The server stores only encrypted data it cannot read.

Zero-knowledge: The encryption key must be generated client-side. The API only accepts pre-encrypted data. Use the Python or Node.js SDK for automatic encryption, or implement AES-256-GCM yourself.

Create CryptoLink

POST /api/send Upload encrypted file and create shareable link

Request Body

{
  "encrypted_data": "base64-encoded AES-256-GCM ciphertext",
  "iv": "base64-encoded 12-byte IV",
  "encrypted_filename": "iv_b64:ciphertext_b64",
  "size_bytes": 102400,
  "ttl_seconds": 86400,
  "max_downloads": 1,
  "single_use": false,
  "pin_hash": "sha256-hex-of-pin (optional)"
}

Response

{ "id": "uuid" }

Build the shareable link: https://unveilpass.com/#/receive?id={id}&k={url_encoded_key_b64}

Limits

  • Free plan: 1 MB per link, 1 link per hour
  • Pro plan: 10 MB per link, unlimited

List CryptoLinks

GET /api/send List all CryptoLinks for the authenticated user

Response

[
  {
    "id": "uuid",
    "size_bytes": 102400,
    "ttl_seconds": 86400,
    "max_downloads": 1,
    "download_count": 0,
    "downloaded": false,
    "pin_hash": "sha256...",
    "pin_attempts": 0,
    "expires_at": "2026-04-12T14:00:00Z",
    "created_at": "2026-04-11T14:00:00Z"
  }
]

Download / Decrypt

GET /api/send/{id}/download Download encrypted data (public, no auth required)

Query Parameters

  • pin_hash — SHA-256 hex of the PIN (required if PIN was set)

Response

{
  "encrypted_data": "base64...",
  "iv": "base64...",
  "encrypted_filename": "iv_b64:ct_b64"
}

Errors

  • 401 — PIN required or invalid PIN (with attempts remaining)
  • 403 — Too many PIN attempts, link blocked
  • 410 — File expired or download limit reached

Get Info

GET /api/send/{id}/info Get metadata without downloading (public)

Response

{
  "size_bytes": 102400,
  "expires_at": "2026-04-12T14:00:00Z",
  "pin_required": true
}

Delete CryptoLink

DELETE /api/send/{id} Delete a CryptoLink

Response

{ "status": "deleted" }

Reset Counters

POST /api/send/{id}/reset-pin Reset PIN attempts and download counter

Response

{ "status": "ok" }

SDK Examples

SDK Python & Node.js Encrypt and send files in one line

Python

from unveilpass import UnveilPassAgent

agent = UnveilPassAgent("uvp_agent_your_key")

# Send a file with 24h TTL and PIN protection
result = agent.send_file("contract.pdf", ttl=86400, pin="482916")
print(result["link"])  # Share this with the recipient
print(result["pin"])   # Share PIN separately (SMS, phone)

# With message and download limit
result = agent.send_file(
    "report.xlsx",
    ttl=604800,         # 7 days
    max_downloads=5,
    message="Monthly report attached"
)

# List and delete
sends = agent.list_sends()
agent.delete_send(sends[0]["id"])

Requires: pip install pycryptodome requests

Node.js

const { UnveilPassAgent } = require('unveilpass');

const agent = new UnveilPassAgent('uvp_agent_your_key');

// Send a file with PIN
const result = await agent.sendFile('contract.pdf', {
    ttl: 86400,
    pin: '482916',
    message: 'Please sign and return'
});
console.log(result.link, result.pin);

// List sends
const sends = await agent.listSends();

// Delete
await agent.deleteSend(sends[0].id);

Other Endpoints

Health Check

GET /api/health Server health check

Response

{
  "status": "ok"
}

curl Example

curl https://unveilpass.com:8444/api/health

Password Generator

POST /api/generator Generate a random password

Request Body

{
  "length": 24,
  "uppercase": true,
  "lowercase": true,
  "digits": true,
  "symbols": true
}

Response

{
  "password": "xK9#mP2£qR7$nL4wB6..."
}

curl Example

curl -X POST https://unveilpass.com:8444/api/generator \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"length": 24, "uppercase": true, "lowercase": true, "digits": true, "symbols": true}'

Audit Log

GET /api/audit View account audit log

Response

[
  {
    "id": 100,
    "action": "login",
    "ip_address": "192.168.1.1",
    "details": "Web login",
    "created_at": "2026-03-28T14:30:00Z"
  }
]

curl Example

curl https://unveilpass.com:8444/api/audit \
  -H "Authorization: Bearer YOUR_TOKEN"