Introduction

This article is the third step in tracking setup. Complete the Add Google Tag Manager and How to Record Conversions using GTM first.

How it works

  • GA4 owns campaign data. GA4 captures UTM parameters and handles attribution. EnrolHQ does not store UTMs.
  • EnrolHQ tells GA4 who converted. JavaScript hooks fire on each success event (enquiry, booking, application, payment) and carry a unique student ID.
  • The student ID joins the two. Matching GA4 campaign data with the student's enrolment outcome in EnrolHQ shows which campaigns produced enrolments.

Capturing UTM parameters

EnrolHQ leaves campaign tracking to Google Analytics by design. Google's attribution models are far more capable than a built-in alternative.

  1. Open Custom Scripts in EnrolHQ.
  2. Add the school's GTM container, with GA4 and Meta tags inside it.
  3. GA4 captures source, medium, campaign, content and term for every session on EnrolHQ-hosted pages.

Important: if the EnrolHQ site sits on a different domain from the school website, set up GA4 cross-domain measurement between the two. Without it, GA4 starts a new session when a carer clicks through to EnrolHQ and credits the enquiry to the school website as a referral instead of the original campaign.

Sending the student ID to GA4

EnrolHQ's JavaScript hooks fire on each success event and carry a unique student ID (student_profile_id). Send that ID to GA4 with the event to link GA4's campaign data to the student's record and enrolment outcome in EnrolHQ.
// Helper: pushes an event to the dataLayer.
// All ad platform tags (GA4, Meta, etc.) are managed in GTM.
function enrolHQPush(eventName, params) {
  window.dataLayer = window.dataLayer || [];
  var payload = { event: eventName, page_location: window.location.href };
  if (params) {
    for (var key in params) {
      if (Object.prototype.hasOwnProperty.call(params, key)) {
        payload[key] = params[key];
      }
    }
  }
  window.dataLayer.push(payload);
}

// Fires when an application for enrolment is submitted
function enrolHQOnEnrolmentSubmitSuccess(payload) {
  enrolHQPush('application_submit', {
    student_profile_id: payload && payload.studentProfileId
  });
}

The EnrolHQ team is happy to walk schools through wiring up the rest.

Attribution models

Attribution happens in GA4, and in Meta and Google Ads for their own reporting. GA4 offers data-driven and last-click attribution. EnrolHQ does not run its own attribution model.

Connecting campaigns to enrolment outcomes

Join the two systems on the student ID:

GA4 EnrolHQ Result
Campaign and student_profile_id for each enquiry, booking and application event. Each student's progress through the enrolment journey, via the EnrolHQ API. Which campaigns produced enquiries, applications and accepted offers.
  1. Push student_profile_id to GA4 with each event using the hooks in this article.
  2. Register student_profile_id as a custom dimension in GA4.
  3. Look up each student's progress through the EnrolHQ API.
  4. Combine the two in a spreadsheet or a reporting tool such as Looker Studio.

Reporting on the full enrolment journey

The Student Profile Conversion report (under Reports) tracks students through configurable stages:

  • Enquiry Submitted.
  • Event/Tour Booked, Attended, Not Attended.
  • Application Submitted (and paid).
  • Interview Booked and Completed.
  • Offer Made.
  • Offer Accepted.
  • Declined / Not Proceeding.

Filter by year of entry, event and other criteria, then export.

Recommended conversion events

EnrolHQ exposes named JavaScript hooks that fire at each meaningful step. Implement them in the school's custom code block, push dataLayer events from inside them, then build GTM triggers on those event names.

Action EnrolHQ hook Payload Suggested event name Meta event
Primary conversions (optimise campaigns on these)
Enquiry submitted enrolHQOnEnquirySubmitSuccess enquiries: [{ id, studentProfileId }] enquiry_submit Lead
Tour/event booking confirmed enrolHQOnBookingConfirmation bookingId, eventId, sessionId, studentProfileIds[] event_booking Schedule
Application submitted enrolHQOnEnrolmentSubmitSuccess studentProfileId application_submit SubmitApplication
Outcome conversion (ROI reporting)
Offer accepted enrolHQInitPaymentSuccess
(paymentKind enr-a)
studentProfileId, paymentId, paymentKind, amount offer_accepted –
Conversions with value
Application fee paid enrolHQInitPaymentSuccess
(other kinds, e.g. enr-f)
studentProfileId, paymentId, paymentKind, amount application_payment –
Secondary conversions
Scholarship/EOI submitted enrolHQOnEOISubmitSuccess studentProfileId scholarship_submit –
Custom Form submitted enrolHQOnCustomFormSubmitSuccess studentProfileId, customFormId, customFormKind, customFormSlug, formSubmitId custom_form_submit –

Page view hooks

Use these for audiences and funnel drop-off, not conversions.

Page EnrolHQ hook Payload
All pages enrolHQInitAlways() None.
Enquiry page enrolHQInitEnquiry() None.
Event list/details enrolHQInitEventList()
enrolHQInitEventDetails()
None.
Enrolment page enrolHQInitEnrolment() None.
Enrolment Dashboard enrolHQInitParentDashboard() None.

Example: enquiry submitted

function enrolHQOnEnquirySubmitSuccess(payload) {
  var enquiries = (payload && payload.enquiries) || [];
  var enquiryIds = enquiries.map(function (e) { return e.id; });
  var studentIds = enquiries.map(function (e) { return e.studentProfileId; });
 
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'enquiry_submit',
    enquiry_ids: enquiryIds.join(','),
    student_profile_ids: studentIds.join(',')
  });
}

Sending accepted offers to Meta and Google Ads

When a carer pays the enrolment acceptance fee online, the payment success hook fires. Push it to the dataLayer as offer_accepted with the amount paid, and GTM sends it to GA4, Meta and Google Ads as a conversion. Add the following to EnrolHQ's Custom Scripts:

<script>
function enrolHQInitPaymentSuccess(payload) {
  if (!payload || !payload.paymentId) return;
 
  // The payment success page shows again if the carer revisits it,
  // so only send each payment once.
  var sentKey = 'enrolhq_payment_sent_' + payload.paymentId;
  try {
    if (window.localStorage.getItem(sentKey)) return;
    window.localStorage.setItem(sentKey, '1');
  } catch (e) {}
 
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: payload.paymentKind === 'enr-a' ? 'offer_accepted' : 'application_payment',
    student_profile_id: payload.studentProfileId,
    payment_id: payload.paymentId,
    payment_kind: payload.paymentKind,
    value: payload.amount,
    currency: 'AUD'
  });
}
</script>

Things to know:

  • The event fires only when the acceptance fee is paid online by card. Offers accepted offline or marked as accepted by school staff do not trigger it.
  • Carers often accept weeks or months after enquiring, usually from an offer email. GA4 credits that session to email or direct, and ad platforms credit it only inside their click window. Use the student ID join to find the original campaign.
  • Accepted offers are low-volume and arrive late, which makes them ideal for ROI reporting but too sparse for bid optimisation. Optimise campaigns on enquiries and tour bookings, and measure ROI on accepted offers.

Best-practice setup

  • Use GA4-style snake_case in an object_action pattern (e.g. enquiry_submit). Title_Snake_Case (e.g. Enquiry_Form_Submission) also works if applied consistently.
  • Keep parameter names consistent across events: student_profile_id, enquiry_id, booking_id, event_id, payment_id, payment_kind, value, currency.
  • Push one dataLayer event per hook and handle platform mapping in GTM. For example, enquiry_submit triggers GA4 generate_lead, Meta Lead and a Google Ads conversion.
  • Map to each platform's standard events. Platforms optimise better on standard events than custom names.
  • Mark only primary events as conversions/key events in GA4 and Google Ads. Secondary events and page views dilute bidding.
  • Use paymentId as the de-duplication ID (transaction_id in GA4 and Google Ads, eventID in Meta).
  • Never push names, emails or phone numbers into the dataLayer. Fetch them server-side through the EnrolHQ API using studentProfileId if ad-platform matching needs them.

Last reviewed: 1 October 2026