Skip to content
GitHub

Web SDK chat API

Control the Runbear chat widget from your page — mount, reset and reopen conversations, send messages, and listen for its lifecycle and session events.


On this page

client.createChat() returns the widget instance, typed Chat. Your page drives it with the methods below and follows what it is doing through events.

const client = new Runbear({ assistantId: "…", auth: { mode: "session", fetchSessionToken } })

const chat = client.createChat()
chat.on("containerReady", ({ threadId }) => saveThreadId(threadId))
chat.on("sessionFailed", ({ reason }) => showRetry(reason))
chat.mount("#runbear-chat")

createChat(threadId) creates a widget that opens an existing conversation instead of starting a new one. See Saving and reopening a conversation.

Methods#

MethodWhat it does
mount(target)Renders the widget into target, a CSS selector or an HTMLElement, and starts the conversation. Throws "Could not find element to mount chat widget" when the selector matches nothing, and "Chat widget is already mounted" on a second call. Does nothing outside a browser. Mount into an empty element: see Limitations
destroy()Removes the widget, removes every event listener, and stops its session renewals. Call it when the element goes away, such as in a React effect's cleanup
on(event, callback)Subscribes to an event
off(event, callback)Unsubscribes the same callback
reset()Starts a new, empty conversation. In session mode it asks your endpoint for a new session, without a resume token
startWithMessage(text)Starts a new conversation and sends text as its first message
startWithThread(threadId)Opens an existing conversation and loads its history. In session mode it first mints a session bound to that thread
addUserMessage(text)Sends text as if the visitor had typed it. Before the widget has a conversation it does nothing and logs a warning
addSystemMessage(text)Queues text as a system message, sent together with the next user message. Before the widget has a conversation it does nothing and logs a warning. reset(), startWithMessage() and startWithThread() clear the queue
retrySession()Session mode only: recovers after sessionFailed. Does nothing in any other state. See Errors

Events#

EventPayloadWhen
chatCreated{ threadId }The widget has a new conversation: created on mount or by reset(), startWithMessage() or, in session mode, startWithThread()
chatStartedNoneThe first message appears in a conversation
renderedNoneThe widget has rendered its UI. It renders again after reset(), startWithMessage(), startWithThread() and a session change, so this can fire several times
containerReady{ threadId }Once per mount, when the widget first has a conversation and can accept messages
messagesLoaded{ threadId, messageCount }After startWithThread() has loaded the history, and after startWithMessage() has created its conversation
sessionReady{ sessionId, threadId }Session mode: the first session is live
sessionRenewed{ sessionId }Session mode: the pass was renewed; same conversation
sessionChanged{ sessionId, threadId }Session mode: a different session is now active, after reset(), startWithMessage(), startWithThread(), or when your endpoint minted a new session instead of refreshing
sessionFailed{ reason }Session mode: the session ended. reason is "declined", "expired", "network" or "misconfigured". See Errors

The ChatEventSession*Data payload types are exported from 0.2.0. ChatEventCreatedData, ChatEventContainerReadyData and ChatEventMessagesLoadedData are exported from 0.5.0 (not yet released); on 0.4.0 those payloads have the same shapes but no exported names. See Types.

Lifecycle#

mount()
  ├─ proxy or direct mode ─▶ POST /v1/threads ─▶ chatCreated ─▶ containerReady
  │                          (with createChat(threadId): containerReady only)
  └─ session mode ─▶ fetchSessionToken() ─▶ sessionReady ─▶ chatCreated ─▶ containerReady

while mounted
  ├─ session mode ─▶ sessionRenewed on each renewal
  ├─ reset() / startWithMessage() ─▶ (sessionChanged) ─▶ chatCreated
  ├─ startWithThread(id) ─▶ (sessionChanged ─▶ chatCreated) ─▶ messagesLoaded
  └─ a session ends ─▶ sessionFailed ─▶ retrySession()

destroy()

Two rules follow from it:

  • Subscribe before you mount. Some events fire during mount() itself, such as containerReady for createChat(threadId) outside session mode.
  • Wait for containerReady before sending. addUserMessage() and addSystemMessage() need a conversation; called earlier they do nothing and log a warning. In session mode sessionReady fires just before the widget adopts the session's conversation, so a message sent from a sessionReady handler is dropped. Use sessionReady, sessionChanged and sessionFailed to follow the session, and containerReady or chatCreated to know the widget can take a message.
chat.on("containerReady", () => {
  chat.addSystemMessage("The visitor is on the pricing page.")
  chat.addUserMessage("What does the Pro plan include?")
})
chat.mount("#runbear-chat")

Saving and reopening a conversation#

To let a visitor come back to a conversation later, on another device or after the stored session has expired:

  1. Save the thread id. Record the threadId from chatCreated in your own database, next to the visitor.
  2. Reopen it. Create the widget with client.createChat(savedThreadId), or call chat.startWithThread(savedThreadId) on a mounted one.
  3. In session mode, forward the thread id once. The SDK passes it to fetchSessionToken as threadId for that one mint; your endpoint forwards it as thread_id to POST /v1/sessions. Forward it only when the SDK sends it. An endpoint that always adds the saved id makes reset() reopen the old conversation instead of starting a new one.

Reopening a conversation replaces the widget's current session, including the stored resume token. The thread must belong to the same agent and your organization, or the mint returns 404. If your endpoint ignores threadId, the visitor lands in a new conversation and sessionChanged reports a different thread id from the one you asked for.

Within one browser, you don't need this: the default storage: "session" already resumes the conversation after a reload. See Where the session is stored.

  • Authentication: session mode and your endpoint
  • Errors: recovering from sessionFailed
  • Types: Chat and the event payload types