Skip to main content

Polling & Refresh

The widget has no push connection: it fetches new messages from your GraphQL endpoint on a timer. This page covers what that means for your users and your backend, and the two settings you can tune.

At a glance​

  • Panel open: the widget polls every 5 s (pollIntervalOpenMs), so agent replies appear within about 5 seconds.
  • Panel minimized: it polls every 30 s (pollIntervalMinimizedMs), only to update the unread count on the launcher badge. 0 turns this off.
  • Hidden tab: no requests. The widget refreshes once as soon as the tab is visible again.
  • Every poll is one GraphQL request per open tab. Nothing is cached, so the intervals directly set the load on your backend.

Settings​

SettingDefaultRangeWhen it applies
pollIntervalOpenMs5000500–60 000 msPanel open.
pollIntervalMinimizedMs300005000–300 000 ms, or 0 (off)Panel minimized, with a conversation.
setConfig({
settings: {
pollIntervalOpenMs: 10000,
pollIntervalMinimizedMs: 0,
},
});

Choosing values. With the defaults, a user with the panel open makes about 12 requests a minute, and about 2 a minute while minimized. A shorter open interval makes replies feel snappier; a longer one reduces load. Raise the minimized interval, or set it to 0, if the unread badge doesn't need to be timely.

When do new messages appear?​

Agent replies show up in the thread when all of these are true:

RequirementWhy
Panel openWhile minimized, replies only update the launcher badge.
Tab visibleHidden tabs don't poll.
The tab has joined the account's open chatEither this tab started it by sending, or it found it on the server (see Multiple tabs and devices).

The delay is up to pollIntervalOpenMs. Opening the panel or returning to the tab refreshes straight away.

Errors and token refresh​

While requests fail (for example the network is down or a token expired), the widget slows down: the delay doubles after each failure, up to 60 s, and goes back to normal after the first success. With the defaults that's 5 s, 10 s, 20 s, 40 s, then 60 s.

getHeaders is called before every request, so a refreshed token is used by the next poll without you doing anything. To recover straight away instead of waiting out the slower retries, for example after the user signs in again, pass a new getHeaders function to setConfig(). The widget goes back to the normal interval and, with the panel open, refetches immediately:

setConfig({ getHeaders: () => ({ Authorization: `Bearer ${newToken}` }) });
tip

Otherwise keep passing the same function: it's compared by identity, and a new one triggers a refetch every time. See Updating config.

Multiple tabs and devices​

An account has one live chat at a time, shared by every tab and device.

  • Joining a chat already in progress: while the panel is open, a tab without a conversation asks the server for the account's open chat on each poll and joins it, so the user doesn't have to send first.
  • A chat ended elsewhere (another tab, device, or support): on the next poll the history stays on screen, dimmed and read-only, ending with the conversationEndedNotice divider. A Start a new conversation button replaces the composer, and polling stops. A reload shows the same ended chat.

Backend permissions​

Joining a chat already in progress uses the InkLiveChatConversations query. It needs CAN_ACCESS_CUSTOMER_QUERIES on the user's role, and a Kraken version that lets account users run it. If the backend rejects it as unauthorised (KT-CT-1111), the widget logs one console warning and stops looking for this session. The chat still works, but a tab only joins a chat started elsewhere once the user sends a message.

Passing new getHeaders or a new apiUrl to setConfig() makes the widget try again, for example after the user signs in with a role that has access. See Backend permissions.