Analistable

How to merge email campaign results with GA4 conversions

By the Analistable team · Updated · 6 min read

Make sure every email link carries utm_source, utm_medium=email and a utm_campaign that identifies the send. Export campaign stats from your email platform and a GA4 report of sessions, key events and revenue by session campaign, normalise the campaign values, then join on them. You get sends, clicks, sessions and conversions on one row per email.

Part of our guide: How to answer questions across multiple spreadsheets

Why the two sides need joining

Your email platform (Mailchimp, Klaviyo, Brevo and similar) knows who received and clicked each email. GA4 knows what those visitors did on the site. Neither knows both. The email platform's own revenue figures, where it has them, use its own attribution rules; GA4's use GA4's. Joining them on the campaign shows the full path — 20,000 sent, 600 clicked, 540 sessions, 27 purchases — and makes the gaps between steps visible.

Tag the links consistently

The join key is utm_campaign. Many email platforms can add UTM parameters automatically when you enable Google Analytics link tracking, often using the campaign name or a slug of it. Check what yours writes by clicking a link in a test send and reading the URL. A reliable convention:

UTM convention for email
parametervalueexample
utm_sourceyour platform or listnewsletter
utm_mediumalways emailemail
utm_campaigndate + short name2026-09-17_autumn_sale
utm_contentlink position (optional)hero_button

Put the send date in the campaign value. Without it, “autumn_sale” from this year and last year merge into one row.

What to export

  • Email platform: one row per campaign with campaign name (or the UTM value if the export includes it), send date, recipients, opens, unique clicks, unsubscribes.
  • GA4: an Exploration (free form) with Session campaign, Session source / medium as dimensions and Sessions, Key events and Total revenue as metrics, filtered to Session medium = email. Use the same date range as the sends, plus a few days after the last send for late clicks.

GA4 renamed “conversions” to “key events” in 2024, so older guides and exports may use either name. Analistable can also pull GA4 directly through its Google Analytics connection, which fetches the report on the server and loads the rows into your browser — useful when you'd rather not rebuild the Exploration each month.

Opens are unreliable since Apple Mail Privacy Protection began preloading images, which inflates open counts. Use clicks as the email-side engagement metric when joining to GA4.

Normalise and join

GA4 records utm_campaign as sent; the email export may hold the human campaign name. If they differ, build a small mapping table, or, if your platform generated the UTM from the name, reproduce its rule (lowercase, spaces to underscores). Then join:

SELECT e.campaign_key, e.recipients, e.unique_clicks,
       g.sessions, g.key_events, g.revenue,
       g.sessions * 1.0 / NULLIF(e.unique_clicks, 0) AS sessions_per_click,
       g.key_events * 1.0 / NULLIF(g.sessions, 0) AS conversion_rate
FROM (
  SELECT LOWER(TRIM(utm_campaign)) AS campaign_key, recipients, unique_clicks
  FROM email_campaigns
) e
LEFT JOIN (
  SELECT LOWER(TRIM("Session campaign")) AS campaign_key,
         SUM("Sessions") AS sessions, SUM("Key events") AS key_events,
         SUM("Total revenue") AS revenue
  FROM ga4_email
  GROUP BY 1
) g ON g.campaign_key = e.campaign_key
ORDER BY revenue DESC NULLS LAST;

Worked example: September sends

Email platform joined to GA4, September 2026
campaignrecipientsunique clicksGA4 sessionskey eventsrevenue
2026-09-03_new_range20000600540271620
2026-09-17_autumn_sale20000900810543780
2026-09-24_how_to_guide198004504058360
Total5980019501755895760

The autumn sale converted 54 / 810 = 6.7% of sessions; the guide converted 8 / 405 = 2.0%, which is fine for a content email but means it shouldn't be judged on revenue. Across the month, 1,755 sessions from 1,950 unique clicks is a 90% click-to-session rate. A much lower rate on one campaign usually means broken tags, a redirect stripping UTMs, or consent-banner losses.

Common problems

  • Campaign shows in GA4 as (not set) or (direct): UTMs were stripped by a redirect or link shortener, or the visitor declined analytics cookies.
  • Revenue appears weeks later: GA4 attributes key events by its attribution model, and a returning visitor may convert days after the email session. Pick one date basis and stick to it.
  • Same campaign value used twice: resends to non-openers often reuse the original UTM. Add a suffix (_resend) if you want them separated.

For GA4 combined with other Google data, see combining Google Analytics and Search Console data and merging GA4 with ad cost data. The cross-spreadsheet guide covers more question types.

Choose the right GA4 dimension

GA4 has several campaign dimensions with different scopes, and choosing the wrong one changes the numbers:

GA4 campaign dimensions
DimensionScopeUse it for
Session campaignThe sessionTraffic and conversions in the session the email started
First user campaignThe user's first visitNew users acquired by an email
Campaign (event scope)The key eventConversions credited by GA4's attribution model

For a per-send report, Session campaign is usually the right choice: it answers “what did people do in the visit that started from this email?”. Event-scoped campaign uses GA4's attribution model, so a purchase can be credited to an email even when the buying session came from somewhere else. Neither is wrong, but mixing them across months makes trends meaningless. Name the dimension in the report title.

If GA4 reports a campaign as (organic) or (referral), the visit arrived without UTMs. Clicks from webmail can show as referrals from mail.google.com or outlook.live.com when links are untagged, which is another reason to tag every link.

Turn it into a monthly email scorecard

Once the join works for one month, stack months with a month column and keep one row per send. A scorecard with recipients, clicks, sessions, key events and revenue per 1,000 recipients lets you compare sends of different list sizes. Revenue per 1,000 recipients for the autumn sale is £3,780 / 20 = £189; for the new-range email, £1,620 / 20 = £81. That's a fairer comparison than raw revenue when list size changes month to month.

Adding unsubscribes to the picture

Revenue isn't the only outcome of a send. Join unsubscribes and spam complaints from the email export onto the same row and calculate unsubscribes per 1,000 recipients. An email that earns well but loses an unusual number of subscribers may cost more in future revenue than it brings in now. Comparing both on one row is the main reason to keep the email-side columns rather than replacing them with GA4 data.

Frequently asked questions

Do I need GA4 Explorations, or will standard reports do?
The standard Traffic acquisition report with Session campaign as the primary dimension works too. Explorations are handier because you can add a medium filter and export exactly the columns you need.
What if my email platform doesn't add UTMs automatically?
Add them by hand to each link, or use a URL builder sheet so the campaign value follows the same pattern every time. Without UTMs, GA4 can't attribute the visit to a specific send.
Should I trust the email platform's revenue or GA4's?
Neither is wrong; they use different attribution. Use GA4 when comparing email with other channels, because every channel is then measured the same way.
Can I join at subscriber level?
Not with standard GA4 reports, which don't expose personal identifiers. Subscriber-level joins need your own user ID tracking and should respect consent and privacy rules.
Why are GA4 sessions lower than email clicks?
Some clicks are bot or security-scanner clicks, some visitors decline analytics cookies, and one person clicking twice in one session counts as one session.

Related guides