Chat
The client.chat namespace is the heart of the Client SDK. It manages threads
(conversations) and the messages within them.
Creating a thread
Section titled “Creating a thread”const thread = await client.chat.create({ title: "Support session", // optional systemMessage: "Be concise", // optional visibility: "private", // "private" | "shared" | "public"});
console.log(thread.id); // use this id for all subsequent callsThe Release id is taken from the client — you don’t pass it again.
Anonymous threads
Section titled “Anonymous threads”For public/landing-page chat where the user isn’t signed in, open an ephemeral thread. The Release must permit anonymous chat.
const thread = await client.chat.createAnonymous();Sending a message
Section titled “Sending a message”Use stream() to send a message and receive the assistant’s reply — it
resolves with the final ChatMessage (and can deliver tokens incrementally;
see Streaming).
const reply = await client.chat.stream(thread.id, "What is your return policy?", { assistantName: "your-assistant-id", // required — the release's assistant/model id});
console.log(reply.content); // assistant textconsole.log(reply.context); // RAG sources, if anyMessage options
Section titled “Message options”await client.chat.stream(thread.id, "Summarize the docs", { assistantName: "support-bot", // required: which assistant responds attachments: [{ type: "image", data: dataUrl, mimeType: "image/png" }], metadata: { source: "help-center" }, replyTo: "msg_abc", // thread a reply to a specific message});Fire-and-forget with send()
Section titled “Fire-and-forget with send()”send() posts the message and returns a SendAck { status: "sent" } immediately.
Generation continues server-side — the reply arrives over the realtime WebSocket
or becomes visible via getTranscript(). Use it when you don’t need to render
the reply inline:
const ack = await client.chat.send(thread.id, "Log this note", { assistantName: "support-bot",});console.log(ack.status); // "sent"
// reply arrives async — poll when you need it:const messages = await client.chat.getTranscript(thread.id);Blocking send with sendAndPoll()
Section titled “Blocking send with sendAndPoll()”If you need a single call that waits for the assistant reply (no streaming),
sendAndPoll() submits the message then polls getTranscript() until the
assistant’s message appears:
const reply = await client.chat.sendAndPoll(thread.id, "Summarize this.", { assistantName: "support-bot", pollInterval: 1500, // check every 1.5s (default) timeout: 60_000, // give up after 60s (default)});console.log(reply.content);Listing and reading threads
Section titled “Listing and reading threads”// Paginated list of the caller's threadsconst { data, hasMore, total } = await client.chat.list({ limit: 20 });
// A single thread's metadataconst thread = await client.chat.get("chat_123");
// Full message history for a threadconst messages = await client.chat.getTranscript("chat_123");for (const m of messages) { console.log(`${m.role}: ${m.content}`);}
// Delete a threadawait client.chat.delete("chat_123");Feedback and ratings
Section titled “Feedback and ratings”Capture thumbs up/down and free-text feedback on assistant messages.
// Simple rating: 1 = thumbs up, -1 = thumbs down, 0 = clearawait client.chat.rateMessage(thread.id, messageId, 1);
// Rating + free-text reasonawait client.chat.submitMessageFeedback(thread.id, messageId, { sentiment: -1, feedback: "The answer missed the EU shipping case.",});For anonymous (landing/embed) chats, feedback is proven by the held signed transcript rather than a session:
await client.chat.submitAnonymousFeedback({ releaseId: "rel_abc123", transcript, // the client-held signed transcript signiture: hmac, // server-issued HMAC messageIndex: 3, sentiment: 1, feedback: "Perfect, thanks!",});To read the feedback your releases received (operator view: list, filter,
and aggregate stats), use the client.feedback
namespace.
Arena variants
Section titled “Arena variants”When a Release runs in arena mode, a message can return multiple model variants for side-by-side comparison. Record the user’s pick:
await client.chat.selectArena(thread.id, messageId, /* selectedIndex */ 0);Streaming surfaces variants as they arrive via onArenaVariant /
onArenaComplete — see Streaming.
Message shape
Section titled “Message shape”Each ChatMessage carries:
| Field | Type | Notes |
|---|---|---|
id | string | Message id |
role | "user" | "assistant" | "system" | |
content | string | The text |
timestamp | string | ISO timestamp |
context | ChatMessageContext[]? | RAG sources, if context bubbles are on |
products | ProductRecommendation[]? | Catalog matches, if any |
tokenCount | number? | |
arenaVariants | ArenaResponseVariant[]? | Present in arena mode |