Apps and channels

The chat widget

Install the widget, sign users in, the JavaScript API, events, customisation and conversations in the widget.

The widget is a single script that renders a chat launcher on any website and connects it to an app.

#Install

Copy the snippet from App → Install. It looks like this:

HTML
<script src="https://<widget host>/widget.js"
        data-app-id="app_xxxxxxxxxxxxxxxxxxxxxxxx"
        data-api-url="https://<api host>/api"
        async></script>

data-app-id is the app's public id; data-api-url is the AgentRow API base URL. Optional attributes: data-identity-token (a JWT already available at page load) and data-open="true" to open the panel immediately.

#Signing users in

Call AgentRow.identify(token) after your user logs in, with a JWT your backend signs using the app secret. Under "require verified" enforcement the widget shows a sign-in gate until it is called. Call AgentRow.logout() when the user signs out.

#JavaScript API

AgentRow.init(options) starts the widget with options such as appId, apiUrl, identityToken, autoOpen, container (mount inline in an element), mode (floating or inline), theme, css, renderers, strings, showToolActivity and showConversations.

Methods: identify, logout, open, close, send(text), newConversation, openConversation(id), listConversations, showConversations, decideApproval (approve or reject the tool call a run is waiting on), answerQuestion and declineQuestion (the question card a run is waiting on), onEvent and respondToEvent (chat window events, Tools), registerClientAction, setTheme (change the design tokens at runtime), on, once, off, waitFor(event, options), getClient (headless client), destroy, createClient (build your own UI on the client), and version.

#Events

The widget emits events your page can react to: ready, open, close, session:started, session:ended, identity:required, conversations:loaded, conversation:loaded, conversation:opened, conversation:new, conversation:created, message:sent, message:failed, message:delta (streamed text), message:received, run:queued, run:started, run:completed, run:failed, tool:started, tool:delta, tool:completed, tool:failed, approval:requested, approval:decided, question:asked, question:answered, question:refused, intake:submitted, intake:refused, event:<name> (an event tool fired <name> in this chat window), client_action:started, client_action:completed, client_action:failed, client_action:deferred, stream:state and error. Handlers can filter by tool name, so a page can react when a specific tool completes, for example to refresh an order panel after the assistant looked it up. The client_action: events report a step a tool asked the chat window to do in the visitor's browser, such as a change to a Shopify cart (Shopify store assistant) or an event your page answers (Tools).

#Customisation

  • From the dashboard (no redeploy): placeholder, welcome message, suggested prompts, accent colour, light or dark theme, position, launcher label and icon, branding, and whether built-in tool activity is shown — and the look: a header logo, the font and its size, the panel's width, height and corner radius, and the colours of the user, assistant and support bubbles and of the header, with a live preview on the Install tab.
  • From the page: theme tokens (colours, radius, panel width), extra CSS inside the widget, host CSS through shadow parts (launcher, panel, header, messages, composer, footer), custom renderers for messages and other parts, custom copy for every string, inline mounting, and a headless client for a fully custom UI.
  • Tool activity: per tool, choose whether end users see nothing, a status line ("Looking up your order…") or full detail, and give the tool its own icon and label for that line. Built-in tools follow the app-level setting.

#The form at the start of a chat

The Install tab can ask the visitor a short form before the first message — name and email by default; fields of type name, email, phone, text or choice, each required or not — once per visitor or at the start of every conversation. A signed-in user is not asked what their identity token already says. The answers travel with the conversation as the end user's details: agents see them in their auth context and the Inbox shows them on the conversation.

#Questions the agent asks

When the toolbox node's Ask the user is on, the agent has the built-in ask_user tool: it can put a card to the person with one or several questions (up to the node's limit per call), each with options, one it recommends, a free answer where it allows it, and several picks where it allows that. The run pauses until the card is answered. The card shows one question at a time with arrows between them, and Cancel and Submit; a lone question with options only is answered by the pick. The answers go back to the agent as the tool's result — they are never a message of the conversation — and the card gives way to an "Answered · …" line; Cancel tells the agent the person chose not to answer, as does nobody answering within the node's wait. The builder's test chat shows the same card. The tool is bound only where someone can answer: the widget and the test chat, never Slack, webhooks or server runs.

#Events the page answers

A Chat window event tool (Tools) lets the agent ask your page to do something and read the result: register AgentRow.onEvent("book_demo", async (input) => …) on the page, and the tool binds on that page. Async events answer later with AgentRow.respondToEvent(id, result), or from your server with the app secret.

#Conversations in the widget

End users see their conversation list, can start a new conversation and switch between earlier ones. Conversations are tied to the end user, so a signed-in user sees the same history on every device; an anonymous visitor's history stays with their browser until they sign in and it is merged.

#When a person takes over

On support apps the widget tells the end user when the conversation was handed to your team ("You're now talking to Billing…"), keeps the composer open, shows each team reply with the person's name, and notes when the team resolved the conversation (sending a message reopens it).

Updated 30 September 2026