Self-hosted data

Add Velt without moving your data.

Per-feature data providers keep comments, recordings, notifications, attachments, and user PII on your infrastructure; Velt stores only minimal identifiers. Node and Python backend SDKs.

No more enterprise deals stalled on “where does our data live?”

Free tier. No credit card. First comment in 5 minutes.

YAyour-infra / architecture
data residency ✓
Your AppSDK runs here · strips PII before write
Your Databasecontent · PII · attachments
identifiers only ↓
Velt Cloudthread structure · document IDs · timestamps
velt.setDataProviders({
  comment: {
    get:    (req) => myDb.fetch(req),
    save:   (req) => myDb.insert(req),
    delete: (req) => myDb.remove(req),
  },
});

velt.setDataProviders(): one call, full control

Build this

Self-hosted data running inside products at

Migrating from an in-house residency layer?Compare·Migration guide

What it is

Your content stays home. Both actors.

Velt self-hosted data keeps user-generated content and PII on your own infrastructure; Velt stores only minimal structural identifiers. You register per-feature data providers for comments, recordings, notifications, activity, attachments, and users; content is stripped from every write on the device and merged back on read, so the UI renders exactly as a Velt-hosted setup. Humans and agents write through the same providers, and the agent comment keeps its Approve and Reject buttons when the thread merges back together.

human revieweragent · AGENT
each write structure → Velt cloudeach write content → your database

merge on read

one rendered thread · the agent comment keeps its Approve and Reject buttons

PII is stripped on the device before any request to Velt is made

humans and agents write through the same providers

How it works

Three steps to data on your infrastructure.

Install the SDKs, implement a provider as callbacks or endpoint URLs, and pass dataProviders to VeltProvider before identify runs. Every key is optional; register only the features you want self-hosted.

01Install
terminal
npm install @veltdev/react
# backend, for endpoint mode:
npm install @veltdev/node
02Implement
providers.ts
// providers.ts — callbacks or endpoint URLs
const comment = {
  get, save, delete, // your store
};
03Wrap
_app.tsx
<VeltProvider
  apiKey={VELT_API_KEY}
  dataProviders={{ comment, recorder, user }}>
  <YourApp />
</VeltProvider>
With Velt

The mechanics

Velt uses a strip-on-write, merge-on-read model. On write, PII is stripped on the device; only the structural remainder goes to Velt while your provider persists the content. Writes hit your database first, and Velt applies the change on its side only after your success response. On read, Velt fetches the content back from your provider and merges it into the structural record. Each operation is a frontend callback or an HTTP endpoint Velt calls for you, and the two styles mix per operation. Timeouts, retries, and rollback on failure are configurable per provider; if your backend is unreachable Velt degrades instead of dropping, rendering the structural record without the content.

// strip-on-write · merge-on-read · your database first

Build it yourself

What an in-house version requires

  • a per-feature split of structural fields versus content
  • strip-on-write and merge-on-read sync
  • your-database-first write ordering with rollback
  • retry and timeout policies per operation
  • a multipart contract for binary files
  • email-to-user identity resolution for mentions
  • graceful rendering when your backend is down
  • a field-level inventory your buyer's security team will accept

Teams that build this build it per feature and re-litigate it per deal. The providers above carry that whole contract as configuration; the field inventory doc is the security-review artifact, already written.

MCP: the faster path.

Skip the steps. Have your agent set it up.

npx -y @velt-js/mcp-installer

Launch self-hosted data this week.

No credit card. Works with React, Next.js, Vue, Angular, and HTML.

Get Free API Key

Capabilities

Your data stays yours.

Each card shows the real mechanics. Toggle to Code for the exact snippet behind it.

01comments
Comment datayour DB
get(req)read a thread from your store
your DB
save(req)write the comment content
your DB
delete(req)remove it on request
your DB
Veltkeeps only the thread structure: never the content
// comments
// comment provider runs against your store
const comment = { get, save, delete };

Comment content on your database

The comment provider's get, save, and delete run against your store; Velt keeps thread structure only. The clause debate, the filing note, the counterparty reply never leave your infrastructure.

02recordings
Recordingsyour bucket
session-rec.webmraw media file
you upload
Your bucketS3 · GCS · Azure
your infra
server-side encodingskipped
transcriptionskipped
// recordings
// uploaded to your bucket
// no server-side encoding or transcription

Recording files in your bucket

Velt uploads each recording to the storage you provide and skips its own server-side encoding and transcription. The client call and the screen capture exist only where you put them.

03notifications
Notificationshybrid
Custom contentresolved on the server
your DB
Comment notificationsassembled in the browser
client-side
// notifications
// custom content resolved from your DB
// comment notifications built client-side

Notification content on your side

Custom notification content resolves from your database at render; comment notifications build client-side from your self-hosted comment data. Reviewers get the full inbox, Velt never holds the message text.

04activity
Activity logappend-only
Log contentevery action recorded
saved
Entity snapshotcaptured at write time
saved
No delete pathrecords never mutate
immutable
// activity
// append-only — no delete
const activity = { get, save };

Append-only activity logs

The activity provider saves log content, entity snapshots, and custom fields to your store; there is no delete. The record your auditor reads lives on infrastructure you control.

05attachments
Attachmentsyour storage
contract-v3.pdfraw bytes
you upload
Amazon S3Google GCSAzure Blob
URL onlyVelt stores the link: never touches the bytes
// attachments
// you upload, you return a URL
const attachment = { save, delete };

Attachments straight to your storage

Velt hands your provider the raw file; you upload to S3, GCS, or Azure Blob and return a URL. Velt never touches the bytes.

06users
User directory{ userId }
Velt cloudstores { userId }: opaque id
Velt
resolves at render
nameemailavatar
// users
// Velt stores only userId
const user = { get }; // name, email, avatar

User PII reduced to an ID

Velt stores only the userId; the user provider resolves names, emails, and avatars from your directory at render. Employee and client identities never enter a vendor database.

07inventory
Field inventory6 fields
fieldyoursvelt
commentText
userId
name / email
documentId
status / ts
attachments
review-readyhand it to your security reviewer: no call needed
// inventory
// docs.velt.dev/self-host-data/field-inventory

The complete field inventory

Every persisted field documented with types, examples, and strip rules: Velt's database versus yours. Hand it to the security reviewer instead of scheduling a call.

08backend
Backend SDKsserver-side
Self-hosting SDK
sdk.selfHosting.getComments(req)reads straight from your MongoDB + S3
your store
REST API
sdk.api.*stateless calls: no database required
no database
// backend
sdk.selfHosting.getComments(req); // Node + Python

Node and Python backend SDKs

sdk.selfHosting.* answers every resolver request against MongoDB and AWS S3; sdk.api.* calls Velt's REST APIs with no database. Your endpoints become pass-throughs, not projects.

Little big details

The long tail, already built.

Shipped functionality only; every line traces to the self-host-data or backend SDK docs. This is the part of an in-house residency layer that never ends.

Per-feature providers: comment, reaction, recorder, notification, activity, attachment, user, anonymousUserMix and match: register only the providers you want; unregistered features stay fully Velt-hostedStrip-on-write, merge-on-read: PII is stripped on the device and never leaves it for Velt, in transit or at restYour-database-first writes: Velt applies a save or delete only after your success responseCallback functions or endpoint URLs per operation, mixable within one providerConfigurable resolveTimeout (default 60s), retryCount, retryDelay, and revertOnFailure rollbackDegrade, don't drop: on resolver failure Velt renders the structural record without the contentfieldsToRemove moves custom fields out of Velt's database; additionalFields copies them to your backendDelete requests minimized to apiKey, documentId, organizationId, and folderIdProvider metadata carries your documentId and organizationId, not Velt's internal hashed IDsSeparate storage scopes: dataProviders.attachment and dataProviders.recorder.storageBinary uploads use a multipart contract; JSON everywhere elseRecording uploads skip Velt's server-side encoding and transcriptionAnonymous user resolution: @mention by email maps to your userId; the raw email is droppedIn-app comment notification content is generated client-side from your self-hosted comment dataDocumented email path is webhooks plus your own email provider when comment content is self-hostedNotification provider applies to custom notifications only; read-only enrichment (get and delete)Activity is append-only and resolves through user, comment, reaction, recorder, then activity providersCross-organization For You notifications call your endpoints with each entry's organizationIdRuns on AWS, GCP, Azure, or any custom infrastructureMongoDB and PostgreSQL backend endpoint examples in the docsNode SDK (@veltdev/node): sdk.selfHosting.* against MongoDB 6+ and S3; MinIO via custom S3 endpointPython SDK (velt-py): sdk.selfHosting.* with MongoDB and S3; sdk.api.* REST parity with NodeREST-API comment writes interoperate via isCommentResolverUsed and isCommentTextAvailableDebug: subscribe to dataProvider events with a moduleName; Velt Chrome DevTools extensionProviders must be set before identify; compatible with the setDocuments methodGDPR REST APIs: get, delete, and check deletion status for a user's data stored in VeltScope boundary: cursors, presence, huddle, and live selection have no resolver and stay Velt-hosted

Make it yours

Your providers, your privacy posture.

Per-provider timeouts, retries, and rollback for the fast path; custom fields, callback-versus-endpoint styles, and a debug event stream underneath.

Configure

Per-provider resolveTimeout, retry policies, and revertOnFailure; resolveUsersConfig to scope user fetches to organization, folder, or document; custom collection names in the Python SDK.

velt.configself-hosted
Data provider
Region
Interface

Extend

fieldsToRemove and additionalFields for your own custom fields; callback versus endpoint style per operation; the dataProvider debug event stream piped into your observability stack.

get · save · deleteyour data provider contract
your DB
Recordings · attachmentsbinary routed to object storage
your bucket
Identifiers · timestampsstructure only: no content
Velt cloud
in-regionresidency stays in your region: call via REST or SDK

In production

Self-hosted data, in products like yours.

Tabbed by vertical, with verified customer screenshots.

SummaryNext StepsDemoCustomer Stories

Hey Conductor!

This Digital Sales Room gives you everything you need to move forward — from proposal to plan.

Our Mutual Action Plan
Training2 / 5
Creating a new Room1
Build a working demo room
Contract sign-off
Maya2m

@Fin We need to make a working demo for Rene and his team

Brand and legal feedback on decks and emails persists to your database; attachments land in your bucket. The client's content policy is satisfied without a second architecture.For sales enablement

See it running in products like yours.

30 minutes, with an engineer, not a sales deck.

Book Demo
Built for enterprise

Built for your customers' compliance.

Per-feature data providers keep content and PII on your infrastructure. SOC 2 Type II audited, HIPAA workloads supported, data residency options including the EU.

PILLAR 01 · DEPLOYMENT

Your data stays yours.

Velt stores minimal identifiers. Everything sensitive lives where you say it does.

▸ comments → your db
▸ recordings → your S3
▸ user PII → never leaves
PILLAR 02 · RELIABILITY

99.999% SLA

Reliability terms in writing for enterprise plans, with a public status page your team can watch.

trailing 90d100.000%
PILLAR 03 · GLOBAL

42 regions

Multi-region infrastructure with residency pinning, so review stays fast wherever your users work.

us-east, eu-west,
ap-south, +39 more
PILLAR 04 · COMPLIANCE

SOC 2 Type II.

The information your buyer's security team asks for, ready before they ask.

SOC 2 report under NDA
HIPAA BAA available
PEN TESTS regular

FAQ

Questions about self-hosted data.

By default, in Velt's managed backend. Register data providers and the content and PII for comments, reactions, recordings, notifications, activity, attachments, and users live on your infrastructure instead, with Velt keeping only structural identifiers. You choose per feature; anything without a provider stays Velt-hosted. Realtime features like cursors and presence have no stored content split and remain Velt-hosted.

Minimal identifiers: IDs, document and organization references, locations and targets, statuses, timestamps, and relationships, which is what Velt needs to position pins, thread comments, and drive real-time sync. Content is stripped on the device before any request to Velt is made. The Complete Field Inventory documents every persisted field on both sides, with types, examples, and strip rules; it is the proof, not this paragraph.

No. What is live today is the data-provider model on this page: your content and PII on your infrastructure, Velt's cloud running the sync and rendering against minimal identifiers. We would rather show you exactly where that boundary sits, in the field inventory, than imply a deployment model that does not exist today. If your requirement is different, book a demo and bring your security team.

Install @veltdev/node, initialize VeltSDK with your MongoDB connection (and S3 credentials if you self-host attachments), and expose endpoints that pass the raw resolver request to sdk.selfHosting methods like getComments, then return the response as-is. On the frontend, point each provider's getConfig, saveConfig, and deleteConfig at those endpoints.

Comments (thread level), reactions, recordings including the files themselves, custom notifications, activity logs, comment attachments, user PII, and anonymous user resolution for email mentions. You can self-host some and leave the rest Velt-hosted.

Velt degrades instead of dropping: reads time out (60 seconds by default, configurable) and the UI renders the structural record without the content, then recovers on the next successful fetch. Writes go to your database first, so Velt never persists a change your side rejected; retries and rollback are configurable per provider.

Velt is priced on usage, not seats: you pay for documents with review activity in a month, with a free tier for development and early production.

Add Velt without moving your data.

Free tier. No credit card. First comment in 5 minutes.

30 minutes, with an engineer, not a sales deck.