window.anyreach and emits a stream of events: what the visitor did on your site, what they did with the widget, and what happened in the conversation. Every event carries the same envelope (visitor id, session, page, campaign, device), so a single record is joinable into a funnel without lookups.
Events are delivered to your own JavaScript callbacks and, optionally, pushed to a Google Tag Manager data layer. Anyreach also receives a fixed subset of them, cut to a few fields, for the widget’s Analytics page and its experiments’ results: the page views, the widget and conversation events, and cart adds from chat. The journey events (session start and end, time on page, scroll depth), identify traits and your track goals stay in your visitor’s browser. What Anyreach receives lists it exactly, and config({ analytics: false }) stops it.
Quick start
Subscribe before the loader arrives by queueing commands onwindow.anyreach. The loader replays the queue when it loads, so listeners registered this way see the very first events (session_started, page_viewed, widget_loaded).
window.anyreach is an object and the same calls work directly:
push([...]) keeps working after load, so a snippet written for the queue form never has to care which state the loader is in.
API
Google Tag Manager
{ event: 'anyreach.<name>', anyreach: { ...payload } }. In GTM, create a Custom Event trigger on anyreach.widget_opened (or a regex such as anyreach\..*) and read fields with Data Layer Variables like anyreach.page_path or anyreach.conversation_id.
Envelope
Every event carries these fields. Ids are minted by the loader on your page, in first-party storage, so they survive across pages even in browsers that partition third-party iframe storage.Events
Page and journey
Emitted by the loader on your page; no widget interaction needed. These give you the denominator for every engagement rate. Turn them off withconfig({ pageEvents: false }) if your consent setup does not cover page-level tracking; that also stops Anyreach counting page views. Of these, only page_viewed is ever sent to Anyreach, and only as a count.
Widget lifecycle
Conversation
Identity
Emitted by the widget when its agent has identity verifiers; the widget turns identity on by itself, there is no widget setting. Neither event carries an identifier (no customer id, email or phone), so both are safe to forward to analytics.Yours
Notes
- Dedupe on
event_id, order onsequence_number. Listeners fire synchronously in the order events happen, but if you forward them to a server, do not trust client clocks for ordering. - What Anyreach receives. Only the subset Widget analytics lists, never message text, displayed question text, form answers,
identifytraits or yourtrackgoals. Conversation data reaches Anyreach through the widget as it always has. Events are delivered only to the origin the loader embedded the widget from; a widget framed some other way emits nothing. - Signed payloads stay out of the stream. The
identifyevent dropssignature,ts,token,jwtandhmacfromtraits, so a signed identity payload never reaches your listeners ordataLayer, where it could be copied and replayed. The widget itself still receives the full traits. - Consent. The page and journey events observe scroll depth, dwell time and URLs. If your consent banner gates that kind of tracking, call
config({ pageEvents: false })until consent is given, or simply do not subscribe. To keep everything from Anyreach until consent, queueconfig({ analytics: false })before the loader and switch it on when the visitor agrees; the widget’s Collect analytics setting turns it off for every visitor. - Outcome classification, intent and sentiment are produced server-side after the conversation and are not part of this stream.

