Web Widgets

Events

Every event the OnePath widgets fire on document, with the exact payload, and the one event you dispatch yourself.

document.addEventListener('onepath:webscheduler:appointment_created', (e) => {
  const { customer, location, time, timezone } = e.detail;
  // your analytics call here
});

All events are CustomEvents on document; read the payload from e.detail. Attach listeners at any time before the event fires, for example in a script in the head right after the loader. Names and payload shapes are stable; new optional fields may be added.

EventFires when
onepath:config-readyThe account configuration has loaded (once per page load)
onepath:widget-readyThe scheduler has opened for the first time and authenticated
onepath:webscheduler:appointment_createdA visitor booked an appointment
onepath:webscheduler:task_createdA visitor asked for a call back instead of a slot
onepath:webchat:request_createdA visitor submitted the chat (text me back) form
onepath:webscheduler:openYou dispatch this to open the scheduler

Booking events need a service address

appointment_created and task_created fire only when the visitor got past the address step, so a service address is always present in the payload. A visitor who leaves on step 1 fires nothing.

Events you listen for

onepath:config-ready

Fires once, as soon as the loader has the account's public configuration and before any widget script loads. Use it to read the brand color or business name, or to check which widgets are enabled before rendering your own buttons.

document.addEventListener('onepath:config-ready', (e) => {
  const { account, channels } = e.detail;
  console.log(account.name);                    // "Wahoo Plumbing"
  console.log(account.brand_color);             // "#004993"
  console.log(channels.web_scheduler.enabled);  // true / false
  console.log(channels.web_chat.enabled);       // true / false
  console.log(channels.web_mcp.enabled);        // true / false, booking by AI agents
});

e.detail:

  • account: name, slug, brand_color, text_color, phone, full_address, logo (URL)
  • channels: web_scheduler.enabled, web_chat.enabled, web_mcp.enabled, telling you which widgets are enabled (web_mcp is booking by AI agents)

The same object is available afterwards as window.onepath.config.

onepath:widget-ready

Fires once, after the scheduler has been opened for the first time and has authenticated with OnePath. It does not fire on page load, and the chat widget never fires it. Do not gate your trigger buttons on it; they work as soon as the loader has run.

document.addEventListener('onepath:widget-ready', (e) => {
  if (e.detail.name === 'scheduler') {
    // the scheduler modal is open and talking to OnePath
  }
});

e.detail: name (always "scheduler"), config (the account configuration above).

onepath:webscheduler:appointment_created

Fires once when a visitor books an appointment. It does not fire again if they cancel from the confirmation screen. Wire it to conversion tracking or a post-booking redirect.

document.addEventListener('onepath:webscheduler:appointment_created', (e) => {
  const { customer, location, time, timezone } = e.detail;
});

e.detail:

{
  "customer": {
    "full_name": "Jane Homeowner",
    "contacts": { "email": "jane@example.com", "phone": "+15125550100" }
  },
  "location": { "address": "2100 Barton Springs Rd, Austin, TX 78704" },
  "time": "2026-07-22T19:00:00.000Z",
  "timezone": "-05:00"
}
  • time: ISO 8601 string of the start of the booked window, in UTC
  • timezone: the UTC offset of that window as a string, for example "-05:00", or null. It is not an IANA zone name
  • customer.contacts.phone: E.164 format; email may be empty when the visitor did not give one
  • source: present only when an AI agent booked through the WebMCP tools, with the value "web_mcp". Scheduler bookings carry no source

onepath:webscheduler:task_created

Fires once when a visitor uses Need it sooner? Request Call Back instead of picking a slot. A lead with a service address exists; no appointment does.

document.addEventListener('onepath:webscheduler:task_created', (e) => {
  const { customer, location } = e.detail;
});

e.detail: customer (same shape as above) and location.address. No time or timezone.

onepath:webchat:request_created

Fires once when the chat form is submitted successfully.

document.addEventListener('onepath:webchat:request_created', (e) => {
  const { customer } = e.detail;   // full_name, contacts.email, contacts.phone
});

e.detail: customer.full_name, customer.contacts.email, customer.contacts.phone (E.164). No location.

Events you dispatch

onepath:webscheduler:open

Opens the scheduler from your own code, optionally pre-filling the visitor and pre-selecting the service. Full pattern: Open the scheduler from a form submit.

document.dispatchEvent(new CustomEvent('onepath:webscheduler:open', {
  detail: {
    phone:            '5125550100',
    name:             'Jane Homeowner',
    email:            'jane@example.com',
    address:          '2100 Barton Springs Rd, Austin, TX',
    serviceable_type: 'Water Heater',
    service_type:     'Estimate',
    context:          'Better Package — 50 Gallon — $2,695'
  }
}));

All fields are optional. An empty detail just opens the modal.

FieldBehavior
phoneApplied only with at least 10 digits; shorter values are ignored. Looked up immediately, like a typed number
nameFull name, first and last (Jane Homeowner). A customer already on file for that phone keeps the name on file
emailPre-fills the email on the address step. Never required
addressSeeds the address field; the visitor confirms a suggestion
serviceable_typePre-selects the service (Water Heater). Must match the account's Services exactly, or it is ignored
service_typeNarrows the pre-selection (Estimate, Repair)
contextFree text saved verbatim on the booking; not shown to the visitor. There is no notes field

The event is queued if the scheduler is still loading, but lost if dispatched before loader.js has run. If the scheduler is disabled on the account, the event is dropped with a warning in the console. Exact serviceable_type / service_type values are on the Services page: app.onepath.ai/settings/account/service_details.

Google Tag Manager

Push each event into the data layer, then build GTM triggers on the event names.

<script>
  window.dataLayer = window.dataLayer || [];
  ['onepath:webscheduler:appointment_created',
   'onepath:webscheduler:task_created',
   'onepath:webchat:request_created'].forEach((name) => {
    document.addEventListener(name, (e) => {
      window.dataLayer.push({
        event:            name.replace(/[:]/g, '_'),   // e.g. onepath_webscheduler_appointment_created
        appointment_time: e.detail.time || null,
        service_address:  e.detail.location ? e.detail.location.address : null,
      });
    });
  });
</script>

In GTM, create a Custom Event trigger named onepath_webscheduler_appointment_created and attach your conversion tag to it. Keep customer names, phones and emails out of the data layer unless your privacy policy covers it.

Google Analytics 4 (gtag)

document.addEventListener('onepath:webscheduler:appointment_created', (e) => {
  gtag('event', 'appointment_booked', {
    appointment_time: e.detail.time,
    timezone:         e.detail.timezone,
  });
});

document.addEventListener('onepath:webscheduler:task_created', () => {
  gtag('event', 'callback_requested');
});

document.addEventListener('onepath:webchat:request_created', () => {
  gtag('event', 'text_back_requested');
});

Mark appointment_booked as a conversion in GA4. For server-side data (the appointment's service, the full customer record, cancellations and reschedules), use webhook events instead; browser events only cover what happens in the widget.

Previous
Booking by AI agents