Cover image for “UTM Capture & Source-of-Truth Setup” showing UTMs flowing from ads to a landing page, then to forms/chat/call, and into the CRM—preserving first and last touch.

UTM Capture & Source-of-Truth Setup

September 19, 20259 min read

Capture first/last touch correctly at the edge so attribution survives reality.


Why last-touch lies (and how to keep first-touch too)

Last-touch is convenient—but it systematically over-credits the final click and hides the work your awareness and mid-funnel campaigns did.

  • Typical failure mode: A prospect discovers you via a YouTube review (first touch), later Googles your brand and clicks a search ad (last touch), then submits a form after a direct visit. If you only store last-touch, search steals credit and video becomes “unprofitable,” so you turn it off—and tank top-of-funnel.

  • Survivorship bias: Cookies expire, privacy settings block referrers, and users switch devices. If you aren’t capturing early touches immediately (and immutably), your “source” becomes (direct)/(none) and your budget migrates to branded or retargeting clicks.

Keep both truths:

  • First touch (FT): The earliest known campaign/channel that earned attention. Treat it as read-only once set.

  • Last touch (LT): The final known campaign/channel that drove the conversion event. Overwrite-permitted.

  • Latest touch (LaT): The most recent non-conversion interaction—useful for sequencing but not for revenue attribution.

  • Multi-touch notes: Lightweight array/log to store meaningful assist events (e.g., “Viewed webinar 2025-09-01; Clicked comparison page 2025-09-08”).

Principle: Write FT once, update LT whenever a qualified session occurs, and append to LaT/Multi-touch as needed.


Edge capture: forms/chat/call-tracking; cookie persistence & fallbacks

Attribution dies in transit. Capture it at the edge—the exact moment a user gives you data or triggers trackable intent.

Where to capture

  • Forms (web & embedded): On submit, serialize UTM and referrer data into hidden fields. Prefer client-side reading of URL params + document.referrer, with server-side validation.

  • Chat widgets: When a new conversation starts or an email/phone is collected, push current UTMs, landing page, and session_id into the chat platform’s custom fields.

  • Call tracking: Use dynamic number insertion (DNI). Assign numbers by channel/campaign or by session. When a call fires, the call record should include UTMs, gclid/fbclid/msclkid, landing URL, and timestamp.

Persistence strategy

  • Storage order of operations:

    1. URL params (truth on the page)

    2. First-party cookies/localStorage (90–180 days)

    3. Server-side session (ties cross-page)

    4. CRM fields (system of record)

  • Cookie horizon: 90–180 days for FT, 30–60 for LT/LaT to avoid stale misattribution.

  • Fallbacks: If UTMs are missing, derive source from referrer (e.g., google / organic), else record (direct)/(none) explicitly with a reason code: missing_params, blocked_referrer, or manual_entry.

Client-side vs server-side tradeoffs

  • Client-side pros: Immediate, no extra infra, easy to enrich forms and chats.

  • Client-side cons: Ad blockers, ITP/ETP, referrer stripping.

  • Server-side pros: Durable, consistent, better PI protection, works with server-side tagging.

  • Server-side cons: Requires infra and mapping between session/user and form/call/chat events.

Recommendation: Hybrid. Capture on the client for survivability; mirror to the server for durability.


Data model: fields, naming, allowed values

Standardize field names so every tool in the chain agrees.

Canonical field map (minimal):

  • ft_source, ft_medium, ft_campaign, ft_term, ft_content

  • lt_source, lt_medium, lt_campaign, lt_term, lt_content

  • landing_page_url, landing_page_path, first_seen_at, last_seen_at

  • session_id, device_type, referrer, referrer_domain

  • gclid, fbclid, msclkid (nullable)

  • latest_touch_json (array of {ts, src, med, cmp, url, note})

Allowed values & normalization

  • source: lowercase vendor or domain root (e.g., google, facebook, linkedin, newsletter, referral).

  • medium: use GA4-compatible set: cpc, organic, email, social, referral, affiliate, display, sms, voice.

  • campaign: yyyy_mm_campaign-theme_objective (e.g., 2025_09_launch_crm-migrations_demo-requests).

  • term/content: free-text but sanitized; use dashes, no spaces; avoid PII.

Write rules

  • FT fields: Write-once per lead/account.

  • LT fields: Overwrite on qualified session (e.g., 30-minute inactivity boundary).

  • Latest touch: append to JSON log with timestamp; cap at N=25 entries to keep payloads small.


Handling “direct/none,” dark social, and offline

(direct)/(none) isn’t always “typed the URL.” It’s often a byproduct of:

  • Dark social: Shares via SMS, iMessage, Slack, or email where referrers are stripped.

    • Mitigation: Add short links with UTMs in share CTAs; embed “Copy Link” buttons that include UTMs. Use channel-specific vanity URLs (e.g., /li/… for LinkedIn) that 302 to UTM’d pages.

  • Untracked offline: QR codes at events, print, podcasts.

    • Mitigation: Unique vanity domains or QR codes per channel and campaign. QR resolves to canonical page with UTMs (e.g., utm_source=event&utm_medium=qr&utm_campaign=vegas_2025).

  • Password manager / app handoff: Mobile app to browser transitions kill referrer.

    • Mitigation: Session pinning via first-party cookie; pass through UTMs on internal links.

Classify direct intelligently

  • If landing_page_path is a deep page (e.g., /pricing/enterprise) and referrer is empty, treat as likely return and preserve FT; do not overwrite FT with direct.

  • Use a reason code field (direct_reason) to support analysis and QA: typed, bookmark, unknown, dark_social, internal_redirect.


QA & reconciliation: ad platform vs CRM

Discrepancies are inevitable. The job is to measure and explain, not to force a false match.

Common gaps

  • Time zone mismatches (ad accounts in UTC, CRM in local).

  • Attribution windows (7-day click vs your 30-day FT cookie).

  • Counting logic (ad platforms report clicks, you report leads/qualified).

QA checklist (weekly)

  1. Parameter completeness: % of leads with ft_source and lt_source present (>95% target).

  2. Value conformity: Sources and mediums within allowed set (>99% valid).

  3. Click-to-lead ratio by channel: Investigate outliers (sudden spikes often = broken forms or bot traffic).

  4. Reason codes: Trend direct_reason to detect instrumentation drift.

  5. Cross-system sanity: Compare CRM leads by source vs platform clicks/impressions (expect correlations, not parity).

Reconciliation approach

  • Build a bridge table keyed on gclid/fbclid/msclkid + timestamp bucket (+ landing path).

  • For unattributed conversions, use probabilistic matching: same IP block + device type + <60-minute delta → candidate match. Mark as inferred, never overwrite canonical FT/LT without evidence.


Reporting views: channel, campaign, creative

Design reports to answer three executive questions: Where do we win? What should we scale? What needs fixing?

Core views

  • FT Contribution by Channel: New leads/opportunities by ft_channel → budget allocation.

  • LT Efficiency by Campaign: Cost per SQL/opp by lt_campaign → optimization focus.

  • Creative/Keyword Lift: SQL rate and win rate by utm_content / utm_term → message-market fit.

  • Journey Overlays: Sankey/flow from FT to LT to Closed/Won → path patterns (e.g., video → branded search → demo).

Practical tips

  • Collapse long-tail values with grouping rules (e.g., map facebook and instagram into meta_paid_social when reporting, but keep raw in storage).

  • Show coverage metrics on every dashboard: % with FT, % with LT, % with valid source/medium.

  • Include QA tiles (e.g., “UTM coverage this week: 97.2%”) beside performance tiles to keep hygiene visible.


Next step: Get the UTM Field Map—a copy-paste schema with FT/LT write rules, normalization, and sample validations you can import into your CRM and data warehouse today.


Show-Rate Engine (Confirm & Rescue)

Category: Demand Generation & Pipeline Growth
Slug: show-rate-engine-confirm-rescue
Thesis: Lift kept appointments with sequences that set expectations, reduce friction, and rescue no-shows.
CTA: Copy the Show-Rate Sequence


The math of show rate → CPA-kept

You don’t buy leads—you buy kept appointments. The only CPA that matters is CPA-kept.

  • Definitions:

    • Booked = someone chose a slot

    • Kept = they actually showed

  • Formula:

    • Show Rate = Kept / Booked

    • CPA-Kept = (Spend ÷ Kept)

    • Small lifts compound: raising show rate from 55% → 70% reduces CPA-Kept by ~21% at the same spend.

Treat show rate as a product problem: clarity, convenience, and commitment.


Confirmation blueprint (timing, channels, content)

Timing (minutes relative to booking)

  • +0 min: On-page confirmation + calendar file (ICS) + clear next step.

  • +1 min (Email): Subject: “You’re confirmed for {Date @ Time} — here’s what to expect.”

  • +5 min (SMS): “Saved your spot. Reply ‘HELP’ for questions.”

  • +60 min (Optional SMS/WhatsApp, high-intent offers): Social proof + prep checklist.

Channels

  • Email carries detail (agenda, prep, links).

  • SMS carries commitment and logistics (time, reschedule link, address/Zoom).

  • Voice (optional for high-ticket): brief voicemail confirming slot, call-back number.

Content

  • Expectation set: “We’ll spend 20 minutes confirming fit. No hard pitch. If it’s not a match, we’ll point you elsewhere.”

  • Value frame: “We’ll calculate your break-even CAC in the first 5 minutes.”

  • Reschedule path: One-click link with guardrails (24-hour window) to reduce last-second flakes.

  • Prep snippet: “Have your current metrics handy: MQLs/mo, show rate, close rate.”


Reminders & prep (calendar/ICS, FAQs, friction removal)

Calendar mechanics

  • Always attach ICS and inject Google/Outlook add-to-calendar links. Title format: Brand | Topic | {Rep}. Include Zoom/Meet deep link.

Reminder schedule (tune by audience)

  • T-24h Email: Agenda + prep + reschedule link.

  • T-3h SMS: “Still good for {Time}? Reply YES to confirm; RESCHED to pick a new time.”

  • T-30m SMS: Parking/Zoom quick link + “Reply ‘HELP’ if you’re running late.”

  • T-5m SMS (optional): “We’re ready when you are.”

Friction removal

  • Micro-FAQ: “What we’ll cover,” “How to prepare,” “Tech check,” “Rescheduling policy.”

  • One-tap reschedule: Prevents full no-shows by converting them into kept-later.

  • Device fit: Test reminder links on iOS/Android/desktop; shorten URLs.


No-show rescue: rapid re-book and credibility assets

When someone misses, the clock is ticking. Aim to re-book within 24–48 hours.

Immediate sequence

  • T+10m SMS: “Missed you—life happens. Grab a new time here: {smart-link}. Need help? Reply.”

  • T+2h Email: Case study (same ICP), a 60-second explainer, and the re-book link.

  • T+24h SMS: “Still holding your spot this week—want {Wed 2:30p} or {Thu 10:00a}?”

Credibility assets to include

  • 1-pager PDF or short deck (“What to expect + outcomes”).

  • 60-second video from the AE/consultant.

  • “Before/after” metric snapshot (e.g., show rate +20%, CPA-kept −18%).

  • Third-party proof (reviews, G2, testimonials).

Operational guardrails

  • Tag no-shows and auto-throttle ad delivery for that user for 7 days to avoid chasing ghosts.

  • If they no-show twice, route to asynchronous discovery (form or Loom Q&A) before granting a third live slot.


Capacity-aware throttling (don’t overbook)

Nothing kills show rate like limited availability and harried reps.

  • Calendar supply management:

    • Set daily caps per rep (e.g., 6 meetings/day).

    • Buffer times (10–15 minutes) between calls to prevent cascading delays.

    • Time-of-day windows matched to audience (e.g., SMB owners evenings; enterprise mid-morning).

  • Smart distribution:

    • Round-robin with skills/vertical routing.

    • Pause inbound calendars when show-adjusted load exceeds target (e.g., scheduled × expected show rate > capacity).

  • Lead scoring interlock:

    • Only show prime slots to qualified leads; others see next-week availability or async options.


Measurement & experiments

Make show rate a first-class KPI and run weekly experiments.

Core metrics

  • Show Rate (by source, offer, rep, time-of-day).

  • Reschedule Rate (saves vs full no-shows).

  • Time-to-meeting (booking → kept).

  • CPA-Kept and Revenue per Kept (downstream).

Experiment ideas

  • Subject line & SMS copy tests: Clarity vs urgency; include {Rep Name} vs not.

  • Reminder cadence: Compare T-24h/T-3h/T-30m vs lighter sequences.

  • Asset inclusion: Add/remove the 60-sec explainer to the T-24h email.

  • Time windows: Offer earlier/later slots for different segments.

  • Two-way confirmation: Requiring “YES” at T-3h can raise show rate but reduce volume—measure both sides.

Attribution

  • Store confirmation_sequence_version and reminder_cadence on the appointment record. Tie kept outcomes back to sequence versions so you can ship changes with confidence.


Next step: Copy the Show-Rate Sequence—prebuilt emails/SMS, ICS settings, and a re-book play that reliably lifts kept appointments without burning rep capacity.

David Leathers is a fractional CMO and AI developer behind Dependable Consulting. He helps teams architect GoHighLevel for revenue: opinionated data models, attribution that reconciles, and automations that don’t break. His work spans demand gen, paid media economics, CRO, compliance/consent (TCPA/A2P), and partner/affiliate programs. Practical, transparent, and metrics-driven—he prefers kept appointments and payback windows over vanity stats.

David Leathers

David Leathers is a fractional CMO and AI developer behind Dependable Consulting. He helps teams architect GoHighLevel for revenue: opinionated data models, attribution that reconciles, and automations that don’t break. His work spans demand gen, paid media economics, CRO, compliance/consent (TCPA/A2P), and partner/affiliate programs. Practical, transparent, and metrics-driven—he prefers kept appointments and payback windows over vanity stats.

Back to Blog