UTM tracking in Customer Insights – Journeys + Static CSV segment uploads
Praxisis D365 Wiki · Public reference · Client-specific details redacted
Source: Claude.ai chat (original: wait-time-tile-90-day-limit__00914bc4.md)
Added: 2026-10-02
Summary
- UTM parameters (
utm_source,utm_medium,utm_campaign,utm_content,utm_term) are a Google Analytics convention, not a Microsoft thing. Nothing in D365 reads them back — they exist so your web analytics can attribute a session. - Enable in CIJ: Settings → Feature switches → UTM Tracking (on) · Settings → Customer engagement → UTM tracking (create one mapping record per business unit).
- UTM insertion is gated by tracking consent. If Compliance Settings consent model is Restrictive and tracking-consent-from-customers is on, the contact must have explicitly opted in before tracking links go in — without consent, UTM codes are not inserted at all. Separate from email/SMS marketing consent.
Key takeaways
- Default UTM mapping:
utm_source= static text you set ·utm_campaign= journey Name ·utm_medium= channel (email/sms) ·utm_content= message name ·utm_term= not populated. - One UTM record per business unit max.
- "Fixing missing UTMs" by flipping to non-restrictive is a privacy-policy decision, not a settings decision — it quietly turns on behavioural tracking for everyone. Flag to the client before anyone touches that toggle.
- UTM tagging is distinct from D365's own link tracking (the
marketingusercontent.comredirect links that feed journey analytics). Configured independently and can be consented differently. - UTM = Urchin Tracking Module (legacy name; Google acquired Urchin Software in 2005, parameter convention stuck).
Static CSV segment uploads
- No feature switch — it's generally available but not where people look first. Two typical misses:
- The segment must be saved before you can add static members.
- Elements pane → Contacts tab is the search-by-name path (capped at 100 members). CSV upload lives at + Add a new group dropdown → inclusion/exclusion group → Upload CSV. Drag-and-drop onto the segment canvas also works.
- CSV format: must have a header column
emailaddress1with addresses to match against existing Dataverse records. Email-only matching — no documented GUID / alternate-key option. - The header is the Dataverse logical name, not a friendly label —
Email,Email Address,EMAILADDRESS1may not be picked up. Test with a 2-row file before a 200K-row upload. - Duplicate emails fan out: three contacts sharing an address = one CSV row brings in all three. Rows with no match go to a "Not found" bucket you can push into Dataverse via standard contact/lead CSV upload and re-run.
- Limits: 200,000 members per static group, max 10 groups → 2,000,000 ceiling. Static + dynamic criteria can coexist in one segment. Exclusion beats inclusion.
- Business-unit scoping differs between static and dynamic: static snapshot only matches contacts the author can see under their BU/team scope. Dynamic query pulls all matching records at run time regardless of author's BU. A static CSV list built by a BU-scoped user will silently come back short.
- No email, bulk size → use the segment builder API (anything the UI does is programmable) rather than hand-building email CSVs. The API path is far less painful when source is a GUID list or alternate key output from an existing data pipeline.
- Manual Select members uses the Dataverse grid — fine for tens or hundreds, limited by browser cache, not for bulk.
Learnings / how to apply
- "UTM depends on tracking consent" is a mandatory section of any CIJ consent-model handover doc — otherwise clients blame Google Analytics for "missing data" that is correctly suppressed by their own compliance setting.
- Standard flow for nonprofit segment uploads: generate a GUID + email staging table → either (a) use emails for CIJ CSV upload (fan-out risk) or (b) use the segment API with GUIDs (safer for exact-cohort targeting). Document which path per client.
- Pre-flight "test CSV header literally spells
emailaddress1" is a one-line checklist item that prevents a 200K-row upload failure.
Need this applied to your own tenant?
Praxisis Sustain Self-Serve builds a private AI Wiki trained on your documents and tickets, with free Tier-2 support when the AI cannot answer. Book a 30-min overview.