Skip to main content

Python SDK for integrating Velt comments, reactions, attachments, and user management into Django applications

Project description

Velt Python SDK

A Python SDK for integrating Velt collaboration features into Python applications. Supports two backends:

  • Self-Hosting (sdk.selfHosting.*) — Direct MongoDB access for self-hosted Velt installations
  • REST API (sdk.api.*) — Wrappers around Velt's REST APIs at api.velt.dev

Installation

pip install velt-py

Requirements

  • Python 3.8+
  • Django 4.2.26+
  • MongoDB (Percona Server or MongoDB Atlas)
  • PyMongo 4.6.3
  • MongoEngine 0.27.0

Quick Start

1. Initialize the SDK

from velt_py import VeltSDK

# Initialize SDK with your MongoDB configuration
sdk = VeltSDK.initialize(config={
    'database': {
        'host': 'localhost:27017',
        'username': 'your-username',
        'password': 'your-password',
        'auth_database': 'admin',
        'database_name': 'velt-integration'  # Your database name
    },
    'apiKey': 'your-velt-api-key',  # Optional: can use VELT_API_KEY env var
    'authToken': 'your-velt-auth-token'  # Optional: can use VELT_AUTH_TOKEN env var
})

2. Use Services

The SDK supports different backends. For self-hosted installations, use the selfHosting backend:

# Comments
result = sdk.selfHosting.comments.getComments(
    organizationId='org-123',
    commentAnnotationIds=['ann-1', 'ann-2'],
    documentIds=['doc-1']
)

sdk.selfHosting.comments.saveComments(
    organizationId='org-123',
    commentAnnotation={
        'ann-1': {
            'comments': {'comment-1': {'commentId': 'comment-1', 'commentText': 'Hello'}},
            'metadata': {}
        }
    },
    documentId='doc-1'
)

sdk.selfHosting.comments.deleteComment(
    organizationId='org-123',
    commentAnnotationId='ann-1'
)

# Reactions
result = sdk.selfHosting.reactions.getReactions(
    organizationId='org-123',
    reactionAnnotationIds=['reaction-1'],
    documentIds=['doc-1']
)

sdk.selfHosting.reactions.saveReactions(
    organizationId='org-123',
    reactionAnnotation={
        'reaction-1': {
            'icon': '👍',
            'metadata': {}
        }
    },
    documentId='doc-1'
)

# Attachments
result = sdk.selfHosting.attachments.getAttachment(
    organizationId='org-123',
    attachmentId=12345
)

sdk.selfHosting.attachments.saveAttachment(
    organizationId='org-123',
    attachment={
        'attachmentId': 12345,
        'name': 'document.pdf',
        'mimeType': 'application/pdf',
        'base64Data': '...',
        'size': 1024
    },
    documentId='doc-1'
)

# Users
result = sdk.selfHosting.users.getUsers(
    organizationId='org-123',
    userIds=['user-1', 'user-2']
)

sdk.selfHosting.users.saveUser(
    organizationId='org-123',
    user={
        'userId': 'user-1',
        'name': 'John Doe',
        'email': 'john@example.com',
        'photoUrl': 'https://example.com/photo.jpg'
    }
)

# Token
result = sdk.selfHosting.token.getToken(
    organizationId='org-123',
    userId='user-1',
    email='john@example.com',
    isAdmin=False
)
token = result['data']['token']

3. REST API Services

For calling Velt's REST APIs (no self-hosted database needed), use the api backend. Each method takes a typed request object:

from velt_py.models.organization import (
    AddOrganizationsRequest,
    GetOrganizationsRequest,
    UpdateOrganizationsRequest,
    DeleteOrganizationsRequest,
    UpdateOrganizationDisableStateRequest
)
from velt_py.models.folder import (
    AddFolderRequest,
    GetFoldersRequest,
    UpdateFolderRequest,
    DeleteFolderRequest,
    UpdateFolderAccessRequest
)
from velt_py.models.notification_api import (
    AddNotificationsRequest,
    GetNotificationsRequest,
    SetNotificationConfigRequest
)
from velt_py.models.user_api import (
    AddUsersRequest,
    GetUsersRequest,
    UpdateUsersRequest,
    DeleteUsersRequest
)
from velt_py.models.user_group import (
    AddUserGroupsRequest,
    AddUsersToGroupRequest,
    DeleteUsersFromGroupRequest
)
from velt_py.models.document import (
    AddDocumentsRequest,
    GetDocumentsRequest,
    UpdateDocumentsRequest
)
from velt_py.models.activity_api import (
    AddActivitiesRequest,
    GetActivitiesRequest,
    UpdateActivitiesRequest,
    DeleteActivitiesRequest
)
from velt_py.models.comment_annotation_api import (
    AddCommentAnnotationsRequest,
    GetCommentAnnotationsRequest,
    GetCommentAnnotationsCountRequest,
    UpdateCommentAnnotationsRequest,
    DeleteCommentAnnotationsRequest,
    AddCommentsRequest,
    GetCommentsRequest,
    UpdateCommentsRequest,
    DeleteCommentsRequest
)
from velt_py.models.crdt import (
    AddCrdtDataRequest,
    GetCrdtDataRequest,
    UpdateCrdtDataRequest
)
from velt_py.models.gdpr import (
    DeleteAllUserDataRequest,
    GetAllUserDataRequest,
    GetDeleteUserDataStatusRequest
)
from velt_py.models.access_control import (
    AddPermissionsRequest,
    GetPermissionsRequest,
    RemovePermissionsRequest,
    GenerateSignatureRequest,
    GenerateTokenRequest
)
from velt_py.models.presence import (
    AddPresenceRequest,
    UpdatePresenceRequest,
    DeletePresenceRequest
)
from velt_py.models.livestate import (
    BroadcastEventRequest
)
from velt_py.models.recording import (
    GetRecordingsRequest
)
from velt_py.models.rewriter import (
    AskAiRequest
)
from velt_py.models.workspace import (
    CreateWorkspaceRequest,
    GetWorkspaceRequest,
    CreateApiKeyRequest,
    UpdateApiKeyRequest,
    GetApiKeysRequest,
    GetApiKeyMetadataRequest,
    ResetAuthTokenRequest,
    GetAuthTokensRequest,
    AddDomainsRequest,
    DeleteDomainsRequest,
    GetDomainsRequest,
    GetEmailStatusRequest,
    SendLoginLinkRequest,
    GetEmailConfigRequest,
    UpdateEmailConfigRequest,
    GetWebhookConfigRequest,
    UpdateWebhookConfigRequest
)

# Organizations — Add
result = sdk.api.organizations.addOrganizations(
    AddOrganizationsRequest(
        organizations=[{'organizationId': 'org-123', 'organizationName': 'My Organization'}]
    )
)

# Organizations — Get (with optional filters and pagination)
result = sdk.api.organizations.getOrganizations(
    GetOrganizationsRequest(
        organizationIds=['org-123'],  # optional, omit to get all
        pageSize=10,                  # optional
        pageToken='next-page-token'   # optional
    )
)

# Organizations — Update
result = sdk.api.organizations.updateOrganizations(
    UpdateOrganizationsRequest(
        organizations=[{'organizationId': 'org-123', 'organizationName': 'Updated Name'}]
    )
)

# Organizations — Delete
result = sdk.api.organizations.deleteOrganizations(
    DeleteOrganizationsRequest(organizationIds=['org-123', 'org-456'])
)

# Organizations — Disable/Enable access
result = sdk.api.organizations.updateOrganizationDisableState(
    UpdateOrganizationDisableStateRequest(organizationIds=['org-123'], disabled=True)
)

# Notifications — Add
result = sdk.api.notifications.addNotifications(
    AddNotificationsRequest(
        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,   # optional
        createDocument=True         # optional
    )
)

# Notifications — Get (with filters and pagination)
result = sdk.api.notifications.getNotifications(
    GetNotificationsRequest(
        organizationId='org-123',
        userId='user-2',          # or documentId
        pageSize=10,              # optional
        order='desc'              # optional: asc or desc
    )
)

# Notifications — Set config (notification preferences)
result = sdk.api.notifications.setNotificationConfig(
    SetNotificationConfigRequest(
        organizationId='org-123',
        userIds=['user-1', 'user-2'],
        config={'inbox': 'ALL', 'email': 'MINE', 'slack': 'NONE'}
    )
)

# Users — Add to organization
result = sdk.api.users.addUsers(
    AddUsersRequest(
        organizationId='org-123',
        users=[{'userId': 'user-1', 'name': 'John Doe', 'email': 'john@example.com', 'accessRole': 'editor'}],
        createOrganization=True  # optional: creates org if it doesn't exist
    )
)

# Users — Get by organization (with optional filters and pagination)
result = sdk.api.users.getUsers(
    GetUsersRequest(
        organizationId='org-123',
        userIds=['user-1'],         # optional
        documentId='doc-1',         # optional
        pageSize=100,               # optional
        allDocuments=True,          # optional: get all document-level users
        groupByDocumentId=True      # optional: group results by document
    )
)

# Users — Update metadata
result = sdk.api.users.updateUsers(
    UpdateUsersRequest(
        organizationId='org-123',
        users=[{'userId': 'user-1', 'name': 'Jane Doe', 'accessRole': 'viewer'}]
    )
)

# Users — Delete from organization
result = sdk.api.users.deleteUsers(
    DeleteUsersRequest(
        organizationId='org-123',
        userIds=['user-1', 'user-2']
    )
)

# User Groups — Add groups
result = sdk.api.userGroups.addUserGroups(
    AddUserGroupsRequest(
        organizationId='org-123',
        organizationUserGroups=[{'groupId': 'engineering', 'groupName': 'Engineering'}],
        createOrganization=True  # optional
    )
)

# User Groups — Add users to a group
result = sdk.api.userGroups.addUsersToGroup(
    AddUsersToGroupRequest(
        organizationId='org-123',
        organizationUserGroupId='engineering',
        userIds=['user-1', 'user-2']
    )
)

# User Groups — Remove users from a group
result = sdk.api.userGroups.deleteUsersFromGroup(
    DeleteUsersFromGroupRequest(
        organizationId='org-123',
        organizationUserGroupId='engineering',
        userIds=['user-1'],    # specific users
        # deleteAll=True       # or remove all users from group
    )
)

# Documents — Add
result = sdk.api.documents.addDocuments(
    AddDocumentsRequest(
        organizationId='org-123',
        documents=[
            {'documentId': 'doc-1', 'documentName': 'My Document'},
            {'documentId': 'doc-2', 'documentName': 'Another Document'}
        ],
        createOrganization=True,  # optional: creates org if it doesn't exist
        folderId='folder-1',      # optional: add to a specific folder
        createFolder=True          # optional: creates folder if it doesn't exist
    )
)

# Documents — Get (with optional filters and pagination)
result = sdk.api.documents.getDocuments(
    GetDocumentsRequest(
        organizationId='org-123',
        documentIds=['doc-1'],    # optional
        folderId='folder-1',      # optional
        pageSize=10               # optional
    )
)

# Documents — Update
result = sdk.api.documents.updateDocuments(
    UpdateDocumentsRequest(
        organizationId='org-123',
        documents=[{'documentId': 'doc-1', 'documentName': 'Updated Name'}]
    )
)

# Documents — Delete
result = sdk.api.documents.deleteDocuments(
    DeleteDocumentsRequest(
        organizationId='org-123',
        documentIds=['doc-1', 'doc-2']
    )
)

# Documents — Move to a different folder
result = sdk.api.documents.moveDocuments(
    MoveDocumentsRequest(
        organizationId='org-123',
        documentIds=['doc-1', 'doc-2'],
        folderId='target-folder-id'
    )
)

# Documents — Update access type
result = sdk.api.documents.updateDocumentAccess(
    UpdateDocumentAccessRequest(
        organizationId='org-123',
        documentIds=['doc-1', 'doc-2'],
        accessType='organizationPrivate'  # 'organizationPrivate', 'restricted', or 'public'
    )
)

# Documents — Disable/enable access
result = sdk.api.documents.updateDocumentDisableState(
    UpdateDocumentDisableStateRequest(
        organizationId='org-123',
        documentIds=['doc-1'],
        disabled=True
    )
)

# Documents — Migrate to a new document ID
result = sdk.api.documents.migrateDocuments(
    MigrateDocumentsRequest(
        organizationId='org-123',
        documentId='old-doc-id',
        newDocumentId='new-doc-id'
    )
)

# Documents — Poll migration status
result = sdk.api.documents.migrateDocumentsStatus(
    MigrateDocumentsStatusRequest(
        organizationId='org-123',
        migrationId='migration-id-from-migrate-call'
    )
)

# Folders — Add
result = sdk.api.folders.addFolder(
    AddFolderRequest(
        organizationId='org-123',
        folders=[{'folderId': 'folder-1', 'folderName': 'My Folder'}],
        createOrganization=True  # optional
    )
)

# Folders — Get (with optional folderId and maxDepth)
result = sdk.api.folders.getFolders(
    GetFoldersRequest(organizationId='org-123', folderId='folder-1', maxDepth=3)
)

# Folders — Update
result = sdk.api.folders.updateFolder(
    UpdateFolderRequest(
        organizationId='org-123',
        folders=[{'folderId': 'folder-1', 'folderName': 'Renamed Folder'}]
    )
)

# Folders — Delete
result = sdk.api.folders.deleteFolder(
    DeleteFolderRequest(organizationId='org-123', folderId='folder-1')
)

# Folders — Update access type
result = sdk.api.folders.updateFolderAccess(
    UpdateFolderAccessRequest(
        organizationId='org-123',
        folderIds=['folder-1'],
        accessType='restricted'
    )
)

# Activities — Add activity logs
result = sdk.api.activities.addActivities(
    AddActivitiesRequest(
        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'
        }]
    )
)

# Activities — Get (with filters and pagination)
result = sdk.api.activities.getActivities(
    GetActivitiesRequest(
        organizationId='org-123',
        documentId='doc-456',
        featureTypes=['comment'],
        order='desc',
        pageSize=50
    )
)

# Activities — Update
result = sdk.api.activities.updateActivities(
    UpdateActivitiesRequest(
        organizationId='org-123',
        activities=[{
            'id': 'activity-001',
            'displayMessageTemplate': '{{user}} updated the comment'
        }]
    )
)

# Activities — Delete by document
result = sdk.api.activities.deleteActivities(
    DeleteActivitiesRequest(
        organizationId='org-123',
        documentId='doc-456'
    )
)

# Comment Annotations — Add
result = sdk.api.commentAnnotations.addCommentAnnotations(
    AddCommentAnnotationsRequest(
        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'}
            }]
        }]
    )
)

# Comment Annotations — Get (with filters and pagination)
result = sdk.api.commentAnnotations.getCommentAnnotations(
    GetCommentAnnotationsRequest(
        organizationId='org-123',
        documentId='doc-1',
        statusIds=['OPEN'],      # optional
        pageSize=10              # optional
    )
)

# Comment Annotations — Get count (total and unread per document)
result = sdk.api.commentAnnotations.getCommentAnnotationsCount(
    GetCommentAnnotationsCountRequest(
        organizationId='org-123',
        documentIds=['doc-1', 'doc-2'],
        userId='user-1'
    )
)

# Comment Annotations — Update (e.g., change status)
result = sdk.api.commentAnnotations.updateCommentAnnotations(
    UpdateCommentAnnotationsRequest(
        organizationId='org-123',
        documentId='doc-1',
        annotationIds=['annotation-id-1'],
        updatedData={'status': {'id': 'RESOLVED', 'name': 'Resolved', 'type': 'terminal'}}
    )
)

# Comment Annotations — Delete
result = sdk.api.commentAnnotations.deleteCommentAnnotations(
    DeleteCommentAnnotationsRequest(
        organizationId='org-123',
        documentId='doc-1',
        annotationIds=['annotation-id-1']
    )
)

# Comments — Add to an existing annotation
result = sdk.api.commentAnnotations.addComments(
    AddCommentsRequest(
        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'}
        }]
    )
)

# Comments — Get from an annotation
result = sdk.api.commentAnnotations.getComments(
    GetCommentsRequest(
        organizationId='org-123',
        documentId='doc-1',
        annotationId='annotation-id-1',
        userIds=['user-1']
    )
)

# Comments — Update
result = sdk.api.commentAnnotations.updateComments(
    UpdateCommentsRequest(
        organizationId='org-123',
        documentId='doc-1',
        annotationId='annotation-id-1',
        commentIds=[123456],
        updatedData={'commentText': 'Updated text', 'commentHtml': '<p>Updated text</p>'}
    )
)

# Comments — Delete
result = sdk.api.commentAnnotations.deleteComments(
    DeleteCommentsRequest(
        organizationId='org-123',
        documentId='doc-1',
        annotationId='annotation-id-1',
        commentIds=[123456]  # optional: omit to delete all
    )
)

# Access Control — Add permissions
result = sdk.api.accessControl.addPermissions(
    AddPermissionsRequest(
        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}
        ]}
    )
)

# Access Control — Get permissions
result = sdk.api.accessControl.getPermissions(
    GetPermissionsRequest(
        organizationId='org-123',
        userIds=['user-1'],
        documentIds=['doc-1']  # optional
    )
)

# Access Control — Remove permissions
result = sdk.api.accessControl.removePermissions(
    RemovePermissionsRequest(
        userId='user-1',
        permissions={'resources': [
            {'type': 'organization', 'id': 'org-123'},
            {'type': 'document', 'id': 'doc-1', 'organizationId': 'org-123'}
        ]}
    )
)

# Access Control — Generate signature for Permission Provider
result = sdk.api.accessControl.generateSignature(
    GenerateSignatureRequest(
        permissions=[{
            'userId': 'user-1',
            'resourceId': 'doc-1',
            'type': 'document',
            'hasAccess': True,
            'accessRole': 'viewer'
        }]
    )
)

# Access Control — Generate JWT token
result = sdk.api.accessControl.generateToken(
    GenerateTokenRequest(
        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'}
        ]}
    )
)

# CRDT — Add editor data (text, map, array, or xml)
result = sdk.api.crdt.addCrdtData(
    AddCrdtDataRequest(
        organizationId='org-123',
        documentId='doc-1',
        editorId='my-collab-note',
        data='Hello, collaborative world!',
        type='text'
    )
)

# CRDT — Get editor data (with optional editorId filter)
result = sdk.api.crdt.getCrdtData(
    GetCrdtDataRequest(
        organizationId='org-123',
        documentId='doc-1',
        editorId='my-collab-note'  # optional: omit to get all editors
    )
)

# CRDT — Update existing editor data
result = sdk.api.crdt.updateCrdtData(
    UpdateCrdtDataRequest(
        organizationId='org-123',
        documentId='doc-1',
        editorId='my-collab-note',
        data='Updated collaborative content!',
        type='text'
    )
)

# Presence — Add users to presence
result = sdk.api.presence.addPresence(
    AddPresenceRequest(
        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'}
        ]
    )
)

# Presence — Update user presence status
result = sdk.api.presence.updatePresence(
    UpdatePresenceRequest(
        organizationId='org-123',
        documentId='doc-456',
        users=[{'userId': 'user-1', 'status': 'away'}]
    )
)

# Presence — Remove users from presence
result = sdk.api.presence.deletePresence(
    DeletePresenceRequest(
        organizationId='org-123',
        documentId='doc-456',
        userIds=['user-1', 'user-2']
    )
)

# Livestate — Broadcast event
result = sdk.api.livestate.broadcastEvent(
    BroadcastEventRequest(
        organizationId='org-123',
        documentId='doc-1',
        liveStateDataId='my-live-state',
        data={'status': 'active', 'message': 'Hello World'},
        merge=True  # optional: merge with existing data instead of replacing
    )
)

# Recordings — Get recordings for an organization/document
result = sdk.api.recordings.getRecordings(
    GetRecordingsRequest(
        organizationId='org-123',
        documentId='doc-456',         # optional
        recordingIds=['rec-1'],       # optional: filter by specific IDs
        pageSize=10,                  # optional
        pageToken='next-page-token'   # optional
    )
)

# Rewriter — Ask AI to rewrite/process text
result = sdk.api.rewriter.askAi(
    AskAiRequest(
        model='gpt-4o',
        prompt='Fix the grammar and spelling in the following text.',
        text='Their going to the store to by some apples.'
    )
)

# GDPR — Delete all user data
result = sdk.api.gdpr.deleteAllUserData(
    DeleteAllUserDataRequest(
        userIds=['user-1', 'user-2'],
        organizationIds=['org-123']  # optional, speeds up deletion
    )
)

# GDPR — Get all user data (paginated)
result = sdk.api.gdpr.getAllUserData(
    GetAllUserDataRequest(
        organizationId='org-123',
        userId='user-1',
        pageToken='next-page-token'  # optional
    )
)

# GDPR — Get deletion job status
result = sdk.api.gdpr.getDeleteUserDataStatus(
    GetDeleteUserDataStatusRequest(jobId='job-id-from-delete-call')
)

# Workspace — Create a new workspace
result = sdk.api.workspace.createWorkspace(
    CreateWorkspaceRequest(
        ownerEmail='owner@example.com',
        workspaceName='My Workspace',
        name='John Doe'
    )
)

# Workspace — Get workspace details
result = sdk.api.workspace.getWorkspace(GetWorkspaceRequest())

# Workspace — Create an API key
result = sdk.api.workspace.createApiKey(
    CreateApiKeyRequest(
        ownerEmail='owner@example.com',
        type='production',
        createAuthToken=True,
        apiKeyName='Production Key',
        allowedDomains=['example.com', '*.example.com']
    )
)

# Workspace — Update an API key name
result = sdk.api.workspace.updateApiKey(
    UpdateApiKeyRequest(apiKey='velt_api_key_1', apiKeyName='Renamed Key')
)

# Workspace — Get API keys (with optional pagination)
result = sdk.api.workspace.getApiKeys(
    GetApiKeysRequest(pageSize=50, pageToken='next-page-token')
)

# Workspace — Get API key metadata
result = sdk.api.workspace.getApiKeyMetadata(GetApiKeyMetadataRequest())

# Workspace — Reset auth token for an API key
result = sdk.api.workspace.resetAuthToken(
    ResetAuthTokenRequest(apiKey='velt_api_key_1')
)

# Workspace — Get auth tokens for an API key
result = sdk.api.workspace.getAuthTokens(
    GetAuthTokensRequest(apiKey='velt_api_key_1')
)

# Workspace — Add allowed domains
result = sdk.api.workspace.addDomains(
    AddDomainsRequest(domains=['example.com', '*.firebase.com'])
)

# Workspace — Delete allowed domains
result = sdk.api.workspace.deleteDomains(
    DeleteDomainsRequest(domains=['example.com'])
)

# Workspace — Get allowed domains
result = sdk.api.workspace.getDomains(GetDomainsRequest())

# Workspace — Check email verification status
result = sdk.api.workspace.getEmailStatus(
    GetEmailStatusRequest(ownerEmail='owner@example.com')
)

# Workspace — Send login link
result = sdk.api.workspace.sendLoginLink(
    SendLoginLinkRequest(email='user@example.com', continueUrl='https://app.example.com/dashboard')
)

# Workspace — Get email configuration
result = sdk.api.workspace.getEmailConfig(GetEmailConfigRequest())

# Workspace — Update email configuration
result = sdk.api.workspace.updateEmailConfig(
    UpdateEmailConfigRequest(
        useEmailService=True,
        emailServiceConfig={'type': 'sendgrid', 'apiKey': 'sg-key', 'fromEmail': 'noreply@example.com'}
    )
)

# Workspace — Get webhook configuration
result = sdk.api.workspace.getWebhookConfig(GetWebhookConfigRequest())

# Workspace — Update webhook configuration
result = sdk.api.workspace.updateWebhookConfig(
    UpdateWebhookConfigRequest(
        useWebhookService=True,
        webhookServiceConfig={
            'authToken': 'webhook-secret',
            'rawNotificationUrl': 'https://example.com/webhook/raw',
            'processedNotificationUrl': 'https://example.com/webhook/processed'
        }
    )
)

# Success response (raw from Velt API):
# {
#     'result': {
#         'status': 'success',
#         'message': 'Organization(s) added successfully.',
#         'data': {
#             'org-123': {
#                 'success': True,
#                 'id': '02cf91e5...',
#                 'message': 'Added Successfully'
#             }
#         }
#     }
# }

# Error response (raw from Velt API):
# {
#     'error': {
#         'message': 'Error adding organization(s).',
#         'status': 'INTERNAL',
#         'details': {
#             'org-123': {
#                 'success': False,
#                 'message': 'Organization already exists.'
#             }
#         }
#     }
# }

Note: REST API service methods return the raw Velt API response as-is, preserving all fields. There is no local validation — the Velt API handles all validation server-side.

Response Format

Self-Hosting Services

Self-hosting service methods return a standardized response format:

Success Response

{
    'success': True,
    'data': {
        # Service-specific data
    }
}

Error Response

{
    'success': False,
    'error': 'Human-readable error message',
    'errorCode': 'ERROR_CODE'  # Optional
}

Data Isolation

All methods require organizationId as the first parameter to ensure data isolation between organizations. The SDK automatically filters all queries by organizationId.

API Reference

REST API Services (sdk.api.*)

OrganizationService (sdk.api.organizations)

  • addOrganizations(request: AddOrganizationsRequest) - Add one or more organizations.
  • getOrganizations(request: GetOrganizationsRequest) - Get organizations. Optionally filter by IDs with pagination.
  • updateOrganizations(request: UpdateOrganizationsRequest) - Update one or more organizations.
  • deleteOrganizations(request: DeleteOrganizationsRequest) - Delete organizations by ID list.
  • updateOrganizationDisableState(request: UpdateOrganizationDisableStateRequest) - Enable or disable access.

DocumentService (sdk.api.documents)

  • addDocuments(request: AddDocumentsRequest) - Add documents to an organization.
  • getDocuments(request: GetDocumentsRequest) - Get documents. Optionally filter by IDs, folder, with pagination.
  • updateDocuments(request: UpdateDocumentsRequest) - Update document metadata.
  • deleteDocuments(request: DeleteDocumentsRequest) - Delete documents by ID list.
  • moveDocuments(request: MoveDocumentsRequest) - Move documents to a different folder.
  • updateDocumentAccess(request: UpdateDocumentAccessRequest) - Update access type for documents.
  • updateDocumentDisableState(request: UpdateDocumentDisableStateRequest) - Enable or disable document access.
  • migrateDocuments(request: MigrateDocumentsRequest) - Migrate a document to a new document ID.
  • migrateDocumentsStatus(request: MigrateDocumentsStatusRequest) - Poll migration status.

UserService (sdk.api.users)

  • addUsers(request: AddUsersRequest) - Add users to an organization, document, or folder.
  • getUsers(request: GetUsersRequest) - Get users with optional filters (document, folder, user IDs, groups) and pagination.
  • updateUsers(request: UpdateUsersRequest) - Update user metadata in an organization, document, or folder.
  • deleteUsers(request: DeleteUsersRequest) - Remove users from an organization, document, or folder.

NotificationApiService (sdk.api.notifications)

  • addNotifications(request: AddNotificationsRequest) - Add notifications to users.
  • getNotifications(request: GetNotificationsRequest) - Get notifications with optional filters and pagination.
  • updateNotifications(request: UpdateNotificationsRequest) - Update existing notifications.
  • deleteNotifications(request: DeleteNotificationsRequest) - Delete notifications.
  • getNotificationConfig(request: GetNotificationConfigRequest) - Get notification preferences for a user.
  • setNotificationConfig(request: SetNotificationConfigRequest) - Set notification preferences for users.

UserGroupService (sdk.api.userGroups)

  • addUserGroups(request: AddUserGroupsRequest) - Add organization user groups.
  • addUsersToGroup(request: AddUsersToGroupRequest) - Add users to a specific user group.
  • deleteUsersFromGroup(request: DeleteUsersFromGroupRequest) - Remove users from a user group (specific users or all).

CommentAnnotationApiService (sdk.api.commentAnnotations)

  • addCommentAnnotations(request: AddCommentAnnotationsRequest) - Add comment annotations to a document.
  • getCommentAnnotations(request: GetCommentAnnotationsRequest) - Get comment annotations with optional filters (location, user, status, timestamps) and pagination.
  • getCommentAnnotationsCount(request: GetCommentAnnotationsCountRequest) - Get total and unread comment annotation counts per document.
  • updateCommentAnnotations(request: UpdateCommentAnnotationsRequest) - Update comment annotations (status, priority, assigned user, etc.).
  • deleteCommentAnnotations(request: DeleteCommentAnnotationsRequest) - Delete comment annotations by document, location, annotation IDs, or user IDs.
  • addComments(request: AddCommentsRequest) - Add comments within a specific CommentAnnotation.
  • getComments(request: GetCommentsRequest) - Get comments within a specific CommentAnnotation.
  • updateComments(request: UpdateCommentsRequest) - Update comments within a specific CommentAnnotation.
  • deleteComments(request: DeleteCommentsRequest) - Delete comments within a specific CommentAnnotation.

ActivityApiService (sdk.api.activities)

  • addActivities(request: AddActivitiesRequest) - Add activity log records for a document.
  • getActivities(request: GetActivitiesRequest) - Get activity logs with optional filters (document, entity, feature/action types, user) and pagination.
  • updateActivities(request: UpdateActivitiesRequest) - Update existing activity log records.
  • deleteActivities(request: DeleteActivitiesRequest) - Delete activity logs by document, entity, or specific IDs.

AccessControlService (sdk.api.accessControl)

  • addPermissions(request: AddPermissionsRequest) - Add permissions for a user on organizations, folders, or documents.
  • getPermissions(request: GetPermissionsRequest) - Get a user's permissions for resources with access role and type details.
  • removePermissions(request: RemovePermissionsRequest) - Remove permissions from a user for specific resources.
  • generateSignature(request: GenerateSignatureRequest) - Generate a secure signature for Permission Provider responses.
  • generateToken(request: GenerateTokenRequest) - Generate a JWT authentication token with user info and resource permissions.

CrdtService (sdk.api.crdt)

  • addCrdtData(request: AddCrdtDataRequest) - Add new CRDT editor data. Supports text, map, array, and xml types.
  • getCrdtData(request: GetCrdtDataRequest) - Get CRDT editor data. Optionally filter by editorId; omit to get all editors for a document.
  • updateCrdtData(request: UpdateCrdtDataRequest) - Update existing CRDT editor data with new content.

PresenceService (sdk.api.presence)

  • addPresence(request: AddPresenceRequest) - Add users to the presence list for a document.
  • updatePresence(request: UpdatePresenceRequest) - Update presence data for existing users on a document.
  • deletePresence(request: DeletePresenceRequest) - Remove users from the presence list for a document.

GdprService (sdk.api.gdpr)

  • deleteAllUserData(request: DeleteAllUserDataRequest) - Delete all user data from Velt (GDPR compliance). Returns a job ID for tracking.
  • getAllUserData(request: GetAllUserDataRequest) - Get all feature data for a user (comments, reactions, recordings, notifications) with pagination.
  • getDeleteUserDataStatus(request: GetDeleteUserDataStatusRequest) - Get the status of a data deletion job.

LivestateService (sdk.api.livestate)

  • broadcastEvent(request: BroadcastEventRequest) - Broadcast a live state event to a document.

RewriterService (sdk.api.rewriter)

  • askAi(request: AskAiRequest) - Send a text rewriting or processing request to an AI model. Supports OpenAI, Anthropic, and Gemini models.

RecordingService (sdk.api.recordings)

  • getRecordings(request: GetRecordingsRequest) - Get recording annotations for a document or organization with optional filtering and pagination.

WorkspaceService (sdk.api.workspace)

  • createWorkspace(request: CreateWorkspaceRequest) - Create a new workspace.
  • getWorkspace(request: GetWorkspaceRequest) - Get workspace details.
  • createApiKey(request: CreateApiKeyRequest) - Create a new API key with optional configuration.
  • updateApiKey(request: UpdateApiKeyRequest) - Update an API key's display name.
  • getApiKeys(request: GetApiKeysRequest) - Get API keys with optional filtering and pagination.
  • getApiKeyMetadata(request: GetApiKeyMetadataRequest) - Get API key metadata (plan info, owner, defaults).
  • resetAuthToken(request: ResetAuthTokenRequest) - Reset the auth token for an API key.
  • getAuthTokens(request: GetAuthTokensRequest) - Get auth tokens for an API key.
  • addDomains(request: AddDomainsRequest) - Add domains to the allowed list.
  • deleteDomains(request: DeleteDomainsRequest) - Remove domains from the allowed list.
  • getDomains(request: GetDomainsRequest) - Get all allowed domains.
  • getEmailStatus(request: GetEmailStatusRequest) - Check email verification status.
  • sendLoginLink(request: SendLoginLinkRequest) - Send a login link via email.
  • getEmailConfig(request: GetEmailConfigRequest) - Get email service configuration.
  • updateEmailConfig(request: UpdateEmailConfigRequest) - Update email service configuration.
  • getWebhookConfig(request: GetWebhookConfigRequest) - Get webhook service configuration.
  • updateWebhookConfig(request: UpdateWebhookConfigRequest) - Update webhook service configuration.

FolderService (sdk.api.folders)

  • addFolder(request: AddFolderRequest) - Add folders to an organization.
  • getFolders(request: GetFoldersRequest) - Get folders. Optionally filter by folder ID with depth control.
  • updateFolder(request: UpdateFolderRequest) - Update folders (rename or move).
  • deleteFolder(request: DeleteFolderRequest) - Delete a folder and all its contents.
  • updateFolderAccess(request: UpdateFolderAccessRequest) - Update access type for folders.

Self-Hosting Services (sdk.selfHosting.*)

CommentService

  • getComments(organizationId, commentAnnotationIds=None, documentIds=None) - Get comments
  • saveComments(organizationId, commentAnnotation, documentId=None) - Save comments
  • deleteComment(organizationId, commentAnnotationId) - Delete a comment

ReactionService

  • getReactions(organizationId, reactionAnnotationIds=None, documentIds=None) - Get reactions
  • saveReactions(organizationId, reactionAnnotation, documentId=None) - Save reactions
  • deleteReaction(organizationId, reactionAnnotationId) - Delete a reaction

AttachmentService

  • getAttachment(organizationId, attachmentId) - Get an attachment
  • saveAttachment(organizationId, attachment, documentId=None) - Save an attachment
  • deleteAttachment(organizationId, attachmentId) - Delete an attachment

UserService

  • getUsers(organizationId, userIds) - Get users by IDs
  • saveUser(organizationId, user) - Save a user

TokenService

  • getToken(organizationId, userId, email=None, isAdmin=None) - Get authentication token

Configuration

Database Configuration

The SDK accepts database configuration in the following format:

config = {
    'database': {
        'host': 'localhost:27017',  # or 'mongodb://...' connection string
        'username': 'your-username',
        'password': 'your-password',
        'auth_database': 'admin',
        'database_name': 'velt-integration'  # Your database name,
        # Optional: override with full connection string
        # 'connection_string': 'mongodb://...'
    }
}

Environment Variables

You can also use environment variables for API credentials:

  • VELT_API_KEY - Velt API key
  • VELT_AUTH_TOKEN - Velt auth token

Error Handling

The SDK uses custom exceptions:

  • VeltSDKError - Base exception
  • VeltDatabaseError - Database-related errors
  • VeltValidationError - Validation errors
  • VeltTokenError - Token-related errors
  • VeltApiError - REST API errors (network failures, unexpected errors)
from velt_py import VeltSDKError, VeltDatabaseError, VeltApiError

try:
    result = sdk.selfHosting.comments.getComments(organizationId='org-123')
except VeltDatabaseError as e:
    print(f"Database error: {e}")
except VeltSDKError as e:
    print(f"SDK error: {e}")

Testing

Install development dependencies:

pip install velt-py[dev]

Run unit tests (mocked, no credentials needed):

pytest tests/ -v --ignore=tests/integration

Run integration tests (hits real Velt API):

VELT_API_KEY=your-key VELT_AUTH_TOKEN=your-token \
    pytest tests/integration/ -v

Run all tests:

VELT_API_KEY=your-key VELT_AUTH_TOKEN=your-token \
    pytest tests/ -v

License

MIT

Support

For issues and questions, please contact support@velt.dev or visit https://docs.velt.dev

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

velt_py-0.1.9.tar.gz (75.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

velt_py-0.1.9-py3-none-any.whl (93.6 kB view details)

Uploaded Python 3

File details

Details for the file velt_py-0.1.9.tar.gz.

File metadata

  • Download URL: velt_py-0.1.9.tar.gz
  • Upload date:
  • Size: 75.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for velt_py-0.1.9.tar.gz
Algorithm Hash digest
SHA256 24b75e5c1fbde81372909d0b98bffea5e5613eef594d7359d7d3f27b49e94ece
MD5 1fa23c1d3482ee9fbc11665e321587e1
BLAKE2b-256 5e24320003aa4cd886bdb05aca4988c35dbbd23880e8e0b64dca767b149230f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for velt_py-0.1.9.tar.gz:

Publisher: publish.yml on snippyly/velt-py-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file velt_py-0.1.9-py3-none-any.whl.

File metadata

  • Download URL: velt_py-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 93.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for velt_py-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 8b64c2ea21e8f898e58744777586537fbe1d2799a7601c50cc52573669d30e8f
MD5 8cc231bc0c5dc88d0b106a41b3167a73
BLAKE2b-256 0e7f9d52cb29379ca182071ca30ba19c2144945e49ab46cc03e9db6e9e60ebfa

See more details on using hashes here.

Provenance

The following attestation bundles were made for velt_py-0.1.9-py3-none-any.whl:

Publisher: publish.yml on snippyly/velt-py-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page