Overview
Velt supports self-hosting your recording annotation PII data:- Recorded files, recording annotation data, identity (user
fromfield), transcription, and attachment URLs can be stored on your own infrastructure, with only necessary identifiers on Velt servers. - Velt Components automatically hydrate recording data in the frontend by fetching from your configured data provider.
- This gives you full control over PII and recorded files while maintaining all Velt recorder features.
How does it work?
When recorder annotations are created, updated, or deleted:- The SDK uses your configured
RecorderAnnotationDataProviderto handle storage and retrieval. - Your data provider implements three optional methods:
get: Fetches recording annotation PII from your databasesave: Stores PII fields and returns updated transcription/attachmentsdelete: Removes PII fields from your database
- The SDK first attempts the operation on your storage infrastructure
- If successful:
- The SDK updates Velt’s servers with minimal identifiers
- The
RecorderAnnotationobject is updated withisRecorderResolverUsed: truewhile PII is being fetched - Once PII is available, the annotation is hydrated with identity, transcription, and attachment data
- If the operation fails, no changes are made to Velt’s servers and the operation is retried if you have configured retries.
Implementation Approaches
You can implement recorder self-hosting using either of these approaches:- Endpoint based: Provide endpoint URLs and let the SDK handle HTTP requests
- Function based: Implement
get,save, anddeletemethods yourself
| Feature | Function based | Endpoint based |
|---|---|---|
| Best For | Complex setups requiring middleware logic, dynamic headers, or transformation before sending | Standard REST APIs where you just need to pass the request “as-is” to the backend |
| Implementation | You write the fetch() or axios code | You provide the endpoint url, static or async headers, and optional credentials |
| Flexibility | High | Medium |
| Speed | Medium | High |
Endpoint based DataProvider
Instead of implementing custom methods, you can configure endpoints directly and let the SDK handle HTTP requests.headers may also be an async function resolved per request, and credentials ('include' | 'same-origin' | 'omit') enables cookie/session auth — see Async headers and credentials for details.getConfig
Config-based endpoint for fetching recording annotation PII. The SDK automatically makes HTTP POST requests with the request body.- Type:
ResolverEndpointConfig - Request body format:
GetRecorderResolverRequest - Response format:
ResolverResponse<Record<string, PartialRecorderAnnotation>>
- React / Next.js
- Other Frameworks
saveConfig
Config-based endpoint for saving recording annotation PII. The SDK automatically makes HTTP POST requests with the request body.- Type:
ResolverEndpointConfig - Request body format:
SaveRecorderResolverRequest - Response format:
ResolverResponse<SaveRecorderResolverData>
- React / Next.js
- Other Frameworks
deleteConfig
Config-based endpoint for deleting recording annotation PII. The SDK automatically makes HTTP POST requests with the request body.- Type:
ResolverEndpointConfig - Request body format:
DeleteRecorderResolverRequest - Response format:
ResolverResponse<undefined>
- React / Next.js
- Other Frameworks
Endpoint based Complete Example
- React / Next.js
- Other Frameworks
Function based DataProvider
Implement custom methods to handle data operations yourself.get
Fetch recording annotation PII data from your database. Called when annotations need to be hydrated in the frontend.- Param:
GetRecorderResolverRequest - Return:
Promise<ResolverResponse<Record<string, PartialRecorderAnnotation>>>
- React / Next.js
- Other Frameworks
save
Store recording annotation PII fields. Called when a recorder annotation is created or updated.- React / Next.js
- Other Frameworks
delete
Remove recording annotation PII from your database. Called when a recorder annotation is deleted.- React / Next.js
- Other Frameworks
config
Configuration for the recorder data provider.- Type:
ResolverConfig. Relevant properties:resolveTimeout: Timeout duration (in milliseconds) for resolver operationsgetRetryConfig:RetryConfig. Configure retry behavior for get operations.saveRetryConfig:RetryConfig. Configure retry behavior for save operations.deleteRetryConfig:RetryConfig. Configure retry behavior for delete operations.additionalFields:string[]. Specify additional fields from theRecorderAnnotationobject to include in the resolver request payloads sent to your backend. By default, only core PII fields (identity, transcription, attachment URLs) are sent. Use this to request extra fields you need (e.g.,recordedTime,pageInfo).
uploadChunks
Controls whether recording media is uploaded as individual chunks during recording, or as a single full recording after theannotationId is assigned.
- Type:
boolean - Default:
false(upload full recording)
true to upload individual chunks as they are recorded, which can be useful for long recordings or unreliable network conditions.
storage
A scopedAttachmentDataProvider for recorder media files. Use this to route recording file uploads to a separate storage backend from your default attachment provider.
- React / Next.js
- Other Frameworks
Function based Complete Example
- React / Next.js
- Other Frameworks
Sample Data
The recorded media file (audio/video) can be stored at any file storage provider of your choice (e.g., AWS S3, Google Cloud Storage, Azure Blob Storage, or your own servers). The
url field in the attachment object points to wherever you host the file.- Stored on your database
- Stored on Velt servers
from). The url field points to wherever you host the recorded file — any file storage provider works.The singular
attachment field is @deprecated in favor of the attachments array. New integrations should rely on attachments only; existing data may still include attachment for backward compatibility.Loading and Upload State Fields
Two fields onRecorderAnnotation indicate recorder resolver status:
| Field | Type | Description |
|---|---|---|
isRecorderResolverUsed | boolean | true while PII is being fetched from the recorder resolver. Use this field to show a loading state in your UI. |
isUrlAvailable | boolean | true once the recording URL has been uploaded and is available (not a local blob URL). Use this field to indicate upload progress. |
Debugging
You can subscribe todataProvider events to monitor and debug recorder resolver operations. Filter for the RecorderResolverModuleName.GET_RECORDER_ANNOTATIONS module name to isolate recorder-specific events.
You can also use the Velt Chrome DevTools extension to inspect and debug your Velt implementation.
RecorderResolverModuleName — Enum of module names for recorder resolver events.
- React / Next.js
- Other Frameworks

