EnrolHQ works alongside Google Analytics 4 (GA4), Google Tag Manager (GTM), Meta and Google Ads so schools can see which campaigns produce real enrolments, not just clicks.
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.
- Open Custom Scripts in EnrolHQ.
- Add the school's GTM container, with GA4 and Meta tags inside it.
- 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
(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. |
- Push
student_profile_idto GA4 with each event using the hooks in this article. - Register
student_profile_idas a custom dimension in GA4. - Look up each student's progress through the EnrolHQ API.
- 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_submittriggers GA4generate_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
paymentIdas the de-duplication ID (transaction_idin GA4 and Google Ads,eventIDin Meta). - Never push names, emails or phone numbers into the dataLayer. Fetch them server-side through the EnrolHQ API using
studentProfileIdif ad-platform matching needs them.
Last reviewed: 1 October 2026