Embed SDK
Available on all plans

Widget JavaScript Events

Every action a user takes inside the booking widget fires a typed JavaScript event. Listen with window.ConsultGen.on() for a global bus, or with element.addEventListener() when you have multiple widgets on the page.

Quick start - add this before widget.js

<!-- Add this BEFORE widget.js loads so no events are missed -->
<script>
  window.ConsultGen = window.ConsultGen || {
    _q: [],
    on: function (event, fn) { this._q.push([event, fn]) },
  }
</script>
<script src="https://cdn.consultgen.app/widget.js" async></script>

Why the stub? The pre-stub queues any on() calls made before widget.js has finished loading. The SDK drains the queue on init so no events are missed.

2 widget lifecycle events
4 booking funnel events
1 contact & identity event
3 payments events

Widget Lifecycle

Booking Funnel

Contact & Identity

Payments

AI Assistant Webhooks

These server-to-server events are made for AI Receptionist and Smart Inbox Pro workflows. They help you wake up a CRM, notify your team, or close the loop automatically without depending on browser-side JavaScript.

Delivery headers

X-ConsultGen-Event: enquiry.created | chat.resolved
X-ConsultGen-Signature: <hex hmac sha256 signature>
Content-Type: application/json

Verify the signature

import crypto from 'node:crypto'

export function verifyConsultGenSignature(rawBody, signatureHeader, webhookSecret) {
  const expected = crypto
    .createHmac('sha256', webhookSecret)
    .update(rawBody, 'utf8')
    .digest('hex')

  return crypto.timingSafeEqual(
    Buffer.from(expected, 'utf8'),
    Buffer.from(signatureHeader || '', 'utf8'),
  )
}
AI Assistant webhook
enquiry.created

Sent when the AI Assistant captures a handover enquiry and pushes the visitor into human follow-up.

When it fires

This fires after the visitor submits their details for sales or support handover.

Why it matters

Use it to create or update a lead in your CRM, notify a human agent quickly, or kick off a fast welcome sequence while intent is still hot.

Payload

FieldTypeDescription
data.enquiry_idstringThe saved enquiry UUID.
data.session_idstringThe related chat session UUID.
data.crm_contact_idstring | nullCRM contact UUID if one was linked.
data.enquiry_kind'general' | 'specialist' | 'purchase'The kind of handover the assistant classified.
data.namestringVisitor name from the handover form.
data.emailstringVisitor email address.
data.phonestring | nullVisitor phone number if supplied.
data.companystring | nullVisitor company if supplied.
{
  "event": "enquiry.created",
  "organization_id": "org_uuid",
  "occurred_at": "2026-07-28T09:08:57.192Z",
  "data": {
    "enquiry_id": "enquiry_uuid",
    "session_id": "session_uuid",
    "crm_contact_id": "contact_uuid",
    "enquiry_kind": "purchase",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "phone": "+27 82 555 0101",
    "company": "Acme Studio"
  }
}
AI Assistant webhook
chat.resolved

Sent when a chat is closed, whether that happens from the staff side or when the visitor ends the conversation.

When it fires

This fires once the chat session is moved into a resolved state and the final visitor rating, if any, has been saved.

Why it matters

Use it to close tickets, move a CRM contact into a resolved stage, trigger a follow-up survey, or measure how many chats ended on a strong note.

Payload

FieldTypeDescription
data.session_idstringThe resolved chat session UUID.
data.scope'marketing' | 'support'Which queue the conversation belonged to.
data.visitor_ratingnumber | nullThe final visitor rating when feedback was submitted.
{
  "event": "chat.resolved",
  "organization_id": "org_uuid",
  "occurred_at": "2026-07-28T09:08:57.192Z",
  "data": {
    "session_id": "session_uuid",
    "scope": "marketing",
    "visitor_rating": 5
  }
}

Support pulse (live account answers)

Support pulse lets the AI Receptionist Support chat answer signed-in customers with live figures from your app. When a visitor asks a metric-style question, ConsultGen calls your HTTPS pulse URL with that visitor’s token and uses the JSON as context. Sales chats never call pulse, and if the request fails the assistant says live data is unavailable instead of guessing. Enable it under Settings → Growth Modules → AI Receptionist → Support pulse.

Expose the auth bridge

// On pages that embed the Support chat (data-scope="support")
window.ConsultGenChatAuth = {
  getCredentials: async () => ({
    accessToken: await getSessionAccessToken(), // your app's signed-in user token
    orgId: getActiveOrgId(),                     // optional
    userId: getCurrentUserId(),                  // optional
  }),
}

Request ConsultGen sends

GET https://your-app.com/api/support/pulse
Authorization: Bearer <accessToken>
x-org-id: <orgId>
Accept: application/json

// Respond with JSON for that user only, e.g.
{ "ok": true, "scheduledPosts": 12, "connected": true }