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 atapi.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 commentssaveComments(organizationId, commentAnnotation, documentId=None)- Save commentsdeleteComment(organizationId, commentAnnotationId)- Delete a comment
ReactionService
getReactions(organizationId, reactionAnnotationIds=None, documentIds=None)- Get reactionssaveReactions(organizationId, reactionAnnotation, documentId=None)- Save reactionsdeleteReaction(organizationId, reactionAnnotationId)- Delete a reaction
AttachmentService
getAttachment(organizationId, attachmentId)- Get an attachmentsaveAttachment(organizationId, attachment, documentId=None)- Save an attachmentdeleteAttachment(organizationId, attachmentId)- Delete an attachment
UserService
getUsers(organizationId, userIds)- Get users by IDssaveUser(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 keyVELT_AUTH_TOKEN- Velt auth token
Error Handling
The SDK uses custom exceptions:
VeltSDKError- Base exceptionVeltDatabaseError- Database-related errorsVeltValidationError- Validation errorsVeltTokenError- Token-related errorsVeltApiError- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file velt_py-0.1.10.tar.gz.
File metadata
- Download URL: velt_py-0.1.10.tar.gz
- Upload date:
- Size: 76.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a89ad04c7b5a73de625a6126373cc6fb0fa55436f58beea547d53ca465f4f767
|
|
| MD5 |
bb81ae7b503c988271c5cb3b24ec63da
|
|
| BLAKE2b-256 |
9779570bac3b32ec15042ceb7311cff8d652a90216e457acd1085170e185fbd1
|
Provenance
The following attestation bundles were made for velt_py-0.1.10.tar.gz:
Publisher:
publish.yml on snippyly/velt-py-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
velt_py-0.1.10.tar.gz -
Subject digest:
a89ad04c7b5a73de625a6126373cc6fb0fa55436f58beea547d53ca465f4f767 - Sigstore transparency entry: 1566684067
- Sigstore integration time:
-
Permalink:
snippyly/velt-py-sdk@cfce32e83e609d2930d7082ceb70842454e95d50 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/snippyly
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cfce32e83e609d2930d7082ceb70842454e95d50 -
Trigger Event:
push
-
Statement type:
File details
Details for the file velt_py-0.1.10-py3-none-any.whl.
File metadata
- Download URL: velt_py-0.1.10-py3-none-any.whl
- Upload date:
- Size: 95.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a2621e7f437facc98cc24a76400105a019b39d3643dc1ac8e52e4b09af823eb
|
|
| MD5 |
cc55b399c8266b3de3f1f35c3941395c
|
|
| BLAKE2b-256 |
bea6d136cedd8aafdb898785ad5d16e7978688abfe07d38d179fb12a1bf14620
|
Provenance
The following attestation bundles were made for velt_py-0.1.10-py3-none-any.whl:
Publisher:
publish.yml on snippyly/velt-py-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
velt_py-0.1.10-py3-none-any.whl -
Subject digest:
9a2621e7f437facc98cc24a76400105a019b39d3643dc1ac8e52e4b09af823eb - Sigstore transparency entry: 1566684072
- Sigstore integration time:
-
Permalink:
snippyly/velt-py-sdk@cfce32e83e609d2930d7082ceb70842454e95d50 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/snippyly
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cfce32e83e609d2930d7082ceb70842454e95d50 -
Trigger Event:
push
-
Statement type: