Put chat on your site

Proactive messages and visitors

Open the chat or show an opener when a visitor matches a rule, and let agents see which signed-in customers are on your site right now and write to them first. The rules, their caps, presence, and starting a chat from the API.

Last updated

Proactive messages

An inbox can open the chat, or show an opener in the preview bubble beside the button, when a visitor matches a rule: Settings › Inboxes › the inbox › Proactive messages. Up to 10 rules; the first that matches fires, at most once per page view. The rules are checked by the chat on your page and need no contact, so they work for anonymous visitors and for signed-in visitors who have never written.

SettingWhat it does
Time on pageSeconds on the page, 0 to 3,600.
ScrollHow far down the page, in percent.
Exit intentThe pointer leaves the top of the window. Desktop only, never on touch screens.
PageA pattern where * matches anything (one starting with / is compared with the path and query, any other with the whole address), or a simple regular expression, checked when saved. The #fragment never counts.
VisitorAny, new, or returning (visited before in this browser).
ActionShow the opener beside the button (the default), or open the chat with it.
MessageThe opener, with a translation per language; the chat picks the visitor's.
How oftenOnce per browsing session (the default), or at most once every N days.

A rule needs at least one of time, scroll or exit intent. Nothing fires while the chat is open or a conversation is under way, nor for 30 minutes (adjustable) after the visitor closed the chat or dismissed a preview. The caps are kept in your page's own storage. A reply to an opener starts the conversation with a line naming the rule, so the agent sees what the visitor answered.

To keep proactive messages off a page, such as a checkout or a payment step, add data-proactive="off" to the script tag. The proactive event tells your page when an opener showed.

Presence

Every widget session announces itself with the current page. The agent app lists signed-in visitors under Inbox, Visitors online: visitors your site identified now, or earlier in the same browser, whether or not they have a contact yet. A visitor who has never written is listed by the name your site signed, from their live session; one who has is listed as their contact, once, even when they are on the site from two devices. Anonymous browsers are not listed, since agents cannot usefully watch hundreds of casual visitors; they become contacts when they write. The list shows the name, the page they are on, how long they have been there, and whether they already have an open conversation. Presence expires 90 seconds after the last heartbeat.

Starting the conversation from the agent side

Clicking a visitor opens a new conversation in the website-chat inbox and sends the first message. Only signed-in visitors can be offered a chat: starting a website chat conversation with any other contact returns 422. For a visitor without a contact, the contact is created (or matched to the one that carries their id) in the same step as the conversation. On the visitor's side the launcher shows an unread badge and, if the page is in the foreground, the panel opens with the message.

Each row of GET /inboxes/{id}/visitors carries exactly one of contact_id and visitor_session_id; pass whichever it has to POST /conversations. A visitor_session_id must belong to the inbox you post to, else 422, and a session that turns out to match a contact your role may not see is refused with 403, as an email of such a contact is.

# visitors currently on the site for inbox 4
curl "$KOMMIO_URL/inboxes/4/visitors" -H "Authorization: Bearer $KOMMIO_KEY"

# open a conversation with a visitor who has a contact (contact_id from the list)
curl -X POST "$KOMMIO_URL/conversations" -H "Authorization: Bearer $KOMMIO_KEY" -H "Content-Type: application/json" \
  -d '{"inbox_id": 4, "contact_id": 133, "content": "Hi! I see you are looking at the pricing page. Anything I can answer?"}'

# or with one who has none yet (visitor_session_id from the list); the contact is created with the conversation
curl -X POST "$KOMMIO_URL/conversations" -H "Authorization: Bearer $KOMMIO_KEY" -H "Content-Type: application/json" \
  -d '{"inbox_id": 4, "visitor_session_id": 5081, "content": "Hi! Anything I can answer about pricing?"}'
Response 200 OK
{ "visitors": [
  { "contact_id": 133, "name": "Maria K. Nowak", "page": "https://acme.example/pricing", "first_seen": "2026-09-22T09:31:10Z", "last_seen": "2026-09-22T09:35:42Z" },
  { "visitor_session_id": 5081, "name": "Jonas Berg", "page": "https://acme.example/pricing", "first_seen": "2026-09-22T09:34:02Z", "last_seen": "2026-09-22T09:35:40Z" }
] }

Every claim on these pages is covered by a test in the repository, and the API reference is generated from the same contract every server serves at /api/openapi. Corrections to [email protected].