Live Chat
Add a chat widget to your site or app with one script tag. Every conversation is a ticket, so chats live in the same inbox, API and webhooks as everything else.
Overview
The ticket is the conversation and its comments are the messages. A chat ticket has source: "chat", so you can filter, assign and report on chats like any other ticket. Agents reply from the ticket, and replies reach the visitor live.
One script tag
Under 25 KB, no dependencies, isolated from your site's CSS
Verified users
Your server vouches for signed-in users; anonymous visitors stay anonymous
Waiting alerts
Chats turn amber, then red, and your team is alerted
Chat is available on all paid plans (Starter, Pro and Enterprise).
Turn On Chat
In the dashboard, open Settings → Channels → Chat for the brand. Owners and admins can switch chat on there.
Then add every address your site is served from, such as https://www.example.com and https://app.example.com, including staging, without a path. The widget only works on the sites listed.
Install the Widget
Paste this into every page that should show chat, just before </body>. The dashboard shows it with your brand id filled in.
<script
src="https://widget.dispatchtickets.com/v0/widget.js"
data-brand="ws_abc123"
data-title="Chat with us"
async></script>The /v0/ address updates automatically with fixes and features. To pin an exact release instead, use /v0.6.0/widget.js.
Options
| Attribute | Default | What it does |
|---|---|---|
| data-brand | Required | Your brand id (ws_...) |
| data-title | Chat with us | The panel header |
| data-greeting | None | First message on this site. Overrides the greeting set in the dashboard |
| data-color | #2563eb | Any CSS color; invalid values are ignored |
| data-position | right | left or right |
What Visitors See
Set these for each brand in Settings → Channels → Chat → What visitors see:
- Greeting: the first message a visitor sees.
- Offline message: shown when nobody on the team is set to Available or Busy, or chat is outside its hours.
- Chat hours: opening and closing times, days and timezone. A closing time earlier than the opening time runs overnight.
The widget header reads “Online now”, “Away right now” or “Closed right now”. Visitors can always write. A message sent while you're away waits as a ticket. The widget only reveals whether someone is available, never who or how many.
The session starts with the visitor's first message, not when the panel opens, and is kept in the browser, so a reload continues the conversation. Visitors can send images (PNG, JPEG, GIF or WebP, up to 5 MB), including pasted screenshots.
Signed-in Users
Without this step every visitor is anonymous. With it, a chat links to the real contact, agents see who it is (marked Verified), and replies are emailed if the visitor has left.
1. Your server asks Dispatch to vouch for the signed-in user. This needs your API key, so it must never run in the browser. Tokens last an hour; cache one per user.
const res = await fetch('https://api.dispatchtickets.com/v1/brands/ws_abc123/chat/identity-token', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.DISPATCH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
userId: user.id, // your stable user id
email: user.email,
name: user.name, // optional
// optional: the company they're acting for
company: { sourceOrgId: org.id, name: org.name },
}),
});
const { token } = await res.json();2. The page passes the token to the widget, and clears the conversation on sign-out:
DispatchChat.identify(token); // once signed in
DispatchChat.reset(); // on sign-outA conversation belongs to the user it was verified as from the moment it starts. If the conversation stored in the browser is anonymous or belongs to someone else (a shared computer, say), identifying sets it aside and the next message starts a fresh one. A bad or expired token never blocks chat: the visitor carries on anonymously and a warning goes to the console.
The optional companyId or company files the chat under that company (see Ticket company). It is signed into the token, so the browser can't change it.
JavaScript API
To call the widget before its script has loaded, add this stub first. It queues calls and replays them once the widget loads.
<script>
window.DispatchChat = window.DispatchChat || { q: [] };
['open','close','toggle','on','registerAction','setContext','identify','reset'].forEach(function (m) {
window.DispatchChat[m] = function () { window.DispatchChat.q.push([m, [].slice.call(arguments)]); };
});
</script>DispatchChat.open(); DispatchChat.close(); DispatchChat.toggle();
// Events: ready, open, close, message, ticket:created
const off = DispatchChat.on('message', (m) => console.log(m.author, m.body));
// Sent when the conversation starts. Kept: pageUrl, referrer, locale, title.
DispatchChat.setContext({ locale: 'fr-CA' });
// A button above the message box.
DispatchChat.registerAction({ id: 'call', label: 'Book a call', handler: ({ sessionId }) => {} });
// Start a conversation from your own "Report a problem" button. Opens the panel
// unless { open: false }. Available once the script has loaded.
const { sessionId } = await DispatchChat.createTicket({ message: 'Checkout button does nothing' });createTicket() sends the message as the visitor's first message. A conversation already open in that browser is set aside, not deleted: it stays a ticket. It returns a Promise, so it isn't in the queue stub.
Alerts & Webhooks
When a visitor is waiting for a reply, the chat turns amber after 1 minute and red after 3, and your team is alerted in the dashboard. Each brand can change these times in Settings → Channels → Chat → Waiting alerts. Each team member can turn the chime off in their Profile.
Chats also send webhooks:
| Event | Fires when |
|---|---|
| chat.started | A visitor sends the first message. Carries the identity (verified or anonymous) |
| chat.message | A visitor or agent message on a chat. Never internal notes |
| ticket.awaiting_reply | A visitor has waited past the brand's first or urgent alert time |
Privacy & Security
- Anonymous visitors are never emailed. An email address they type is shown to agents as unverified, and is never used as the ticket's requester.
- Only the sites on your list can use your brand's chat, and visitor routes are rate limited.
- Each conversation has its own secret token, stored hashed. Live updates use short-lived, single-use stream tokens.
- Turning chat off, or removing a site, cuts off conversations already open.
- Marking a chat as spam blocks that conversation. The visitor isn't told; what they send is kept on the spam ticket, but it raises no alerts, webhooks or notifications. Restore the ticket from Spam to lift the block.