Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.velt.dev/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Velt Node SDK exposes two independent backends:
BackendNamespaceUse case
Self-hostingsdk.selfHosting.*Store Velt data in your own MongoDB + AWS S3
REST APIsdk.api.*Call Velt’s REST APIs directly — no database required
Self-hosting backend (sdk.selfHosting.*) simplifies backend implementation by 90%. Instead of writing custom database queries and storage logic, you:
  1. Pass your DB and storage configs to the SDK
  2. Call the relevant SDK method with the raw request payload
  3. Return the resulting response directly to the client
REST API backend (sdk.api.*) provides feature parity with the Velt Python SDK. 17 services, fully-typed TypeScript request objects, and raw Velt API responses. No database or AWS configuration needed.

Installation

npm install @veltdev/node
For self-hosting, also install the optional peer dependencies you plan to use:
npm install mongodb              # required for self-hosting backend
npm install @aws-sdk/client-s3   # required only if using S3 for attachments

Requirements

  • Node.js 18+
  • TypeScript 5.x (optional — JavaScript is fully supported)
  • MongoDB 6+ (Percona Server or MongoDB Atlas) for self-hosting
  • mongodb ^6 and @aws-sdk/client-s3 ^3 as optional peer dependencies

Quick Start

Initialize the SDK

Self-hosting initialization (MongoDB + optional AWS):
import { VeltSDK } from '@veltdev/node';

const sdk = VeltSDK.initialize({
  database: {
    host: 'localhost:27017',
    username: 'your-username',
    password: 'your-password',
    auth_database: 'admin',
    database_name: 'velt-integration',
  },
  apiKey: 'YOUR_VELT_API_KEY',
  authToken: 'YOUR_VELT_AUTH_TOKEN'
});
REST API-only initialization (no database needed):
import { VeltSDK } from '@veltdev/node';

const sdk = VeltSDK.initialize({
  apiKey: 'YOUR_VELT_API_KEY',
  authToken: 'YOUR_VELT_AUTH_TOKEN'
});

// All sdk.api.* services are now available
const result = await sdk.api.organizations.getOrganizations({ organizationIds: ['org-123'] });
The database section is optional when using only sdk.api.*. Set VELT_API_KEY and VELT_AUTH_TOKEN environment variables as an alternative to passing credentials in the config object.

Shutdown

Call await sdk.close() when your process exits to release the database connection pool.

Configuration

Environment Variables

VariableConfig key equivalentPurpose
VELT_API_KEYapiKeyVelt API key for authenticating REST API calls
VELT_AUTH_TOKENauthTokenVelt auth token for authenticating REST API calls
VELT_WORKSPACE_IDDefault workspace ID for workspace-scoped operations
VELT_WORKSPACE_AUTH_TOKENAuth token scoped to a specific workspace
AWS_ACCESS_KEY_IDAWS access key for S3 attachments
AWS_SECRET_ACCESS_KEYAWS secret key for S3 attachments
AWS_REGIONAWS region for S3
AWS_S3_BUCKET_NAMES3 bucket name for attachments
AWS_S3_ENDPOINT_URLCustom S3 endpoint (e.g., for MinIO)

Self-Hosting Configuration

Configure MongoDB connection for storing comments, reactions, and user data.
const sdk = VeltSDK.initialize({
  database: {
    // Option 1: Connection string (recommended for MongoDB Atlas)
    // Overrides host/username/password if provided
    connection_string: 'mongodb+srv://user:pass@cluster.mongodb.net/velt-db',

    // Option 2: Individual components
    // host: 'localhost:27017',
    // username: 'your-username',
    // password: 'your-password',
    // auth_database: 'admin',
    // database_name: 'velt-db',

    // Optional fields:
    // type: 'mongodb',       // defaults to 'mongodb'
    // use_srv: true,         // use mongodb+srv:// (auto-detected for *.mongodb.net hosts)
  }
});

Self-Hosting Backend

Each self-hosting service is loaded asynchronously on first access via await sdk.selfHosting.getXxx(). The service is cached after the first call. The token service is the exception — it is available as a direct synchronous property via sdk.selfHosting.token.

Comments

Access via await sdk.selfHosting.getComments().

getComments

const commentsService = await sdk.selfHosting.getComments();
const result = await commentsService.getComments({
  organizationId: 'org-123',
  documentIds: ['doc-1'],
});
Response
{
  success: true,
  statusCode: 200,
  data: { /* comment annotations keyed by annotationId */ }
}

saveComments

const commentsService = await sdk.selfHosting.getComments();
const result = await commentsService.saveComments({
  metadata: { organizationId: 'org-123', documentId: 'doc-1' },
  commentAnnotation: {
    'annotation-1': {
      annotationId: 'annotation-1',
      comments: { '123456': { commentId: '123456', commentText: 'Hello' } },
      metadata: {},
    },
  },
});
Response
{ success: true, statusCode: 200, data: { saved: true } }

deleteComment

const commentsService = await sdk.selfHosting.getComments();
const result = await commentsService.deleteComment({
  commentAnnotationId: 'annotation-1',
  metadata: { organizationId: 'org-123' },
});
Response
{ success: true, statusCode: 200, data: { deleted: true } }

Reactions

Access via await sdk.selfHosting.getReactions().

getReactions

const reactionsService = await sdk.selfHosting.getReactions();
const result = await reactionsService.getReactions({
  organizationId: 'org-123',
  documentIds: ['doc-1'],
});
Response
{ success: true, statusCode: 200, data: { /* reaction annotations */ } }

saveReactions

const reactionsService = await sdk.selfHosting.getReactions();
const result = await reactionsService.saveReactions({
  metadata: { organizationId: 'org-123', documentId: 'doc-1' },
  reactionAnnotation: {
    'reaction-1': { annotationId: 'reaction-1', icon: 'thumbsup', metadata: {} },
  },
});
Response
{ success: true, statusCode: 200, data: { saved: true } }

deleteReaction

const reactionsService = await sdk.selfHosting.getReactions();
const result = await reactionsService.deleteReaction({
  reactionAnnotationId: 'reaction-1',
  metadata: { organizationId: 'org-123' },
});
Response
{ success: true, statusCode: 200, data: { deleted: true } }

Attachments

Access via await sdk.selfHosting.getAttachments().

getAttachment

  • Fetches an attachment record by organization and attachment ID.
  • Params: positional — organizationId (string), attachmentId (number)
  • Returns: VeltSelfHostingResponse
const attachmentsService = await sdk.selfHosting.getAttachments();
const result = await attachmentsService.getAttachment('org-123', 12345);
Response
{
  success: true,
  statusCode: 200,
  data: {
    attachmentId: 12345,
    name: 'document.pdf',
    mimeType: 'application/pdf',
    size: 1024,
    url: 'https://s3.amazonaws.com/...'
  }
}

saveAttachment

const attachmentsService = await sdk.selfHosting.getAttachments();
const result = await attachmentsService.saveAttachment(
  {
    metadata: { organizationId: 'org-123', documentId: 'doc-1' },
    attachment: {
      attachmentId: 12345,
      name: 'document.pdf',
      mimeType: 'application/pdf',
      size: 1024,
    },
  },
  fileBuffer,        // optional Buffer for S3 upload
  'document.pdf',    // optional
  'application/pdf'  // optional
);
Response
{ success: true, statusCode: 200, data: { saved: true, attachmentId: 12345 } }

deleteAttachment

const attachmentsService = await sdk.selfHosting.getAttachments();
const result = await attachmentsService.deleteAttachment({
  attachmentId: 12345,
  metadata: { organizationId: 'org-123' },
});
Response
{ success: true, statusCode: 200, data: { deleted: true } }

Users

Access via await sdk.selfHosting.getUsers().

getUsers

const usersService = await sdk.selfHosting.getUsers();
const result = await usersService.getUsers({
  organizationId: 'org-123',
  userIds: ['user-1'],
});
Response
{
  success: true,
  statusCode: 200,
  data: [{ userId: 'user-1', name: 'John Doe', email: 'john@example.com' }]
}

Recorder

Access via await sdk.selfHosting.getRecorder().

getRecorderAnnotations

const recorderService = await sdk.selfHosting.getRecorder();
const result = await recorderService.getRecorderAnnotations({
  organizationId: 'org-123',
  documentIds: ['doc-1'],
});
Response
{ success: true, statusCode: 200, data: { /* recorder annotations */ } }

saveRecorderAnnotation

const recorderService = await sdk.selfHosting.getRecorder();
const result = await recorderService.saveRecorderAnnotation({
  metadata: { organizationId: 'org-123', documentId: 'doc-1' },
  recorderAnnotation: { annotationId: 'rec-1', metadata: {} },
});
Response
{ success: true, statusCode: 200, data: { saved: true } }

deleteRecorderAnnotation

const recorderService = await sdk.selfHosting.getRecorder();
const result = await recorderService.deleteRecorderAnnotation({
  recorderAnnotationId: 'rec-1',
  metadata: { organizationId: 'org-123' },
});
Response
{ success: true, statusCode: 200, data: { deleted: true } }

Notifications

Access via await sdk.selfHosting.getNotifications().

getNotifications

const notificationsService = await sdk.selfHosting.getNotifications();
const result = await notificationsService.getNotifications({
  organizationId: 'org-123',
  userId: 'user-1',
});
Response
{ success: true, statusCode: 200, data: [/* notifications */] }

saveNotifications

const notificationsService = await sdk.selfHosting.getNotifications();
await notificationsService.saveNotifications({
  metadata: { organizationId: 'org-123', documentId: 'doc-1' },
  notifications: [{ id: 'n-1', actionUser: { userId: 'user-1' }, displayBodyMessage: 'Hello' }],
});
Response
{ success: true, statusCode: 200, data: { saved: true } }

deleteNotification

const notificationsService = await sdk.selfHosting.getNotifications();
await notificationsService.deleteNotification({
  notificationId: 'n-1',
  metadata: { organizationId: 'org-123', userId: 'user-1' },
});
Response
{ success: true, statusCode: 200, data: { deleted: true } }

Activities

Access via await sdk.selfHosting.getActivities().

getActivities

const activitiesService = await sdk.selfHosting.getActivities();
const result = await activitiesService.getActivities({
  organizationId: 'org-123',
  documentId: 'doc-1',
});
Response
{ success: true, statusCode: 200, data: [/* activities */] }

saveActivities

const activitiesService = await sdk.selfHosting.getActivities();
await activitiesService.saveActivities({
  metadata: { organizationId: 'org-123', documentId: 'doc-1' },
  activities: [{ id: 'activity-1', featureType: 'comment', actionType: 'comment.add' }],
});
Response
{ success: true, statusCode: 200, data: { saved: true } }

Token

Access via the synchronous sdk.selfHosting.token property (no await).

getToken

  • Generates a Velt auth token for a user.
  • Params: positional — organizationId (string), userId (string), email (string, optional), isAdmin (boolean, optional)
  • Returns: VeltSelfHostingResponse
Note: getToken takes positional arguments — not a request object.
const tokenResult = await sdk.selfHosting.token.getToken(
  'org-123',
  'user-1',
  'john@example.com',
  false
);
const token = (tokenResult.data as { token: string }).token;
Response
{ success: true, statusCode: 200, data: { token: 'eyJhbGciOiJIUzI1NiIs...' } }

REST API Backend

The sdk.api.* namespace provides 17 services covering all Velt REST API operations. No database or AWS configuration is required — only apiKey and authToken. Every sdk.api.* method requires an organizationId in its request payload. Velt enforces data isolation per-organization server-side.

Organizations

Namespace: sdk.api.organizations

addOrganizations

await sdk.api.organizations.addOrganizations({
  organizations: [{ organizationId: 'org-123', organizationName: 'My Organization' }],
});
Response
{
  result: {
    status: 'success',
    message: 'Organization(s) added successfully.',
    data: {
      'org-123': { success: true, id: '02cf91e5...', message: 'Added Successfully' }
    }
  }
}

getOrganizations

await sdk.api.organizations.getOrganizations({
  organizationIds: ['org-123'],
  pageSize: 10,
  pageToken: 'next-page-token',
});
Response
{
  result: {
    status: 'success',
    message: 'Organization(s) retrieved successfully.',
    data: [
      { id: 'org-123', organizationName: 'Your Organization Name', disabled: false }
    ],
    nextPageToken: 'pageToken'
  }
}

updateOrganizations

await sdk.api.organizations.updateOrganizations({
  organizations: [{ organizationId: 'org-123', organizationName: 'Updated Name' }],
});
Response
{ result: { status: 'success', message: 'Organization(s) updated successfully.', data: {} } }

deleteOrganizations

await sdk.api.organizations.deleteOrganizations({ organizationIds: ['org-123'] });
Response
{ result: { status: 'success', message: 'Organization(s) deleted successfully.', data: {} } }

updateOrganizationDisableState

await sdk.api.organizations.updateOrganizationDisableState({
  organizationIds: ['org-123'],
  disabled: true,
});
Response
{ result: { status: 'success', message: 'Organization(s) disable state updated.', data: {} } }

Folders

Namespace: sdk.api.folders

addFolder

await sdk.api.folders.addFolder({
  organizationId: 'org-123',
  folders: [{ folderId: 'folder-1', folderName: 'My Folder' }],
  createOrganization: true,
});
Response
{ result: { status: 'success', message: 'Folder(s) added successfully.', data: {} } }

getFolders

await sdk.api.folders.getFolders({
  organizationId: 'org-123',
  folderId: 'folder-1',
  maxDepth: 3,
});
Response
{
  result: {
    status: 'success',
    message: 'Folders retrieved successfully.',
    data: [
      {
        folderId: 'folder-1',
        folderName: 'Folder 1',
        organizationId: 'org-123',
        parentFolderId: 'root',
        createdAt: 1738695615706,
        lastUpdated: 1738696287859
      }
    ]
  }
}

updateFolder

await sdk.api.folders.updateFolder({
  organizationId: 'org-123',
  folders: [{ folderId: 'folder-1', folderName: 'Renamed' }],
});
Response
{ result: { status: 'success', message: 'Folder(s) updated successfully.', data: {} } }

deleteFolder

await sdk.api.folders.deleteFolder({ organizationId: 'org-123', folderId: 'folder-1' });
Response
{ result: { status: 'success', message: 'Folder deleted successfully.', data: {} } }

updateFolderAccess

await sdk.api.folders.updateFolderAccess({
  organizationId: 'org-123',
  folderIds: ['folder-1'],
  accessType: 'restricted',
});
Response
{ result: { status: 'success', message: 'Folder access updated successfully.', data: {} } }

Documents

Namespace: sdk.api.documents

addDocuments

await sdk.api.documents.addDocuments({
  organizationId: 'org-123',
  documents: [
    { documentId: 'doc-1', documentName: 'My Document' },
    { documentId: 'doc-2', documentName: 'Another Document' },
  ],
  createOrganization: true,
  folderId: 'folder-1',
  createFolder: true,
});
Response
{
  result: {
    status: 'success',
    message: 'Document(s) added successfully.',
    data: {
      'doc-1': { success: true, message: 'Added Successfully' },
      'doc-2': { success: true, message: 'Added Successfully' }
    }
  }
}

getDocuments

await sdk.api.documents.getDocuments({
  organizationId: 'org-123',
  documentIds: ['doc-1'],
  folderId: 'folder-1',
  pageSize: 10,
});
Response
{
  result: {
    status: 'success',
    message: 'Document(s) retrieved successfully.',
    data: [
      { documentName: 'yourDocumentName', disabled: false, accessType: 'public', id: 'yourDocumentId' }
    ],
    pageToken: 'nextPageToken'
  }
}

updateDocuments

await sdk.api.documents.updateDocuments({
  organizationId: 'org-123',
  documents: [{ documentId: 'doc-1', documentName: 'Renamed' }],
});
Response
{ result: { status: 'success', message: 'Document(s) updated successfully.', data: {} } }

deleteDocuments

await sdk.api.documents.deleteDocuments({
  organizationId: 'org-123',
  documentIds: ['doc-1', 'doc-2'],
});
Response
{ result: { status: 'success', message: 'Document(s) deleted successfully.', data: {} } }

moveDocuments

await sdk.api.documents.moveDocuments({
  organizationId: 'org-123',
  documentIds: ['doc-1', 'doc-2'],
  folderId: 'target-folder-id',
});
Response
{ result: { status: 'success', message: 'Document(s) moved successfully.', data: {} } }

updateDocumentAccess

await sdk.api.documents.updateDocumentAccess({
  organizationId: 'org-123',
  documentIds: ['doc-1', 'doc-2'],
  accessType: 'organizationPrivate',
});
Response
{ result: { status: 'success', message: 'Document access updated successfully.', data: {} } }

updateDocumentDisableState

await sdk.api.documents.updateDocumentDisableState({
  organizationId: 'org-123',
  documentIds: ['doc-1'],
  disabled: true,
});
Response
{ result: { status: 'success', message: 'Document(s) disable state updated.', data: {} } }

migrateDocuments

Note: migrateDocuments is asynchronous and returns a migrationId. Poll completion with migrateDocumentsStatus.
await sdk.api.documents.migrateDocuments({
  organizationId: 'org-123',
  documentId: 'old-doc-id',
  newDocumentId: 'new-doc-id',
});
Response
{
  result: {
    status: 'success',
    message: 'Document migration started successfully.',
    data: { migrationId: 'yourMigrationId' }
  }
}

migrateDocumentsStatus

await sdk.api.documents.migrateDocumentsStatus({
  organizationId: 'org-123',
  migrationId: 'migration-1',
});
Response
{
  result: {
    status: 'success',
    message: 'Migration status retrieved successfully.',
    data: { migrationId: 'yourMigrationId', status: 'completed' }
  }
}

Users

Namespace: sdk.api.users

addUsers

await sdk.api.users.addUsers({
  organizationId: 'org-123',
  users: [{ userId: 'user-1', name: 'John Doe', email: 'john@example.com', accessRole: 'editor' }],
  createOrganization: true,
});
Response
{ result: { status: 'success', message: 'User(s) added successfully.', data: {} } }

getUsers

await sdk.api.users.getUsers({
  organizationId: 'org-123',
  userIds: ['user-1'],
  documentId: 'doc-1',
  pageSize: 100,
  allDocuments: true,
  groupByDocumentId: true,
});
Response
{
  result: {
    status: 'success',
    message: 'User(s) retrieved successfully.',
    data: [
      { email: 'userEmail@domain.com', name: 'userName', userId: 'yourUserId' }
    ],
    nextPageToken: 'pageToken'
  }
}

updateUsers

await sdk.api.users.updateUsers({
  organizationId: 'org-123',
  users: [{ userId: 'user-1', name: 'Jane Doe', accessRole: 'viewer' }],
});
Response
{ result: { status: 'success', message: 'User(s) updated successfully.', data: {} } }

deleteUsers

await sdk.api.users.deleteUsers({ organizationId: 'org-123', userIds: ['user-1'] });
Response
{ result: { status: 'success', message: 'User(s) deleted successfully.', data: {} } }

User Groups

Namespace: sdk.api.userGroups

addUserGroups

await sdk.api.userGroups.addUserGroups({
  organizationId: 'org-123',
  organizationUserGroups: [{ groupId: 'engineering', groupName: 'Engineering' }],
  createOrganization: true,
});
Response
{ result: { status: 'success', message: 'User group(s) added successfully.', data: {} } }

addUsersToGroup

await sdk.api.userGroups.addUsersToGroup({
  organizationId: 'org-123',
  organizationUserGroupId: 'engineering',
  userIds: ['user-1', 'user-2'],
});
Response
{ result: { status: 'success', message: 'Users added to group successfully.', data: {} } }

deleteUsersFromGroup

await sdk.api.userGroups.deleteUsersFromGroup({
  organizationId: 'org-123',
  organizationUserGroupId: 'engineering',
  userIds: ['user-1'],
});
Response
{ result: { status: 'success', message: 'Users removed from group successfully.', data: {} } }

Notifications

Namespace: sdk.api.notifications

addNotifications

await sdk.api.notifications.addNotifications({
  organizationId: 'org-123',
  documentId: 'doc-1',
  actionUser: { userId: 'user-1', name: 'John Doe', email: 'john@example.com' },
  displayHeadlineMessageTemplate: '{actionUser} commented on your document',
  displayBodyMessage: 'Check out the new comment',
  notifyUsers: [{ userId: 'user-2', name: 'Jane Doe' }],
  createOrganization: true,
  createDocument: true,
});
Response
{ result: { status: 'success', message: 'Notification(s) added successfully.', data: {} } }

getNotifications

await sdk.api.notifications.getNotifications({
  organizationId: 'org-123',
  userId: 'user-2',
  pageSize: 10,
  order: 'desc',
});
Response
{
  result: {
    status: 'success',
    message: 'Notification(s) retrieved successfully.',
    data: [
      {
        id: 'notificationId',
        notificationSource: 'custom',
        actionUser: { userId: 'user-1', name: 'John Doe', email: 'john@example.com' },
        displayBodyMessage: 'Check out the new comment',
        displayHeadlineMessageTemplate: '{actionUser} commented on your document',
        timestamp: 1722409519944
      }
    ],
    pageToken: 'nextPageToken'
  }
}

updateNotifications

await sdk.api.notifications.updateNotifications({
  organizationId: 'org-123',
  userId: 'user-2',
  notifications: [{ notificationId: 'n-1', read: true }],
});
Response
{ result: { status: 'success', message: 'Notification(s) updated successfully.', data: {} } }

deleteNotifications

await sdk.api.notifications.deleteNotifications({
  organizationId: 'org-123',
  userId: 'user-2',
  notificationIds: ['n-1'],
});
Response
{ result: { status: 'success', message: 'Notification(s) deleted successfully.', data: {} } }

getNotificationConfig

await sdk.api.notifications.getNotificationConfig({
  organizationId: 'org-123',
  userId: 'user-1',
});
Response
{
  result: {
    status: 'success',
    message: 'User config fetched successfully.',
    data: [
      {
        config: { inbox: 'ALL', email: 'ALL' },
        metadata: { organizationId: 'org-123', apiKey: 'API_KEY', documentId: 'doc-1', userId: 'user-1' }
      }
    ]
  }
}

setNotificationConfig

await sdk.api.notifications.setNotificationConfig({
  organizationId: 'org-123',
  userIds: ['user-1', 'user-2'],
  config: { inbox: 'ALL', email: 'MINE', slack: 'NONE' },
});
Response
{ result: { status: 'success', message: 'User config set successfully.', data: {} } }

Comment Annotations

Namespace: sdk.api.commentAnnotations

addCommentAnnotations

await sdk.api.commentAnnotations.addCommentAnnotations({
  organizationId: 'org-123',
  documentId: 'doc-1',
  commentAnnotations: [{
    location: { id: 'section-1', locationName: 'Introduction' },
    commentData: [{
      commentText: 'This needs review',
      commentHtml: '<p>This needs review</p>',
      from: { userId: 'user-1', name: 'John Doe', email: 'john@example.com' },
    }],
  }],
});
Response
{ result: { status: 'success', message: 'Annotation(s) added successfully.', data: {} } }

getCommentAnnotations

await sdk.api.commentAnnotations.getCommentAnnotations({
  organizationId: 'org-123',
  documentId: 'doc-1',
  statusIds: ['OPEN'],
  pageSize: 10,
});
Response
{
  result: {
    status: 'success',
    message: 'Annotations fetched successfully.',
    data: [
      {
        type: 'comment',
        comments: [
          {
            commentId: 123456,
            commentText: 'This is a sample comment text.',
            commentHtml: '<p>This is a sample comment text.</p>',
            from: { userId: 'user123', name: 'John Doe', email: 'john.doe@example.com' },
            createdAt: 1687344600000
          }
        ],
        status: { id: 'OPEN', name: 'Open', type: 'default' }
      }
    ]
  }
}

getCommentAnnotationsCount

await sdk.api.commentAnnotations.getCommentAnnotationsCount({
  organizationId: 'org-123',
  documentIds: ['doc-1', 'doc-2'],
  userId: 'user-1',
});
Response
{
  result: {
    status: 'success',
    message: 'Comment count retrieved successfully.',
    data: {
      'doc-1': { total: 4, unread: 2 },
      'doc-2': { total: 2, unread: 0 }
    }
  }
}

updateCommentAnnotations

await sdk.api.commentAnnotations.updateCommentAnnotations({
  organizationId: 'org-123',
  documentId: 'doc-1',
  annotationIds: ['annotation-id-1'],
  updatedData: { status: { id: 'RESOLVED', name: 'Resolved', type: 'terminal' } },
});
Response
{ result: { status: 'success', message: 'Annotation(s) updated successfully.', data: {} } }

deleteCommentAnnotations

await sdk.api.commentAnnotations.deleteCommentAnnotations({
  organizationId: 'org-123',
  documentId: 'doc-1',
  annotationIds: ['annotation-id-1'],
});
Response
{ result: { status: 'success', message: 'Annotation(s) deleted successfully.', data: {} } }

addComments

await sdk.api.commentAnnotations.addComments({
  organizationId: 'org-123',
  documentId: 'doc-1',
  annotationId: 'annotation-id-1',
  commentData: [{
    commentText: 'I agree, let me fix this',
    from: { userId: 'user-2', name: 'Jane Doe' },
  }],
});
Response
{ result: { status: 'success', message: 'Comment(s) added successfully.', data: {} } }

getComments

await sdk.api.commentAnnotations.getComments({
  organizationId: 'org-123',
  documentId: 'doc-1',
  annotationId: 'annotation-id-1',
  userIds: ['user-1'],
});
Response
{
  result: {
    status: 'success',
    message: 'Comments(s) retrieved successfully.',
    data: [
      {
        commentId: 153783,
        commentText: 'Sample Comment Text',
        commentHtml: '<div>Hello Updated 2</div>',
        from: { userId: 'yourUserId', name: 'User Name', email: 'user@example.com' },
        lastUpdated: '2024-06-20T09:53:42.258Z',
        status: 'added',
        type: 'text'
      }
    ]
  }
}

updateComments

await sdk.api.commentAnnotations.updateComments({
  organizationId: 'org-123',
  documentId: 'doc-1',
  annotationId: 'annotation-id-1',
  commentIds: [123456],
  updatedData: { commentText: 'Updated text', commentHtml: '<p>Updated text</p>' },
});
Response
{ result: { status: 'success', message: 'Comment(s) updated successfully.', data: {} } }

deleteComments

await sdk.api.commentAnnotations.deleteComments({
  organizationId: 'org-123',
  documentId: 'doc-1',
  annotationId: 'annotation-id-1',
  commentIds: [123456],
});
Response
{ result: { status: 'success', message: 'Comment(s) deleted successfully.', data: {} } }

Activities

Namespace: sdk.api.activities

addActivities

await sdk.api.activities.addActivities({
  organizationId: 'org-123',
  documentId: 'doc-456',
  activities: [{
    featureType: 'comment',
    actionType: 'comment.add',
    actionUser: { userId: 'user-1', name: 'John Doe', email: 'john@example.com' },
    displayMessageTemplate: '{{user}} added a comment',
  }],
});
Response
{ result: { status: 'success', message: 'Activity(s) added successfully.', data: {} } }

getActivities

await sdk.api.activities.getActivities({
  organizationId: 'org-123',
  documentId: 'doc-456',
  featureTypes: ['comment'],
  order: 'desc',
  pageSize: 50,
});
Response
{
  result: {
    status: 'success',
    message: 'Activity(s) retrieved successfully.',
    data: [
      {
        id: 'activity-001',
        featureType: 'comment',
        actionType: 'comment.add',
        actionUser: { userId: 'user-1', email: 'user@example.com', name: 'User Name' },
        targetEntityId: 'annotation-789',
        displayMessageTemplate: '{{user}} added a comment',
        metadata: { apiKey: 'yourApiKey', documentId: 'doc-456', organizationId: 'org-123' },
        timestamp: 1722409519944
      }
    ],
    pageToken: 'nextPageToken'
  }
}

updateActivities

await sdk.api.activities.updateActivities({
  organizationId: 'org-123',
  activities: [{ id: 'activity-001', displayMessageTemplate: '{{user}} updated the comment' }],
});
Response
{ result: { status: 'success', message: 'Activity(s) updated successfully.', data: {} } }

deleteActivities

await sdk.api.activities.deleteActivities({
  organizationId: 'org-123',
  documentId: 'doc-456',
});
Response
{ result: { status: 'success', message: 'Activity(s) deleted successfully.', data: {} } }

Access Control

Namespace: sdk.api.accessControl

addPermissions

await sdk.api.accessControl.addPermissions({
  user: { userId: 'user-1' },
  permissions: {
    resources: [
      { type: 'organization', id: 'org-123', accessRole: 'editor' },
      { type: 'document', id: 'doc-1', organizationId: 'org-123', accessRole: 'viewer', expiresAt: 1728902400 },
    ],
  },
});
Response
{ result: { status: 'success', message: 'Permissions added successfully.', data: {} } }

getPermissions

await sdk.api.accessControl.getPermissions({
  organizationId: 'org-123',
  userIds: ['user-1'],
  documentIds: ['doc-1'],
});
Response
{
  result: {
    status: 'success',
    message: 'User permissions retrieved successfully.',
    data: {
      'user-1': {
        documents: { 'doc-1': { accessRole: 'viewer', accessType: 'restricted' } },
        organization: { 'org-123': { accessRole: 'editor' } }
      }
    }
  }
}

removePermissions

await sdk.api.accessControl.removePermissions({
  userId: 'user-1',
  permissions: {
    resources: [
      { type: 'organization', id: 'org-123' },
      { type: 'document', id: 'doc-1', organizationId: 'org-123' },
    ],
  },
});
Response
{ result: { status: 'success', message: 'Permissions removed successfully.', data: {} } }

generateSignature

await sdk.api.accessControl.generateSignature({
  permissions: [{
    userId: 'user-1',
    resourceId: 'doc-1',
    type: 'document',
    hasAccess: true,
    accessRole: 'viewer',
  }],
});
Response
{
  result: {
    status: 'success',
    message: 'Signature generated successfully.',
    data: { signature: 'a1b2c3d4e5f6...' }
  }
}

generateToken

await sdk.api.accessControl.generateToken({
  userId: 'user-1',
  userProperties: { name: 'John Doe', email: 'john@example.com', isAdmin: false },
  permissions: {
    resources: [
      { type: 'organization', id: 'org-123', accessRole: 'viewer' },
      { type: 'document', id: 'doc-1', organizationId: 'org-123', accessRole: 'editor' },
    ],
  },
});
Response
{
  result: {
    status: 'success',
    message: 'Token generated successfully.',
    data: { token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' }
  }
}

CRDT

Namespace: sdk.api.crdt Supports text, map, array, and xml CRDT data types.

addCrdtData

await sdk.api.crdt.addCrdtData({
  organizationId: 'org-123',
  documentId: 'doc-1',
  editorId: 'my-collab-note',
  data: 'Hello, collaborative world!',
  type: 'text',
});
Response
{ result: { status: 'success', message: 'CRDT data added successfully.', data: {} } }

getCrdtData

await sdk.api.crdt.getCrdtData({
  organizationId: 'org-123',
  documentId: 'doc-1',
  editorId: 'my-collab-note',
});
Response
{
  result: {
    status: 'success',
    message: 'CRDT data retrieved successfully.',
    data: [
      {
        data: 'Hello, collaborative world!',
        id: 'my-collab-note',
        lastUpdate: '2025-01-20T10:30:00.000Z',
        lastUpdatedBy: 'user-123',
        sessionId: 'session-abc-456'
      }
    ]
  }
}

updateCrdtData

await sdk.api.crdt.updateCrdtData({
  organizationId: 'org-123',
  documentId: 'doc-1',
  editorId: 'my-collab-note',
  data: 'Updated collaborative content!',
  type: 'text',
});
Response
{ result: { status: 'success', message: 'CRDT data updated successfully.', data: {} } }

Presence

Namespace: sdk.api.presence

addPresence

await sdk.api.presence.addPresence({
  organizationId: 'org-123',
  documentId: 'doc-456',
  users: [
    { userId: 'user-1', name: 'John Doe', email: 'john@example.com', status: 'online' },
    { userId: 'user-2', name: 'Jane Doe', status: 'away' },
  ],
});
Response
{ result: { status: 'success', message: 'Presence added successfully.', data: {} } }

updatePresence

await sdk.api.presence.updatePresence({
  organizationId: 'org-123',
  documentId: 'doc-456',
  users: [{ userId: 'user-1', status: 'away' }],
});
Response
{ result: { status: 'success', message: 'Presence updated successfully.', data: {} } }

deletePresence

await sdk.api.presence.deletePresence({
  organizationId: 'org-123',
  documentId: 'doc-456',
  userIds: ['user-1', 'user-2'],
});
Response
{ result: { status: 'success', message: 'Presence removed successfully.', data: {} } }

Livestate

Namespace: sdk.api.livestate

broadcastEvent

await sdk.api.livestate.broadcastEvent({
  organizationId: 'org-123',
  documentId: 'doc-1',
  liveStateDataId: 'my-live-state',
  data: { status: 'active', message: 'Hello World' },
  merge: true,
});
Response
{ result: { status: 'success', message: 'Event broadcast successfully.', data: {} } }

Recordings

Namespace: sdk.api.recordings

getRecordings

await sdk.api.recordings.getRecordings({
  organizationId: 'org-123',
  documentId: 'doc-456',
  recordingIds: ['rec-1'],
  pageSize: 10,
  pageToken: 'next-page-token',
});
Response
{
  result: {
    status: 'success',
    message: 'Recorder annotations retrieved successfully.',
    data: [
      {
        type: 'recorder',
        recordingType: 'screen',
        mode: 'floating',
        metadata: { apiKey: 'YOUR_API_KEY', documentId: 'doc-456', organizationId: 'org-123' },
        recordedTime: { duration: 4204.55, display: '00:00:04' },
        displayName: 'Screen Recording 1773814490242.mp4',
        annotationId: 'ypvmVTROaNU1qP4kq7Cc',
        attachments: [{
          attachmentId: 875113,
          url: 'https://storage.googleapis.com/...',
          mimeType: 'video/mp4',
          name: 'recording_1773814490242.mp4',
          type: 'mp4',
          size: 103551
        }],
        latestVersion: 5
      }
    ],
    pageToken: 'nextPageToken'
  }
}

Rewriter

Namespace: sdk.api.rewriter Supports OpenAI, Anthropic, and Gemini models.

askAi

Note: askAi may take several seconds to respond. The SDK does not enforce a client-side timeout.
await sdk.api.rewriter.askAi({
  model: 'gpt-4o',
  prompt: 'Fix the grammar and spelling in the following text.',
  text: 'Their going to the store to by some apples.',
});
Response
{
  result: {
    success: true,
    text: 'The rewritten or processed text returned by the model.'
  }
}

GDPR

Namespace: sdk.api.gdpr

deleteAllUserData

Note: deleteAllUserData is asynchronous and returns a job ID. Poll completion with getDeleteUserDataStatus.
await sdk.api.gdpr.deleteAllUserData({
  userIds: ['user-1', 'user-2'],
  organizationIds: ['org-123'],
});
Response
{
  result: {
    status: 'success',
    message: 'User data deletion job queued.',
    data: { jobId: 'delete-job-id' }
  }
}

getAllUserData

await sdk.api.gdpr.getAllUserData({
  organizationId: 'org-123',
  userId: 'user-1',
  pageToken: 'next-page-token',
});
Response
{
  result: {
    status: 'success',
    message: 'Data fetched successfully.',
    data: {
      comments: [/* up to 100 items */],
      reactions: [/* up to 100 items */],
      recordings: [/* up to 100 items */],
      notifications: [/* up to 100 items */]
    },
    nextPageToken: 'bhdwdqwjs298e39e479ddkeuw==329'
  }
}

getDeleteUserDataStatus

await sdk.api.gdpr.getDeleteUserDataStatus({ jobId: 'job-id-from-delete-call' });
Response
{
  result: {
    status: 'success',
    message: 'Data fetched successfully.',
    data: {
      isDeleteCompleted: true,
      tasksLeft: 0,
      lastTaskCompletedTime: 1748972106739
    }
  }
}

Workspace

Namespace: sdk.api.workspace

createWorkspace

await sdk.api.workspace.createWorkspace({
  ownerEmail: 'owner@example.com',
  workspaceName: 'My Workspace',
  name: 'John Doe',
});
Response
{ result: { status: 'success', message: 'Workspace created successfully.', data: {} } }

getWorkspace

  • Retrieves details for the current workspace.
  • Params: empty object {}
  • Returns: GetWorkspaceResponse
await sdk.api.workspace.getWorkspace({});
Response
{
  result: {
    status: 'success',
    message: 'Workspace retrieved successfully.',
    data: {
      id: 'workspace_abc123',
      name: 'My Workspace',
      owner: { email: 'owner@example.com', id: 'owner_id_123', name: 'John Doe', avatar: '' },
      authToken: 'eyJhbGciOiJSUzI1NiIs...',
      apiKeyList: {
        velt_api_key_1: { apiKeyName: 'John Doe Test API Key', id: 'velt_api_key_1', type: 'testing' }
      }
    }
  }
}

createApiKey

await sdk.api.workspace.createApiKey({
  ownerEmail: 'owner@example.com',
  type: 'production',
  createAuthToken: true,
  apiKeyName: 'Production Key',
  allowedDomains: ['example.com', '*.example.com'],
});
Response
{
  result: {
    status: 'success',
    message: 'API key created successfully.',
    data: { apiKey: 'velt_api_key_2', authToken: 'eyJhbGciOi...' }
  }
}

updateApiKey

await sdk.api.workspace.updateApiKey({ apiKey: 'velt_api_key_1', apiKeyName: 'Renamed Key' });
Response
{ result: { status: 'success', message: 'API key updated successfully.', data: {} } }

getApiKeys

await sdk.api.workspace.getApiKeys({ pageSize: 50, pageToken: 'next-page-token' });
Response
{
  result: {
    status: 'success',
    message: 'API keys retrieved successfully.',
    data: [
      { id: 'velt_api_key_1', apiKeyName: 'Production Key', type: 'production' },
      { id: 'velt_api_key_2', apiKeyName: 'Testing Key', type: 'testing' }
    ],
    nextPageToken: 'eyJsYXN0SWQiOiJ2ZWx0X2FwaV9rZXlfMiJ9'
  }
}

getApiKeyMetadata

await sdk.api.workspace.getApiKeyMetadata({});
Response
{
  result: {
    status: 'success',
    message: 'API key metadata retrieved successfully.',
    data: {
      defaultDocumentAccessType: 'public',
      planInfo: { type: 'sdk test' },
      ownerEmail: 'owner@example.com'
    }
  }
}

resetAuthToken

await sdk.api.workspace.resetAuthToken({ apiKey: 'velt_api_key_1' });
Response
{
  result: {
    status: 'success',
    message: 'Auth token reset successfully.',
    data: { authToken: 'eyJhbGciOi...' }
  }
}

getAuthTokens

await sdk.api.workspace.getAuthTokens({ apiKey: 'velt_api_key_1' });
Response
{
  result: {
    status: 'success',
    message: 'Auth tokens retrieved successfully.',
    data: {
      apiKey: 'velt_api_key_1',
      authTokens: [
        { token: 'eyJhbGciOiJSUzI1NiIs...', name: 'Default Auth Token', domains: [] }
      ]
    }
  }
}

addDomains

await sdk.api.workspace.addDomains({ domains: ['example.com', '*.firebase.com'] });
Response
{ result: { status: 'success', message: 'Domains added successfully.', data: {} } }

deleteDomains

await sdk.api.workspace.deleteDomains({ domains: ['example.com'] });
Response
{ result: { status: 'success', message: 'Domains deleted successfully.', data: {} } }

getDomains

await sdk.api.workspace.getDomains({});
Response
{
  result: {
    status: 'success',
    message: 'Allowed domains retrieved successfully.',
    data: { allowedDomains: ['localhost', '127.0.0.1', 'example.com'] }
  }
}

getEmailStatus

await sdk.api.workspace.getEmailStatus({ ownerEmail: 'owner@example.com' });
Response
{
  result: {
    status: 'success',
    message: 'Email verified and workspace reactivated',
    data: { verified: true }
  }
}
await sdk.api.workspace.sendLoginLink({
  email: 'user@example.com',
  continueUrl: 'https://app.example.com/dashboard',
});
Response
{ result: { status: 'success', message: 'Login link sent.', data: {} } }

getEmailConfig

await sdk.api.workspace.getEmailConfig({});
Response
{
  result: {
    status: 'success',
    message: 'Email configuration retrieved successfully.',
    data: {
      useEmailService: false,
      emailServiceConfig: { type: 'default', apiKey: '', fromEmail: '', fromCompany: '', commentTemplateId: '', tagTemplateId: '' }
    }
  }
}

updateEmailConfig

await sdk.api.workspace.updateEmailConfig({
  useEmailService: true,
  emailServiceConfig: { type: 'sendgrid', apiKey: 'sg-key', fromEmail: 'noreply@example.com' },
});
Response
{ result: { status: 'success', message: 'Email config updated successfully.', data: {} } }

getWebhookConfig

await sdk.api.workspace.getWebhookConfig({});
Response
{
  result: {
    status: 'success',
    message: 'Webhook configuration retrieved successfully.',
    data: {
      useWebhookService: false,
      webhookServiceConfig: { authToken: '', rawNotificationUrl: '', processedNotificationUrl: '' }
    }
  }
}

updateWebhookConfig

await sdk.api.workspace.updateWebhookConfig({
  useWebhookService: true,
  webhookServiceConfig: {
    authToken: 'webhook-secret',
    rawNotificationUrl: 'https://example.com/webhook/raw',
    processedNotificationUrl: 'https://example.com/webhook/processed',
  },
});
Response
{ result: { status: 'success', message: 'Webhook config updated successfully.', data: {} } }

Token

Namespace: sdk.api.token

getToken

  • Generates a Velt auth token for a user via REST.
  • Params: positional — organizationId (string), userId (string), email (string, optional), isAdmin (boolean, optional)
  • Returns: VeltApiResponse
Note: getToken takes positional arguments — not a request object.
await sdk.api.token.getToken('org-123', 'user-1', 'john@example.com', false);
Response
{
  result: {
    status: 'success',
    message: 'Token generated successfully.',
    data: { token: 'eyJhbGciOiJIUzI1NiIs...' }
  }
}

Error Handling

The SDK exports five typed error classes:
ClassExtendsWhen thrown
VeltSDKErrorErrorBase class for all SDK errors
VeltDatabaseErrorVeltSDKErrorMongoDB connection or query failures
VeltValidationErrorVeltSDKErrorMissing or invalid request parameters
VeltTokenErrorVeltSDKErrorToken generation failures
VeltApiErrorVeltSDKErrorREST API call failures
import { VeltSDK, VeltDatabaseError, VeltApiError } from '@veltdev/node';

try {
  const result = await sdk.api.organizations.getOrganizations({ organizationIds: ['org-123'] });
} catch (err) {
  if (err instanceof VeltApiError) {
    console.error('API call failed:', err.message);
  } else if (err instanceof VeltDatabaseError) {
    console.error('Database error:', err.message);
  } else {
    throw err;
  }
}
Common self-hosting error codes returned in the response errorCode field:
  • INVALID_INPUT — Request data is malformed or missing required fields
  • INTERNAL_ERROR — Server-side error during processing
  • NOT_FOUND — Requested resource was not found

Distribution

The package ships both CommonJS (CJS) and ES Module (ESM) bundles with rolled-up .d.ts type definitions, making it compatible with all modern Node.js project setups.
// ESM
import { VeltSDK } from '@veltdev/node';

// CommonJS
const { VeltSDK } = require('@veltdev/node');