UTM Convention — Paid Ads (Google Ads first)
Status: Active · Created: 2026-06-11 (ads-tracking prerequisites, churchwiseai-web PR feat/ads-tracking-prereqs)
Owner: founder · Applies to: every paid-ad destination URL across all properties.
The convention
Every ad's final URL MUST carry these parameters (lowercase, hyphen-separated values):
| Param | Value | Rule |
|---|---|---|
utm_source | google | The platform: google, meta, bing, … |
utm_medium | cpc | Always cpc for paid search/social ads |
utm_campaign | voice-launch-{adgroup} | {campaign-name}-{adgroup}, e.g. voice-launch-pastors, voice-launch-missed-calls |
utm_term | (optional) | Keyword/audience, when useful |
utm_content | (optional) | Ad variant id for A/B, e.g. ad-a |
Example destination URL:
https://churchwiseai.com/voice?utm_source=google&utm_medium=cpc&utm_campaign=voice-launch-pastors
Google Ads auto-appends gclid (and wbraid/gbraid); Meta appends fbclid. Do NOT add them manually. Auto-tagging must stay ON in Google Ads.
Why this exact shape matters (the plumbing that consumes it)
- Capture —
<AttributionCapture />(churchwiseai-websrc/components/AttributionCapture.tsx) writesutm_*+ click IDs into thecwa_attr_first/cwa_attr_lastcookies (90 days, first touch never overwritten, last touch always). - Checkout stamping — all 7 checkout-creation routes snapshot both cookies into Stripe session metadata (
attr_first/attr_last, ≤500 chars each) viasrc/lib/growth/attribution-stripe.ts. - Conversion — the Stripe webhook inbox processor reads that metadata on
checkout.session.completed: persists the buyer toleads(origin_source='checkout',first_touch/last_touchjsonb), fires the GA4 Measurement Protocolpurchase(transaction_id = Stripe event id), and fans out to Meta CAPI / Google Ads viareportAdConversion()(src/lib/growth/checkout-conversion.ts). - Reporting — GA4 campaign reports group by
utm_campaign; the Growth Command Center (/founder/[token]/growth) readsleads.first_touch/last_touch. A campaign value that doesn't follow{campaign}-{adgroup}shows up as noise in both.
GA4 key events (mark as Key Events in GA4 Admin)
| Event | Fired when | Where |
|---|---|---|
demo_call_click | demo tel: link tapped | /voice, /pricing FAQ, /demo |
begin_checkout | checkout form opens/submits | /onboard checkout + upgrade, funeral + vet checkouts |
generate_lead | contact/demo/ROI form succeeds | /contact, wiseaiagency contact, vet book, ROI calculator |
purchase | Stripe checkout completes (server-side MP) | webhook inbox processor |
Operational rules
- New campaign names are kebab-case:
{product}-{theme}, e.g.voice-launch,prowebsite-spring. Ad-group suffix appended by the ads platform tracking template or by hand. - Never send paid traffic to a URL without the three required params — the click is then unattributable and pollutes organic CAC math.
- Landing pages must NOT be Pro Website customer surfaces (
/s/,/p/,/preview/,*.john316.church) — analytics are gated off there by design. - Env prerequisites before first spend:
GA4_API_SECRET(GA4 server purchase),META_PIXEL_ID+META_CAPI_ACCESS_TOKEN(Meta CAPI),GOOGLE_ADS_*(offline click conversion upload — stub until provisioned). All no-op gracefully when absent.