Complete API documentation for PVYvault, a zero-knowledge password and data management system. This guide covers all endpoints, authentication methods, and data models needed for webextension development.
Please note, that the API is as PVYvault itself, restricted in Access to only your other PVYapps and all your Organization Users by Default within your PVY-ID Domain (Zero IT Infrastructure Exposure).
If you want the API to be accessible from outside of your PVY@Cloud, PVY@Office Rack Appliance or your PVY@Home Appliance, you have to add this Node/Host or Remote Site first over PVYvpn, either as a P2P Node or using if your targeted Nodes are on Amazon EWS, GoogleCloud or Azure, you use the deployable PVYsg to tunnel this endpoints securely into your closed environment. In Short, we have boundries for Security implemented, but no Limits to inlcude any other Endpoins in your existing IT Infrastructure elsewhere.
All PVYvault API calls use POST method with JSON payloads:
POST /server HTTP/1.1
Host: https://vault.your.tld
Content-Type: application/json
Accept: application/json
Content-Length: <length>
{
"method": "methodName",
"params": { ... }
}
{
"result": { ... },
"error": {
"code": "ERROR_CODE",
"message": "Error description"
}
}
Content-Type: application/json - Required for all requestsAccept: application/json - Required for all responsesAuthorization: Bearer <session-id> - Required for authenticated methodsPVYvault supports multiple authentication methods suitable for webextension
development:
Configuration:
const oauthConfig = {
clientId: "vault.your.tld",
authorizationEndpoint:
"https://id.your.tld/auth/realms/ClientsAuth/protocol/openid-connect/auth",
tokenEndpoint:
"https://id.your.tld/auth/realms/ClientsAuth/protocol/openid-connect/token",
userInfoEndpoint:
"https://your.tld/auth/realms/ClientsAuth/protocol/openid-connect/userinfo",
redirectUri: "https://vault.your.tld/oauth",
};
OAuth Flow for Webextension:
// 1. Initiate OAuth
const authResponse = await api.startAuthRequest({
email: "user@company.com",
type: AuthType.Oauth,
purpose: AuthPurpose.Login,
});
// 2. Redirect user to OAuth provider
window.location.href = authResponse.data.authUrl;
// 3. Handle OAuth callback (in /oauth route)
if (window.location.pathname === "/oauth") {
const params = new URLSearchParams(window.location.search);
const code = params.get("code");
const state = params.get("state");
// 4. Complete OAuth authentication
const result = await api.completeAuthRequest({
email: "user@company.com",
id: state,
data: { code, state },
});
}
Start Email Verification:
const response = await api.startAuthRequest({
email: "user@example.com",
type: AuthType.Email,
purpose: AuthPurpose.Login,
});
// Email with verification code sent to user
Complete Email Login:
const result = await api.completeAuthRequest({
email: "user@example.com",
id: response.id,
data: { code: "123456" },
});
WebAuthn for Webextension:
// Start WebAuthn registration/login
const response = await api.startAuthRequest({
type: AuthType.WebAuthnPlatform,
purpose: AuthPurpose.Login,
});
// Complete with biometric/security key
const result = await api.completeAuthRequest({
id: response.id,
data: {
credentialId: credentialId,
signature: signature,
clientDataJSON: clientDataJSON,
},
});
Start Session:
const sessionStart = await api.startCreateSession({
email: "user@example.com",
});
// Compute SRP values
const sessionData = await computeSRPValues(
sessionStart.srpId,
sessionStart.B,
userPassword
);
Complete Session:
const session = await api.completeCreateSession({
srpId: sessionStart.srpId,
accountId: sessionStart.accountId,
M: sessionData.M,
A: sessionData.A,
addTrustedDevice: false,
});
// Use session for authenticated requests
api.setSession(session);
const account = new Account({
email: "user@example.com",
name: "John Doe",
publicKey: userPublicKey,
encryptedPrivateKey: encryptedPrivateKey,
});
const result = await api.createAccount({
account: account,
auth: emailAuth,
});
const account = await api.getAccount();
// Requires authenticated session
const updatedAccount = await api.updateAccount({
...existingAccount,
name: "John Smith",
});
const result = await api.changeEmail({
authToken: verificationToken,
email: "newemail@example.com",
});
await api.deleteAccount(accountId);
// Irreversible operation
const recoveryResult = await api.recoverAccount({
account: newAccount,
auth: recoveryAuth,
verify: emailVerificationToken,
});
const vault = new Vault({
name: "Personal Passwords",
organization: null, // Personal vault
encryptedVault: encryptedVaultData,
});
const createdVault = await api.createVault(vault);
const vault = await api.getVault(vaultId);
// Returns vault with decrypted content
const updatedVault = await api.updateVault({
...existingVault,
name: "Updated Vault Name",
encryptedVault: newEncryptedData,
});
await api.deleteVault(vaultId);
// Requires admin permissions for org vaults
const vaults = await api.listVaults({
limit: 100,
offset: 0,
});
const org = new Organization({
name: "Company Name",
description: "Secure password management for our team",
publicKey: orgPublicKey,
encryptedPrivateKey: encryptedOrgPrivateKey,
});
const createdOrg = await api.createOrg(org);
const org = await api.getOrg(orgId);
// Requires membership in organization
const updatedOrg = await api.updateOrg({
...existingOrg,
name: "Updated Company Name",
});
// Requires Owner or Admin role
await api.deleteOrg(orgId);
// Requires Owner role
const orgs = await api.listOrgs({
limit: 50,
offset: 0,
});
const response = await api.startRegisterAuthenticator({
type: AuthType.Totp,
purposes: [AuthPurpose.Login],
device: deviceInfo,
});
// Complete registration
const result = await api.completeRegisterAuthenticator({
id: response.id,
data: { secret: totpSecret },
});
await api.deleteAuthenticator(authenticatorId);
const authInfo = await api.getAuthInfo();
// Returns: authenticators, sessions, trusted devices, etc.
await api.updateAuth({
verifier: newPasswordVerifier,
keyParams: newKeyDerivationParams,
mfaOrder: ["webauthn", "totp", "email"],
});
const attachment = new Attachment({
name: "important-file.pdf",
size: file.size,
mimeType: "application/pdf",
encryptedData: encryptedFileContent,
});
const attachmentId = await api.createAttachment(attachment);
const attachment = await api.getAttachment({
vault: vaultId,
id: attachmentId,
});
await api.deleteAttachment({
vault: vaultId,
id: attachmentId,
});
const sessionInfo = await api.getSessionInfo();
// Returns session details and trusted devices
await api.revokeSession(sessionId);
// Logs out specific session
await api.removeTrustedDevice(deviceId);
const entry = await api.createKeyStoreEntry({
data: encryptedKeyData,
authenticatorId: "authenticator-id",
});
const entry = await api.getKeyStoreEntry({
id: entryId,
authToken: verificationToken,
});
await api.deleteKeyStoreEntry(entryId);
interface Account {
id: string; // Unique account identifier
email: string; // User email address
name: string; // Display name
publicKey: Uint8Array; // Public key for encryption
encryptedPrivateKey: string; // Encrypted private key
encryptedMasterKey: string; // Encrypted master password
keyParams: PBKDF2Params; // Key derivation parameters
verified: boolean; // Email verification status
locked: boolean; // Account lock status
created: Date; // Creation timestamp
updated: Date; // Last update timestamp
}
interface Vault {
id: string; // Vault identifier
name: string; // Vault display name
organization?: string; // Organization ID (null for personal)
encryptedVault: string; // Encrypted vault contents
encryptedMasterKey: string; // Encrypted vault master key
keyParams: PBKDF2Params; // Key derivation parameters
created: Date; // Creation timestamp
updated: Date; // Last update timestamp
}
interface Organization {
id: string; // Organization identifier
name: string; // Organization name
description?: string; // Organization description
publicKey: Uint8Array; // Organization public key
encryptedPrivateKey: string; // Encrypted private key
encryptedMasterKey: string; // Encrypted master key
members: OrganizationMember[]; // Organization members
groups: Group[]; // Organization groups
created: Date; // Creation timestamp
updated: Date; // Last update timestamp
}
interface Session {
id: string; // Session identifier
accountId: string; // Account ID
deviceInfo: DeviceInfo; // Device information
created: Date; // Creation timestamp
lastAccessed: Date; // Last access timestamp
expires: Date; // Expiration timestamp
}
interface Authenticator {
id: string; // Authenticator identifier
type: AuthType; // Authentication type
description: string; // Display description
purposes: AuthPurpose[]; // Supported purposes
status: AuthenticatorStatus; // Current status
created: Date; // Creation timestamp
lastUsed?: Date; // Last usage timestamp
device?: DeviceInfo; // Associated device
state?: any; // Type-specific state
}
const ws = new WebSocket("wss://vault.your.tld/server/ws");
ws.onopen = () => {
// Authenticate WebSocket
ws.send(
JSON.stringify({
type: "authenticate",
session: sessionId,
})
);
};
// Listen for vault updates
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case "vault_updated":
handleVaultUpdate(message.data);
break;
case "item_added":
handleItemAdded(message.data);
break;
case "sync_complete":
handleSyncComplete(message.data);
break;
}
};
authenticate - Authenticate WebSocket connectionvault_updated - Vault content changeditem_added - New vault item addeditem_updated - Vault item modifieditem_deleted - Vault item removedsync_complete - Synchronization finishederror - Error occurred during operation| Code | Description | Resolution |
|---|---|---|
ACCOUNT_NOT_FOUND |
Account doesn’t exist | Verify email or create account |
INVALID_CREDENTIALS |
Authentication failed | Check password/auth method |
ACCOUNT_LOCKED |
Account is locked | Contact administrator |
SESSION_EXPIRED |
Session expired | Re-authenticate |
PERMISSION_DENIED |
Insufficient permissions | Check user role |
VAULT_NOT_FOUND |
Vault doesn’t exist | Verify vault ID |
ORG_NOT_FOUND |
Organization doesn’t exist | Verify org ID |
INVALID_INVITE |
Invalid invitation | Check invite link |
RATE_LIMIT_EXCEEDED |
Too many requests | Wait and retry |
SERVER_ERROR |
Internal server error | Contact support |
{
"error": {
"code": "SESSION_EXPIRED",
"message": "Session has expired. Please log in again."
}
}