Complete TypeScript SDK reference for the Lifestream Vault API
npm install @lifestreamdynamics/vault-sdk
import { LifestreamVaultClient } from '@lifestreamdynamics/vault-sdk';
const client = new LifestreamVaultClient({
baseUrl: 'https://your-vault-instance.com',
apiKey: 'lsv_k_your_api_key',
});
// List vaults
const vaults = await client.vaults.list();
// Get a document
const doc = await client.documents.get(vaultId, 'path/to/doc.md');
// Search
const results = await client.search.search({ q: 'search terms' });
The SDK automatically prepends /api/v1 to all requests, so baseUrl should be the root URL of your server (e.g., https://vault.example.com), not the API prefix URL.
The client requires either an API key or an access token. If neither is provided, the constructor throws an error.
const client = new LifestreamVaultClient({
baseUrl: 'https://example.com',
apiKey: 'lsv_k_...',
});
const client = new LifestreamVaultClient({
baseUrl: 'https://example.com',
accessToken: 'eyJ...',
});
const client = new LifestreamVaultClient({
baseUrl: 'https://example.com',
accessToken: 'eyJ...',
refreshToken: 'eyJ...',
onTokenRefresh: (tokens) => {
// Persist new tokens
saveTokens(tokens);
},
});
The LifestreamVaultClient constructor accepts the following options:
| Option | Type | Default | Description |
|---|---|---|---|
baseUrl | string | -- (required) | Base URL of the Lifestream Vault API server |
apiKey | string | -- | API key (lsv_k_ prefix) |
accessToken | string | -- | JWT access token |
refreshToken | string | -- | JWT refresh token for automatic renewal |
timeout | number | 30000 | Request timeout in milliseconds |
refreshBufferMs | number | 60000 | Milliseconds before token expiry to trigger proactive refresh |
onTokenRefresh | function | -- | Callback with new tokens after refresh |
enableRequestSigning | boolean | true for API keys | Enable HMAC-SHA256 request signing |
enableAuditLogging | boolean | false | Enable client-side audit logging |
auditLogPath | string | ~/.lsvault/audit.log | Path to the audit log file |
import { LifestreamVaultClient } from '@lifestreamdynamics/vault-sdk';
const client = new LifestreamVaultClient({
baseUrl: 'https://vault.example.com',
apiKey: 'lsv_k_your_api_key_here',
timeout: 60000, // 60 seconds
enableRequestSigning: true,
enableAuditLogging: true,
auditLogPath: '/var/log/lsvault-audit.log',
});
The SDK throws typed errors that can be caught and handled:
import {
LifestreamVaultError,
NotFoundError,
ValidationError,
AuthenticationError,
AuthorizationError,
RateLimitError,
NetworkError,
} from '@lifestreamdynamics/vault-sdk';
try {
const doc = await client.documents.get(vaultId, 'missing.md');
} catch (error) {
if (error instanceof NotFoundError) {
console.error('Document not found:', error.resource);
} else if (error instanceof RateLimitError) {
console.error('Rate limited, retry after:', error.retryAfter);
} else if (error instanceof NetworkError) {
console.error('Network issue:', error.message);
}
}
All errors extend LifestreamVaultError and include the following properties:
statusCode — HTTP status code (if applicable)resource — The resource type that caused the error (e.g., 'document', 'vault')resourceId — The ID of the specific resource (if applicable)| Error Class | Description | Status Code |
|---|---|---|
LifestreamVaultError | Base error class | varies |
NotFoundError | Resource not found | 404 |
ValidationError | Invalid request parameters | 400 |
AuthenticationError | Authentication failed | 401 |
AuthorizationError | Insufficient permissions | 403 |
RateLimitError | Rate limit exceeded | 429 |
NetworkError | Network connectivity issue | -- |
The SDK includes several utility classes for advanced use cases:
Automatic JWT refresh with proactive renewal based on token expiry.
import { TokenManager } from '@lifestreamdynamics/vault-sdk';
const tokenManager = new TokenManager({
baseUrl: 'https://vault.example.com',
accessToken: 'eyJ...',
refreshToken: 'eyJ...',
refreshBufferMs: 60000, // Refresh 60s before expiry
onTokenRefresh: (tokens) => {
// Persist tokens securely (avoid localStorage — prefer httpOnly cookies or in-memory storage)
saveTokensToYourSecureStorage(tokens);
},
});
// Get current valid token (auto-refreshes if needed)
const token = await tokenManager.getToken();
HMAC-SHA256 request signing for API key authentication.
import { Signature } from '@lifestreamdynamics/vault-sdk';
const signature = Signature.sign(
apiKey,
method,
path,
timestamp,
body
);
// Verify signature
const isValid = Signature.verify(
apiKey,
method,
path,
timestamp,
body,
receivedSignature
);
AES-256-GCM encryption for vault data.
import { Encryption } from '@lifestreamdynamics/vault-sdk';
// Generate a new encryption key
const key = Encryption.generateKey();
// Encrypt data
const encrypted = Encryption.encrypt(key, 'sensitive data');
// Decrypt data
const decrypted = Encryption.decrypt(key, encrypted);
Client-side audit logging for security compliance.
import { AuditLogger } from '@lifestreamdynamics/vault-sdk/audit';
const logger = new AuditLogger({
enabled: true,
logPath: '/var/log/lsvault-audit.log',
});
// Log an operation
await logger.log({
operation: 'document.read',
userId: 'user-123',
resourceType: 'document',
resourceId: 'doc-456',
timestamp: new Date(),
});
Many list methods support pagination via limit and offset parameters:
async function getAllDocuments(vaultId: string) {
const allDocs = [];
let offset = 0;
const limit = 100;
while (true) {
const batch = await client.documents.list(vaultId, { limit, offset });
allDocs.push(...batch);
if (batch.length < limit) {
break; // No more results
}
offset += limit;
}
return allDocs;
}
import {
NotFoundError,
ValidationError,
AuthenticationError,
RateLimitError,
} from '@lifestreamdynamics/vault-sdk';
async function safeDocumentGet(vaultId: string, path: string) {
try {
return await client.documents.get(vaultId, path);
} catch (error) {
if (error instanceof NotFoundError) {
console.log('Document does not exist');
return null;
} else if (error instanceof AuthenticationError) {
// Token expired, refresh and retry
await refreshAuthToken();
return await client.documents.get(vaultId, path);
} else if (error instanceof RateLimitError) {
// Wait and retry
await new Promise(resolve => setTimeout(resolve, error.retryAfter * 1000));
return await client.documents.get(vaultId, path);
} else if (error instanceof ValidationError) {
console.error('Invalid parameters:', error.details);
throw error;
} else {
// Unknown error
console.error('Unexpected error:', error);
throw error;
}
}
}
// Upload multiple documents in parallel
async function uploadDocuments(vaultId: string, docs: Array<{ path: string; content: string }>) {
const results = await Promise.allSettled(
docs.map(doc => client.documents.put(vaultId, doc.path, doc.content))
);
const succeeded = results.filter(r => r.status === 'fulfilled').length;
const failed = results.filter(r => r.status === 'rejected').length;
console.log(`Uploaded ${succeeded} documents, ${failed} failed`);
return results;
}
When receiving webhook payloads, verify the HMAC signature:
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const computed = hmac.digest('hex');
return crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(signature));
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-lsvault-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
webhookSecret
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process webhook event
handleWebhookEvent(req.body);
res.status(200).send('OK');
});
name: Deploy Docs
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install SDK
run: npm install @lifestreamdynamics/vault-sdk
- name: Deploy documentation
env:
LSVAULT_API_KEY: ${{ secrets.LSVAULT_API_KEY }}
run: |
node scripts/deploy-docs.js
# scripts/deploy-docs.js
import { LifestreamVaultClient } from '@lifestreamdynamics/vault-sdk';
import fs from 'fs';
const client = new LifestreamVaultClient({
baseUrl: process.env.LSVAULT_BASE_URL,
apiKey: process.env.LSVAULT_API_KEY,
});
const vaultId = 'your-vault-id';
const docsDir = './docs';
for (const file of fs.readdirSync(docsDir)) {
if (file.endsWith('.md')) {
const content = fs.readFileSync(`${docsDir}/${file}`, 'utf-8');
await client.documents.put(vaultId, file, content);
console.log(`Uploaded ${file}`);
}
}
FROM node:18-alpine
WORKDIR /app
RUN npm install @lifestreamdynamics/vault-sdk
COPY sync-script.js .
CMD ["node", "sync-script.js"]
Manage vaults with the VaultsResource. The Vault type includes: id, name, slug, description (nullable), createdAt, updatedAt.
client.vaults() => Promise<Vault[]>List all vaults the authenticated user has access to.
Promise<Vault[]>const vaults = await client.vaults.list();
console.log(vaults);
(vaultId: string) => Promise<Vault>Get a single vault by ID.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The unique identifier of the vault |
Promise<Vault>const vault = await client.vaults.get('vault-123');
console.log('Vault name:', vault.name);
(params: { name: string; description?: string }) => Promise<Vault>Create a new vault.
| Name | Type | Required | Description |
|---|---|---|---|
| params.name | string | Yes | The name of the vault |
| params.description | string | No | Optional description for the vault |
Promise<Vault>const vault = await client.vaults.create({
name: 'My Notes',
description: 'Personal knowledge base',
});
console.log('Created vault:', vault.id);
(vaultId: string, params: { name?: string; description?: string | null }) => Promise<Vault>Update a vault's name or description.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The unique identifier of the vault |
| params.name | string | No | New name for the vault |
| params.description | string | null | No | New description (use null to clear) |
Promise<Vault>const updated = await client.vaults.update('vault-123', {
name: 'Updated Vault Name',
description: null, // Clear description
});
(vaultId: string) => Promise<void>Delete a vault permanently.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The unique identifier of the vault to delete |
Promise<void>await client.vaults.delete('vault-123');
console.log('Vault deleted');
Manage documents within vaults. The Document type includes: id, vaultId, path, title (nullable), contentHash, sizeBytes, tags, fileModifiedAt, createdAt, updatedAt.
client.documents(vaultId: string, dirPath?: string) => Promise<DocumentListItem[]>List documents in a vault, optionally filtered by directory.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| dirPath | string | No | Optional directory path to filter by |
Promise<DocumentListItem[]>// List all documents
const docs = await client.documents.list('vault-123');
// List documents in a specific directory
const notes = await client.documents.list('vault-123', 'notes/');
(vaultId: string, docPath: string) => Promise<DocumentWithContent>Get a document's metadata and content.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| docPath | string | Yes | The document path (e.g., "notes/hello.md") |
Promise<DocumentWithContent>const result = await client.documents.get(
'vault-123',
'notes/hello.md'
);
console.log('Title:', result.document.title);
console.log('Content:', result.content);
(vaultId: string, docPath: string, content: string) => Promise<Document>Create or update a document (upsert). Checks SHA-256 content hash to skip unchanged writes.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| docPath | string | Yes | The document path (must end with .md) |
| content | string | Yes | The markdown content |
Promise<Document>const doc = await client.documents.put(
'vault-123',
'notes/hello.md',
'# Hello World\n\nThis is my note.'
);
console.log('Document saved:', doc.path);
(vaultId: string, docPath: string) => Promise<void>Delete a document permanently.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| docPath | string | Yes | The document path |
Promise<void>await client.documents.delete('vault-123', 'notes/old.md');
console.log('Document deleted');
(vaultId: string, sourcePath: string, destination: string, overwrite?: boolean) => Promise<{ message: string; source: string; destination: string }>Move a document to a new path.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| sourcePath | string | Yes | Current document path |
| destination | string | Yes | New document path |
| overwrite | boolean | No(default: false) | Whether to overwrite if destination exists |
Promise<{ message: string; source: string; destination: string }>const result = await client.documents.move(
'vault-123',
'drafts/post.md',
'published/post.md',
true // overwrite if exists
);
console.log(result.message);
(vaultId: string, sourcePath: string, destination: string, overwrite?: boolean) => Promise<{ message: string; source: string; destination: string }>Copy a document to a new path.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| sourcePath | string | Yes | Source document path |
| destination | string | Yes | Destination document path |
| overwrite | boolean | No(default: false) | Whether to overwrite if destination exists |
Promise<{ message: string; source: string; destination: string }>const result = await client.documents.copy(
'vault-123',
'templates/meeting.md',
'meetings/2024-02-14.md'
);
console.log(result.message);
Full-text search across documents using PostgreSQL websearch_to_tsquery syntax. The SearchResponse includes: results (array of SearchResult objects), total count, and the executed query.
client.search(params: { q: string; vault?: string; tags?: string; limit?: number; offset?: number }) => Promise<SearchResponse>Search documents across all accessible vaults or within a specific vault.
| Name | Type | Required | Description |
|---|---|---|---|
| params.q | string | Yes | Search query (PostgreSQL websearch_to_tsquery syntax) |
| params.vault | string | No | Limit search to a specific vault ID |
| params.tags | string | No | Filter by tags (comma-separated) |
| params.limit | number | No | Maximum number of results to return |
| params.offset | number | No | Pagination offset |
Promise<SearchResponse>// Basic search
const results = await client.search.search({
q: 'typescript tutorial',
});
// Search within a vault with filters
const filtered = await client.search.search({
q: 'api documentation',
vault: 'vault-123',
tags: 'backend,nodejs',
limit: 20,
offset: 0,
});
console.log(`Found ${filtered.total} results`);
filtered.results.forEach(result => {
console.log(`${result.path}: ${result.snippet}`);
});
AI features including chat sessions and document summarization. Requires a subscription tier that includes AI features. The AiChatSession type includes: id, title, vaultId (nullable), createdAt, updatedAt. The AiChatMessage type includes: id, role (user/assistant/system), content, tokensUsed, createdAt.
client.aiPro or higher(params: { message: string; sessionId?: string; vaultId?: string }) => Promise<{ sessionId: string; message: { role: string; content: string; sources: string[] }; tokensUsed: number }>Send a chat message and receive an AI response with optional vault context.
| Name | Type | Required | Description |
|---|---|---|---|
| params.message | string | Yes | The chat message to send |
| params.sessionId | string | No | Existing session ID (creates new if omitted) |
| params.vaultId | string | No | Vault ID for context-aware responses |
Promise<{ sessionId: string; message: { role: string; content: string; sources: string[] }; tokensUsed: number }>const response = await client.ai.chat({
message: 'Summarize my recent notes about TypeScript',
vaultId: 'vault-123',
});
console.log('AI:', response.message.content);
console.log('Sources:', response.message.sources);
console.log('Session ID:', response.sessionId);
() => Promise<AiChatSession[]>List all AI chat sessions for the authenticated user.
Promise<AiChatSession[]>const sessions = await client.ai.listSessions();
sessions.forEach(session => {
console.log(`${session.title} - ${session.createdAt}`);
});
(sessionId: string) => Promise<{ session: AiChatSession; messages: AiChatMessage[] }>Get a chat session with its full message history.
| Name | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | The session ID |
Promise<{ session: AiChatSession; messages: AiChatMessage[] }>const { session, messages } = await client.ai.getSession('session-123');
console.log('Session:', session.title);
messages.forEach(msg => {
console.log(`${msg.role}: ${msg.content}`);
});
(sessionId: string) => Promise<void>Delete a chat session and all its messages.
| Name | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | The session ID to delete |
Promise<void>await client.ai.deleteSession('session-123');
console.log('Session deleted');
(vaultId: string, documentPath: string) => Promise<{ summary: string; keyTopics: string[]; tokensUsed: number }>Generate an AI summary of a document with key topics.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| documentPath | string | Yes | The document path |
Promise<{ summary: string; keyTopics: string[]; tokensUsed: number }>const result = await client.ai.summarize(
'vault-123',
'research/paper.md'
);
console.log('Summary:', result.summary);
console.log('Key Topics:', result.keyTopics.join(', '));
console.log('Tokens Used:', result.tokensUsed);
Manage API keys for programmatic access. API keys use the lsv_k_ prefix and can be scoped to specific vaults and permissions.
client.apiKeys() => Promise<ApiKey[]>List all API keys for the authenticated user.
Promise<ApiKey[]>const keys = await client.apiKeys.list();
keys.forEach(key => {
console.log(`${key.name}: ${key.prefix}... (active: ${key.isActive})`);
});
(keyId: string) => Promise<ApiKey>Get a specific API key by ID.
| Name | Type | Required | Description |
|---|---|---|---|
| keyId | string | Yes | The API key ID |
Promise<ApiKey>const key = await client.apiKeys.get('key-123');
console.log('Key name:', key.name);
console.log('Scopes:', key.scopes);
(params: CreateApiKeyParams) => Promise<ApiKeyWithSecret>Create a new API key. The secret is returned only at creation time.
| Name | Type | Required | Description |
|---|---|---|---|
| params.name | string | Yes | A descriptive name for the key |
| params.scopes | string[] | Yes | Array of permission scopes (e.g., ["documents:read", "documents:write"]) |
| params.vaultId | string | No | Limit key access to a specific vault |
| params.expiresAt | Date | string | No | Optional expiration date |
Promise<ApiKeyWithSecret>const key = await client.apiKeys.create({
name: 'CI/CD Pipeline',
scopes: ['documents:read', 'documents:write'],
vaultId: 'vault-123',
expiresAt: '2025-12-31',
});
console.log('API Key:', key.key);
console.log('Save this key securely - it cannot be retrieved again!');
(keyId: string, params: UpdateApiKeyParams) => Promise<ApiKey>Update an API key's name or active status.
| Name | Type | Required | Description |
|---|---|---|---|
| keyId | string | Yes | The API key ID |
| params.name | string | No | New name for the key |
| params.isActive | boolean | No | Activate or deactivate the key |
Promise<ApiKey>// Deactivate a key
const updated = await client.apiKeys.update('key-123', {
isActive: false,
});
console.log('Key deactivated:', updated.name);
(keyId: string) => Promise<void>Delete an API key permanently.
| Name | Type | Required | Description |
|---|---|---|---|
| keyId | string | Yes | The API key ID to delete |
Promise<void>await client.apiKeys.delete('key-123');
console.log('API key deleted');
Manage user profile and storage information.
client.user() => Promise<User>Get the authenticated user's profile information.
Promise<User>const user = await client.user.me();
console.log('Email:', user.email);
console.log('Name:', user.name);
console.log('Role:', user.role);
console.log('Tier:', user.subscriptionTier);
() => Promise<StorageUsage>Get storage usage breakdown per vault.
Promise<StorageUsage>const storage = await client.user.getStorage();
console.log('Total bytes:', storage.totalBytes);
console.log('Total MB:', (storage.totalBytes / 1024 / 1024).toFixed(2));
storage.vaults.forEach(vault => {
console.log(` ${vault.name}: ${vault.sizeBytes} bytes`);
});
Manage subscription tiers, billing, and usage limits.
client.subscription() => Promise<Subscription>Get current subscription details and usage information.
Promise<Subscription>const subscription = await client.subscription.get();
console.log('Tier:', subscription.tier);
console.log('Active:', subscription.isActive);
console.log('Expires:', subscription.expiresAt);
console.log('Usage:', subscription.usage);
() => Promise<Plan[]>List available subscription plans with features and pricing.
Promise<Plan[]>const plans = await client.subscription.listPlans();
plans.forEach(plan => {
console.log(`${plan.name}: $${plan.priceMonthly}/month`);
console.log('Features:', plan.features);
});
(tier: string, returnUrl: string) => Promise<CheckoutSession>Create a checkout session for upgrading to a new tier.
| Name | Type | Required | Description |
|---|---|---|---|
| tier | string | Yes | The target tier (e.g., "pro", "business") |
| returnUrl | string | Yes | URL to redirect to after checkout |
Promise<CheckoutSession>const session = await client.subscription.createCheckoutSession(
'pro',
'https://myapp.com/settings/subscription'
);
// Redirect user to checkout URL
window.location.href = session.url;
(reason?: string) => Promise<void>Cancel the current subscription.
| Name | Type | Required | Description |
|---|---|---|---|
| reason | string | No | Optional cancellation reason for feedback |
Promise<void>await client.subscription.cancel('Switching to self-hosted');
console.log('Subscription cancelled');
(returnUrl: string) => Promise<PortalSession>Create a billing portal session for managing payment methods and invoices.
| Name | Type | Required | Description |
|---|---|---|---|
| returnUrl | string | Yes | URL to redirect to after portal session |
Promise<PortalSession>const portal = await client.subscription.createPortalSession(
'https://myapp.com/settings/subscription'
);
// Redirect to billing portal
window.location.href = portal.url;
() => Promise<Invoice[]>List all invoices for the subscription.
Promise<Invoice[]>const invoices = await client.subscription.listInvoices();
invoices.forEach(invoice => {
console.log(`${invoice.date}: $${invoice.amount} - ${invoice.status}`);
});
Manage teams, members, invitations, and team vaults. Teams enable collaboration with role-based access control (owner, admin, member).
client.teams() => Promise<Team[]>List teams the authenticated user belongs to.
Promise<Team[]>const teams = await client.teams.list();
teams.forEach(team => {
console.log(`${team.name} - Role: ${team.myRole}`);
});
(teamId: string) => Promise<Team>Get a team by ID.
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
Promise<Team>const team = await client.teams.get('team-123');
console.log('Team:', team.name);
console.log('Description:', team.description);
(params: { name: string; description?: string }) => Promise<Team>Create a new team. The creator becomes the owner.
| Name | Type | Required | Description |
|---|---|---|---|
| params.name | string | Yes | Team name |
| params.description | string | No | Team description |
Promise<Team>const team = await client.teams.create({
name: 'Engineering',
description: 'Backend engineering team',
});
console.log('Team created:', team.id);
(teamId: string, params: UpdateTeamParams) => Promise<Team>Update a team's name or description (requires admin or owner role).
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
| params.name | string | No | New team name |
| params.description | string | No | New team description |
Promise<Team>const updated = await client.teams.update('team-123', {
description: 'Updated team description',
});
(teamId: string) => Promise<void>Delete a team (owner only).
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID to delete |
Promise<void>await client.teams.delete('team-123');
console.log('Team deleted');
(teamId: string) => Promise<TeamMember[]>List all members of a team.
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
Promise<TeamMember[]>const members = await client.teams.listMembers('team-123');
members.forEach(member => {
console.log(`${member.name} (${member.email}) - ${member.role}`);
});
(teamId: string, userId: string, role: "admin" | "member") => Promise<TeamMember>Update a team member's role (requires admin or owner).
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
| userId | string | Yes | The user ID |
| role | "admin" | "member" | Yes | The new role |
Promise<TeamMember>const member = await client.teams.updateMemberRole(
'team-123',
'user-456',
'admin'
);
console.log('Updated role to:', member.role);
(teamId: string, userId: string) => Promise<void>Remove a member from the team (requires admin or owner).
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
| userId | string | Yes | The user ID to remove |
Promise<void>await client.teams.removeMember('team-123', 'user-456');
console.log('Member removed');
(teamId: string) => Promise<void>Leave a team (cannot leave if you are the only owner).
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID to leave |
Promise<void>await client.teams.leave('team-123');
console.log('Left team');
(teamId: string, email: string, role: "admin" | "member") => Promise<TeamInvitation>Invite a user to the team (requires admin or owner).
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
string | Yes | Email address to invite | |
| role | "admin" | "member" | Yes | Role for the invited user |
Promise<TeamInvitation>const invitation = await client.teams.inviteMember(
'team-123',
'alice@example.com',
'member'
);
console.log('Invitation sent:', invitation.id);
(teamId: string) => Promise<TeamInvitation[]>List pending invitations for a team.
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
Promise<TeamInvitation[]>const invitations = await client.teams.listInvitations('team-123');
invitations.forEach(inv => {
console.log(`${inv.email} - ${inv.status}`);
});
(teamId: string, invitationId: string) => Promise<void>Revoke a pending invitation.
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
| invitationId | string | Yes | The invitation ID |
Promise<void>await client.teams.revokeInvitation('team-123', 'inv-456');
console.log('Invitation revoked');
(teamId: string, params: { name: string; description?: string }) => Promise<Record<string, unknown>>Create a vault under the team scope.
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
| params.name | string | Yes | Vault name |
| params.description | string | No | Vault description |
Promise<Record<string, unknown>>const vault = await client.teams.createVault('team-123', {
name: 'Shared Documentation',
description: 'Team knowledge base',
});
console.log('Team vault created:', vault);
(teamId: string) => Promise<Record<string, unknown>[]>List all vaults belonging to the team.
| Name | Type | Required | Description |
|---|---|---|---|
| teamId | string | Yes | The team ID |
Promise<Record<string, unknown>[]>const vaults = await client.teams.listVaults('team-123');
console.log('Team vaults:', vaults);
Public document publishing with SEO metadata. Published documents appear at /:profileSlug/:docSlug with custom title, description, and OG image.
client.publish(vaultId: string) => Promise<PublishedDocumentWithMeta[]>List the authenticated user's published documents.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
Promise<PublishedDocumentWithMeta[]>const published = await client.publish.listMine('vault-123');
published.forEach(doc => {
console.log(`${doc.slug}: ${doc.seoTitle}`);
console.log(` URL: https://vault.example.com/${doc.profileSlug}/${doc.slug}`);
});
(vaultId: string, documentPath: string, params: PublishDocumentParams) => Promise<PublishedDocument>Publish a document with SEO settings.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| documentPath | string | Yes | The document path |
| params.slug | string | Yes | URL slug for the published document |
| params.seoTitle | string | No | SEO title (falls back to document title) |
| params.seoDescription | string | No | SEO description |
| params.ogImage | string | No | Open Graph image URL |
Promise<PublishedDocument>const published = await client.publish.create(
'vault-123',
'blog/my-post.md',
{
slug: 'my-first-post',
seoTitle: 'My First Blog Post',
seoDescription: 'An introduction to my blog',
ogImage: 'https://example.com/og-image.png',
}
);
console.log('Published at:', `/${published.profileSlug}/${published.slug}`);
(vaultId: string, documentPath: string, params: UpdatePublishParams) => Promise<PublishedDocument>Update publish settings for a document.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| documentPath | string | Yes | The document path |
| params | UpdatePublishParams | Yes | Fields to update |
Promise<PublishedDocument>const updated = await client.publish.update(
'vault-123',
'blog/my-post.md',
{
seoTitle: 'Updated Title',
seoDescription: 'Updated description',
}
);
(vaultId: string, documentPath: string) => Promise<void>Unpublish a document.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| documentPath | string | Yes | The document path |
Promise<void>await client.publish.delete('vault-123', 'blog/my-post.md');
console.log('Document unpublished');
External service integration for bidirectional sync (Google Drive, etc.). Managed by BullMQ workers with sync logging.
client.connectorsRequires connectors plan feature(vaultId?: string) => Promise<Connector[]>List connectors, optionally filtered by vault.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | No | Optional vault ID to filter by |
Promise<Connector[]>// List all connectors
const connectors = await client.connectors.list();
// List connectors for a specific vault
const vaultConnectors = await client.connectors.list('vault-123');
connectors.forEach(conn => {
console.log(`${conn.name} (${conn.provider}): ${conn.direction}`);
});
(connectorId: string) => Promise<Connector>Get a connector by ID.
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | Yes | The connector ID |
Promise<Connector>const connector = await client.connectors.get('conn-123');
console.log('Provider:', connector.provider);
console.log('Direction:', connector.direction);
console.log('Last sync:', connector.lastSyncAt);
(params: CreateConnectorParams) => Promise<Connector>Create a new connector.
| Name | Type | Required | Description |
|---|---|---|---|
| params.provider | string | Yes | Provider type (e.g., "google_drive") |
| params.name | string | Yes | Connector name |
| params.vaultId | string | Yes | Target vault ID |
| params.direction | string | Yes | Sync direction ("pull", "push", "bidirectional") |
| params.config | object | Yes | Provider-specific configuration |
Promise<Connector>const connector = await client.connectors.create({
provider: 'google_drive',
name: 'My Google Drive',
vaultId: 'vault-123',
direction: 'bidirectional',
config: {
folderId: 'google-folder-id-here',
credentials: { /* OAuth tokens */ },
},
});
console.log('Connector created:', connector.id);
(connectorId: string, params: UpdateConnectorParams) => Promise<Connector>Update a connector's configuration or active status.
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | Yes | The connector ID |
| params | UpdateConnectorParams | Yes | Fields to update |
Promise<Connector>const updated = await client.connectors.update('conn-123', {
name: 'Updated Connector Name',
isActive: true,
});
(connectorId: string) => Promise<void>Delete a connector.
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | Yes | The connector ID |
Promise<void>await client.connectors.delete('conn-123');
console.log('Connector deleted');
(connectorId: string) => Promise<TestConnectionResult>Test a connector's connection to the external service.
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | Yes | The connector ID |
Promise<TestConnectionResult>const result = await client.connectors.test('conn-123');
if (result.success) {
console.log('Connection successful');
} else {
console.error('Connection failed:', result.error);
}
(connectorId: string) => Promise<TriggerSyncResult>Trigger a manual sync for a connector.
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | Yes | The connector ID |
Promise<TriggerSyncResult>const result = await client.connectors.sync('conn-123');
console.log('Sync triggered:', result.jobId);
(connectorId: string) => Promise<ConnectorSyncLog[]>List recent sync logs for a connector.
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | Yes | The connector ID |
Promise<ConnectorSyncLog[]>const logs = await client.connectors.logs('conn-123');
logs.forEach(log => {
console.log(`${log.startedAt}: ${log.status}`);
console.log(` Added: ${log.itemsAdded}, Updated: ${log.itemsUpdated}, Failed: ${log.itemsFailed}`);
if (log.error) console.log(` Error: ${log.error}`);
});
Internal event handlers (auto-tag, template, etc.) configured per vault and executed automatically on document events.
client.hooksPro or higher(vaultId: string) => Promise<Hook[]>List hooks configured for a vault.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
Promise<Hook[]>const hooks = await client.hooks.list('vault-123');
hooks.forEach(hook => {
console.log(`${hook.name}: ${hook.event} -> ${hook.action}`);
});
(vaultId: string, params: CreateHookParams) => Promise<Hook>Create a new hook for automatic event handling.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| params.name | string | Yes | Hook name |
| params.event | string | Yes | Event type (e.g., "document.create") |
| params.action | string | Yes | Action to perform (e.g., "auto-tag") |
| params.config | object | Yes | Hook-specific configuration |
Promise<Hook>const hook = await client.hooks.create('vault-123', {
name: 'Auto-tag new docs',
event: 'document.create',
action: 'auto-tag',
config: { tags: ['new', 'unreviewed'] },
});
console.log('Hook created:', hook.id);
(vaultId: string, hookId: string, params: UpdateHookParams) => Promise<Hook>Update a hook's configuration or active status.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| hookId | string | Yes | The hook ID |
| params | UpdateHookParams | Yes | Fields to update |
Promise<Hook>const updated = await client.hooks.update('vault-123', 'hook-456', {
isActive: false,
});
console.log('Hook deactivated');
(vaultId: string, hookId: string) => Promise<void>Delete a hook.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| hookId | string | Yes | The hook ID |
Promise<void>await client.hooks.delete('vault-123', 'hook-456');
console.log('Hook deleted');
(vaultId: string, hookId: string) => Promise<HookExecution[]>List recent executions of a hook.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| hookId | string | Yes | The hook ID |
Promise<HookExecution[]>const executions = await client.hooks.listExecutions('vault-123', 'hook-456');
executions.forEach(exec => {
console.log(`${exec.createdAt}: ${exec.status}`);
if (exec.error) console.log('Error:', exec.error);
});
Outbound HTTP notifications with retry logic for vault events. Webhooks are delivered to external URLs with HMAC signature verification.
client.webhooksPro or higher(vaultId: string) => Promise<Webhook[]>List webhooks configured for a vault.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
Promise<Webhook[]>const webhooks = await client.webhooks.list('vault-123');
webhooks.forEach(webhook => {
console.log(`${webhook.url}: ${webhook.events.join(', ')}`);
});
(vaultId: string, params: CreateWebhookParams) => Promise<WebhookWithSecret>Create a webhook. The signing secret is returned only at creation time.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| params.url | string | Yes | The webhook URL |
| params.events | string[] | Yes | Event types to subscribe to |
| params.description | string | No | Optional description |
Promise<WebhookWithSecret>const webhook = await client.webhooks.create('vault-123', {
url: 'https://example.com/webhook',
events: ['document.create', 'document.update', 'document.delete'],
description: 'Sync to external system',
});
console.log('Webhook URL:', webhook.url);
console.log('Secret (save securely):', webhook.secret);
(vaultId: string, webhookId: string, params: UpdateWebhookParams) => Promise<Webhook>Update a webhook's URL, events, or active status.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| webhookId | string | Yes | The webhook ID |
| params | UpdateWebhookParams | Yes | Fields to update |
Promise<Webhook>const updated = await client.webhooks.update('vault-123', 'webhook-456', {
events: ['document.create', 'document.update'],
isActive: true,
});
(vaultId: string, webhookId: string) => Promise<void>Delete a webhook.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| webhookId | string | Yes | The webhook ID |
Promise<void>await client.webhooks.delete('vault-123', 'webhook-456');
console.log('Webhook deleted');
(vaultId: string, webhookId: string) => Promise<WebhookDelivery[]>List recent delivery attempts for a webhook.
| Name | Type | Required | Description |
|---|---|---|---|
| vaultId | string | Yes | The vault ID |
| webhookId | string | Yes | The webhook ID |
Promise<WebhookDelivery[]>const deliveries = await client.webhooks.listDeliveries('vault-123', 'webhook-456');
deliveries.forEach(delivery => {
console.log(`${delivery.createdAt}: ${delivery.status} (${delivery.statusCode})`);
if (delivery.error) console.log('Error:', delivery.error);
});
System administration endpoints for statistics, user management, and health monitoring. Requires admin role.
client.adminAdmin role required() => Promise<SystemStats>Get system-wide statistics.
Promise<SystemStats>const stats = await client.admin.getStats();
console.log('Total users:', stats.totalUsers);
console.log('Total documents:', stats.totalDocuments);
console.log('Total storage (GB):', (stats.totalStorageBytes / 1024 / 1024 / 1024).toFixed(2));
(metric: string, period: string) => Promise<TimeseriesResponse>Get timeseries data for a specific metric and period.
| Name | Type | Required | Description |
|---|---|---|---|
| metric | string | Yes | Metric name ("signups", "documents", "storage") |
| period | string | Yes | Time period ("7d", "30d", "90d") |
Promise<TimeseriesResponse>const data = await client.admin.getTimeseries('signups', '30d');
data.dataPoints.forEach(point => {
console.log(`${point.date}: ${point.value}`);
});
(params?: AdminUserListParams) => Promise<AdminUserListResponse>List users with filtering and pagination.
| Name | Type | Required | Description |
|---|---|---|---|
| params.search | string | No | Search by email or name |
| params.tier | string | No | Filter by subscription tier |
| params.role | string | No | Filter by role |
| params.limit | number | No | Page size |
| params.offset | number | No | Pagination offset |
Promise<AdminUserListResponse>const result = await client.admin.listUsers({
tier: 'pro',
limit: 50,
offset: 0,
});
console.log(`Found ${result.total} pro users`);
result.users.forEach(user => {
console.log(`${user.email} - ${user.subscriptionTier}`);
});
(userId: string) => Promise<AdminUserDetail>Get detailed user information.
| Name | Type | Required | Description |
|---|---|---|---|
| userId | string | Yes | The user ID |
Promise<AdminUserDetail>const user = await client.admin.getUser('user-123');
console.log('Email:', user.email);
console.log('Role:', user.role);
console.log('Tier:', user.subscriptionTier);
console.log('Storage:', user.storageUsage);
(userId: string, params: AdminUpdateUserParams) => Promise<AdminUser>Update user role, status, or subscription tier.
| Name | Type | Required | Description |
|---|---|---|---|
| userId | string | Yes | The user ID |
| params.role | string | No | New role (user/admin) |
| params.subscriptionTier | string | No | New subscription tier |
| params.isActive | boolean | No | Activate or deactivate account |
Promise<AdminUser>const updated = await client.admin.updateUser('user-123', {
role: 'admin',
subscriptionTier: 'business',
});
console.log('User updated:', updated.email);
(limit?: number) => Promise<ActivityEntry[]>Get recent system-wide activity.
| Name | Type | Required | Description |
|---|---|---|---|
| limit | number | No(default: 100) | Maximum number of entries to return |
Promise<ActivityEntry[]>const activity = await client.admin.getActivity(50);
activity.forEach(entry => {
console.log(`${entry.timestamp}: ${entry.action} by ${entry.userEmail}`);
});
() => Promise<SubscriptionSummary>Get per-tier user counts and revenue summary.
Promise<SubscriptionSummary>const summary = await client.admin.getSubscriptionSummary();
console.log('Free users:', summary.tiers.free);
console.log('Pro users:', summary.tiers.pro);
console.log('Business users:', summary.tiers.business);
console.log('Total MRR:', summary.totalMRR);
() => Promise<SystemHealth>Check database and Redis health status.
Promise<SystemHealth>const health = await client.admin.getHealth();
console.log('Database:', health.database.status);
console.log('Redis:', health.redis.status);
console.log('Overall:', health.status);