Where does this run? Your analytics setup never goes inside the SiteGPT
widget. The install snippet (
https://sitegpt.ai/widget/YOUR_CHATBOT_ID.js) runs
on your own page, alongside the GTM or GA4 you already have there. The chat
widget posts each event from its iframe to your page, and that snippet forwards
it to your dataLayer, a window event, and any $sitegpt callback. So you
wire everything up on your own site, using the tracking that already lives there.Events
Every event is delivered in three ways at once (see How to listen): adataLayer push for GTM, a window CustomEvent, and a $sitegpt callback.
| Event | Fires when | Payload |
|---|---|---|
chat_opened | The chat window is opened | chatbotId |
chat_closed | The chat window is closed | chatbotId |
conversation_started | The visitor sends their first message in a new conversation | chatbotId, threadId |
message_sent | The visitor sends any message | chatbotId, threadId |
lead_submitted | The visitor submits the lead / contact form | chatbotId, threadId |
human_handover | The conversation is handed over to a human agent | chatbotId, threadId |
booking_link_clicked | The visitor clicks a scheduling link (Calendly, Cal.com, HubSpot Meetings, Google/Microsoft Bookings, and similar) in a reply | chatbotId, threadId, url (provider host only, e.g. https://calendly.com) |
Payloads are intentionally free of personal data (no name, email, phone, or
message text), so they are safe to forward to GA4, which prohibits sending
personally identifiable information. The lead details themselves stay in your
SiteGPT dashboard and any connected CRM.
How to listen
Pick the method that matches your stack. You can use more than one.- Google Tag Manager
- Google Analytics 4 (gtag)
- Custom JavaScript
Each event is pushed to To use it in GTM:
window.dataLayer with the event name
sitegpt_<event> (for example sitegpt_conversation_started). The payload
fields are added to the same object.Example pushed object:Create a Custom Event trigger
In GTM, add a Trigger → Custom Event and set the Event name to
the event you want, e.g.
sitegpt_lead_submitted. Use
sitegpt_.* with Use regex matching to capture every SiteGPT event
in one trigger.Read the payload (optional)
Create Data Layer Variables named
chatbotId, threadId, or url
to pass those values into your tags.The widget pushes to
dataLayer directly, so it works even if GTM loads
after the widget. You do not need to pre-declare window.dataLayer.Multiple widgets on one page
If you run more than one SiteGPT chatbot on the same page, every event payload includes thechatbotId it came from. In GTM/GA4, filter on the chatbotId
data layer variable; in a callback or DOM listener, check data.chatbotId.
Reference
- dataLayer event name:
sitegpt_<event>(e.g.sitegpt_chat_opened) - DOM event name:
sitegpt:<event>(e.g.sitegpt:chat_opened), payload onevent.detail - SDK callback:
window.$sitegpt.push(['on', '<event>', fn]), payload passed tofn
JavaScript SDK
Control the widget programmatically
Webhooks
Receive server-side events (leads, messages, escalations)