Velt
Chat SDK adapter backed by Velt Comments. Maps Velt organizations, documents, comment annotations, and comments to the Chat SDK Channel/Thread/Message model.
Install
pnpm add @veltdev/chat-sdk-adapterQuick start
import { Chat } from "chat";
import { createMemoryState } from "@chat-adapter/state-memory";
import { createVeltAdapter, type VeltAdapter } from "@veltdev/chat-sdk-adapter";
const bot = new Chat<{ velt: VeltAdapter }>({
userName: "Velt Bot",
adapters: {
velt: createVeltAdapter({
apiKey: process.env.VELT_API_KEY,
webhookSecret: process.env.VELT_WEBHOOK_SECRET,
botUserId: "velt-bot",
botUserName: "Velt Bot",
}),
},
state: createMemoryState(),
});
bot.onNewMention(async (thread, message) => {
await thread.post(`Hi ${message.author.fullName}! How can I help?`);
});The adapter maps Velt documents to Chat SDK channels, comment annotations to Chat SDK threads, and individual comments to messages — so the rest of the Chat SDK API (subscriptions, handlers, posts, reactions) works exactly the same as with any other adapter.
Configuration
Prop
Type
Platform setup
- Create a Velt account and copy your API key.
- Add a bot user to your organization (
POST /v2/users/addwithuserId: "velt-bot") so it can post and appears in the @-mention list. - Configure webhooks (Velt Console → Configurations → Webhook Service, or
POST /v2/workspace/webhookconfig/update) and subscribe to:comment.addcomment_annotation.addcomment.reaction_addcomment.reaction_delete
- Copy the signing secret (
whsec_...for Advanced/v2 webhooks) intowebhookSecret.
Point your Velt webhook URL at the route that forwards requests to bot.webhooks.velt (see Webhook events).
Webhook events
| Event | Role |
|---|---|
comment.add | Drives Chat SDK message processing |
comment_annotation.add | First comment of a new thread |
comment.reaction_add | Drives reaction handlers |
comment.reaction_delete | Drives reaction handlers |
import { after } from "next/server";
import { bot } from "@/lib/bot";
export const runtime = "nodejs"; // raw body + crypto; not edge
export async function POST(request: Request) {
return bot.webhooks.velt(request, {
waitUntil: (task) => after(() => task),
});
}Velt has two webhook systems and the adapter verifies both: Advanced (v2) with Svix-style HMAC-SHA256 (whsec_..., default) and Basic (v1) with an Authorization: Basic <token> header (set webhookVersion: "v1"). Invalid requests return 401. Passing waitUntil lets work continue after the response is sent in serverless environments like Vercel.
ID encoding
- Thread ID:
velt:{organizationId}:{documentId}:{annotationId} - Channel ID:
velt:{organizationId}:{documentId}
encodeThreadId
adapter.encodeThreadId(data: {
organizationId: string;
documentId: string;
annotationId: string;
}): string;const encoded = adapter.encodeThreadId({
organizationId: "my-org",
documentId: "doc-1",
annotationId: "NHR5sMWU7YmTv2HJ1nVC",
});
// "velt:my-org:doc-1:NHR5sMWU7YmTv2HJ1nVC"decodeThreadId
adapter.decodeThreadId(threadId: string): {
organizationId: string;
documentId: string;
annotationId: string;
};Each segment is URL-encoded, so ids may safely contain :. Throws if the format is invalid.
Message format
Velt Comments are stored as commentHtml, so the adapter converts between Velt HTML and the Chat SDK's mdast AST (VeltFormatConverter). Inbound {{userId}} mention tokens are normalized to readable @Name. Each parsed Message.raw also carries lightweight document context (documentName, documentUrl, anchoredText) so bots can ground replies.
Supported: paragraphs with bold, italic, code, strikethrough, links, and @mentions.
Flattened to plain text / paragraphs: headings, lists, code blocks, tables, and card payloads (rendered as fallback text). Interactivity is not preserved.
Reactions
Reading reactions (onReaction) works on all Velt plans.
Writing reactions (addReaction / removeReaction) is not supported on the managed Velt backend — there is no managed REST endpoint to add a reaction as a user, so these methods throw a clear PermissionError. To enable reaction writes, provide selfHostingConfig.reactionsService (a self-hosted reactions service backed by your own database).
Examples
- Velt Chat SDK Bot — Next.js bot that replies to @-mentions in Velt comment threads.
- Velt Chat SDK AI Bot — same stack with a streaming Claude reply flow.
- Full walkthrough: Get started with a Chat SDK bot using Velt.
Feature support
Messaging
| Feature | Supported |
|---|---|
| Post message | |
| Edit message | |
| Delete message | |
| File uploads | |
| Streaming | |
| Scheduled messages |
Rich content
| Feature | Supported |
|---|---|
| Card format | Flattened to text |
| Buttons | |
| Link buttons | |
| Select menus | |
| Tables | Flattened to text |
| Fields | |
| Images in cards | |
| Modals |
Conversations
| Feature | Supported |
|---|---|
| Slash commands | |
| Mentions | Users |
| Add reactions | Self-hosted only |
| Remove reactions | Self-hosted only |
| Typing indicator | |
| DMs | |
| Ephemeral messages | |
| User lookup | resolveUsers |
| Parent subject | |
| Native client | |
| Custom API endpoint |
Message history
| Feature | Supported |
|---|---|
| Fetch messages | |
| Fetch single message | |
| Fetch thread info | |
| Fetch channel messages | |
| List threads | |
| Fetch channel info | |
| Post channel message |