Using Webhooks inside Google Tag Manager for data enrichment - 3 ways & 10 use cases

Most GTM implementations are a one-way pipe to GA4 or other tools. But with webhooks, it can become a powerful connector between systems. In this post, I explain how to send data from GTM to a webhook in three ways—and why it matters. From fixing Samcart’s Order ID vs. Transaction ID gap to building smarter automations, webhooks turn GTM into a true data hub.

The idea of using Webhooks inside of Google Tag Manager occurred while working on a web tracking project that used Samcart for checkouts.

The problem is as follows:
When a purchase happens, Samcart creates two IDs: an Order ID and a Transaction ID.

  • The Transaction ID goes into the dataLayer for GA4.
  • The Order ID appears only in Samcart’s reports.

The two never travel together. GA4 has no Order ID, and Samcart has no Transaction ID. Without linking them, you can’t reconcile orders or send accurate refunds back into GA4.

The fix was to capture both at the source. In GTM, I fired a webhook on purchase to send the Transaction ID into Zapier. Separately, Samcart sent the Order ID into another webhook. Storing them side by side gave me the missing link.

With webhooks, GTM can talk to systems that never had a native tag. CRMs, support tools, finance systems, internal databases—you name it. Instead of relying solely on analytics platforms, you can make GTM feed data wherever you need it.

And the best part? You don’t need a developer to rewrite backend code. You can get started with a webhook tag in a few minutes.

How to send data from GTM to a webhook

I’m using Zapier webhooks but you can use any webhooks. Infact, you can also create your own webhook.
There are three main ways to do it. Each has trade-offs.

1. Quick & Dirty: GET via Image Tag

  • The simplest hack: fire a Custom Image tag in GTM.
  • The webhook URL includes your data as query parameters.
  • Zero CORS headaches, fires reliably.
  • Works when your payload is tiny (think: a transaction ID + timestamp).

This is the “just make it work” method. Perfect for lightweight signals and this is the one I used for my implementation.

In Zapier

  • Create a Zap → Webhooks by Zapier → Catch Hook.
  • Copy the catch URL.

In GTM

  • Create Data Layer Variables for the fields you want to send (e.g. dlv – client_id, dlv – event_name, etc.).
  • Create Tag → Custom Image
    • Image URL (an example): https://hooks.zapier.com/hooks/catch/XXXXXXX/YYYYYYY/?event={{dlv – event_name}}&client_id={{dlv – client_id}}&value={{dlv – value}}
    • Enable “Support document.write” = off.
  • Create Trigger → Custom Event e.g. zap_event (or whatever you push).

On your site/app, fire it with:

dataLayer.push({
event: 'zap_event',
event_name: 'form_submit',
client_id: window.gtag && gtag.get ? gtag.get('get', 'client_id') : undefined,
value: 123
});

Pros: dead simple, no CORS.
Cons: URL length limits; values visible in URL; GET only.

2. Better (POST) from web GTM

  • Use a Custom HTML tag and POST a JSON body.
  • With navigator.sendBeacon, you avoid CORS preflight issues and it still fires on page unload.
  • You can send more fields, structured neatly.
  • Great for purchases, form data, or any event where you want richer context.

Think of this as the grown-up method: flexible, reliable, still easy to set up.
This lets you POST safely from the browser without preflight. Great for modest payloads.

In Zapier

Same as above: Catch Hook URL.

In GTM

  • Make your Data Layer Variables as above.
  • Tag → Custom HTML (fire on your custom event – this one is just an example)
<script>
(function () {
var url = 'https://hooks.zapier.com/hooks/catch/XXXXXXX/YYYYYYY/';
// Build a clean payload from the dataLayer variables you exposed in GTM
var payload = {
event_name: '{{dlv - event_name}}',
client_id: '{{dlv - client_id}}',
value: '{{dlv - value}}',
page_url: '{{Page URL}}',
user_agent: '{{User Agent}}'
};

// Remove empty/undefined keys
Object.keys(payload).forEach(function(k){ if (payload[k] == null || payload[k] === '') delete payload[k]; });

// Prefer sendBeacon; it avoids CORS preflight and works during unload
var body = JSON.stringify(payload);
var ok = false;
if (navigator.sendBeacon) {
var blob = new Blob([body], { type: 'application/json' });
ok = navigator.sendBeacon(url, blob);
}
if (!ok) {
// Fallback with fetch using a CORS-safe content-type
try {
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'text/plain;charset=UTF-8' }, // text/plain avoids preflight
body: body,
mode: 'no-cors',
keepalive: true
});
} catch(e) {}
}
})();
</script>
  • Trigger → Custom Event (e.g., zap_event).
  • Fire it by pushing to the dataLayer (same as above).

Pros: POST, more fields, reliable on page unload, avoids CORS.
Cons: You can’t read the Zapier response (not needed for this use-case).

3. Most robust: route via Server-Side GTM (recommended for scale)

  • Client → sGTM endpoint (first-party) → sGTM makes a server POST to Zapier.
  • No browser CORS or adblockers.
  • You can add auth/secret, throttle, retries, QA, PII scrubbing.

In sGTM: Create a Custom HTTP tag (or template) that POSTs to Zapier; trigger it from a custom client or GA4 MP event you forward.

High-level steps

  • Set up sGTM container (App Engine / Cloud Run).
  • In Web GTM, send a lightweight request to your sGTM endpoint (via GA4, or a custom HTTP tag to /zap-proxy).
  • In sGTM, catch it and Tag → HTTP Request to Zapier with JSON body.

Field mapping & hygiene (important)

  • Whitelist what you send. Don’t dump the whole dataLayer. Build a small payload object with only allowed keys.
  • PII: Only send personal data to Zapier if you have consent and it’s in scope. Hash emails if you must send them.
  • Consent: If you use Cookiebot, add a trigger condition so this fires only when the relevant consent category is granted (e.g., cookie_consent_update + your consent state).
  • Dupes: Add an event_id (UUID) in your payload for deduplication on the Zapier side if your flow can double-fire.
  • Error handling: With sendBeacon/no-cors you can’t read responses. If you need delivery audits, prefer sGTM so you can log and retry.

Testing checklist

  • In GTM Preview, push a test event to dataLayer and ensure your tag fires once.
  • In Zapier → Test Trigger → you should see the payload arrive.
  • Add filters/paths in Zapier as needed.
  • Publish GTM.

TrackFunnels has been a fantastic resource for ConversionLab. We have been using them to troubleshoot tracking, implement GA4 and GTM setups, and handle Q&A for our e-commerce clients on Shopify. Their team is friendly, responsive, and truly knowledgeable. It’s a huge relief to have a reliable, go-to provider for any analytics issue that comes up.

Finge Holden
Founder & Conversion Rockstar, ConversionLab

Why you’d ever do this: the use cases

Sending data from GTM to a webhook may sound niche. It’s not. Once you start, you’ll see dozens of possibilities.

Here are some use cases:

Analytics & Reconciliation

  • Order ↔ Transaction ID mapping: My Samcart example. Store both IDs at purchase so refunds, renewals, and customer lookups actually work.
  • Attribution backfill: Catch when GA4 shows purchases that never make it into your order system, or vice versa.

Finance & Operations

  • Refund readiness: Keep a clean lookup table of transaction IDs so Finance can process GA4 refunds without guesswork.
  • Revenue discrepancy alerts: Trigger a webhook to compare order counts vs. GA4 transactions and flag if they drift too far apart.

QA & Monitoring

  • Tag health heartbeat: Use a webhook as a “heartbeat.” If purchases don’t show up for an hour when traffic is normal, you know something broke.
  • Environment drift detection: Spot if staging fires live purchase events into GA4, or production fails to send at all.

Marketing & Customer Experience

  • Campaign pacing sanity check: Roll up transaction IDs by hour or day in Zapier to sanity-check media spend.
  • High-value alerts: Send a Slack message when a big purchase happens, so the team can celebrate (or react fast if it’s fraud).
  • Customer support lookup: Support agents can search by GA4 transaction ID to find the matching order in Samcart.

Compliance & Audit

  • Immutable log: Store a timestamped copy of every purchase event. Handy for disputes or audits.
  • Consent auditing: If you also capture consent state, you can prove when purchases happened with or without certain consents.

Product & Experimentation

  • Feature impact pulse: Did a checkout redesign help or hurt conversions? Count transactions via webhook before/after.
  • Anomaly spotting: Alert if purchase timestamps cluster in strange ways (bursts, sudden gaps), pointing to broken forms or payment outages.

Start lean, grow later

You don’t need to boil the ocean. My setup started lean: GTM sends just transaction ID + timestamp into Zapier. Samcart sends order ID + timestamp. That was enough to solve the immediate problem: making refunds work in GA4.
From there, you can layer on more use cases. Send campaign data, customer identifiers (hashed if needed), or trigger downstream automations.

The point is: GTM is not just a one-way pipe. With webhooks, you can make it a hub.

Webhooks can turn GTM into a connector between systems that don’t normally talk. In my case, it solved a Samcart ↔ GA4 mismatch that made refunds impossible. In yours, it could be about reconciling orders, sending alerts, or automating ops.
Start small: send one or two key fields into a webhook.

Once you see the value, you’ll find plenty of reasons to expand. Anything unclear? Write in the comments and we’ll be happy top respond. If you’d like us to implement this for you, please feel free to contact.

Need Help with Data Tracking & Attrubution?

TrackFunnels is an expert Data Tracking consulting.

If you’ve trouble tracking events for your B2B or eCommerce business whether in GA4 or any other analytics platform OR if you are facing attribution issues like UTM not properly passing through, schedule a free call with our founder.

Book a free consultation →

FAQs: Technical terms explained for marketers

Q: What is GET?

A GET request is like sending information through the URL itself — similar to adding parameters at the end of a link (for example, ?utm_source=google).

When GTM uses a GET request (like with an Image tag), it simply loads a tiny invisible image whose URL carries your data. It’s the quickest way to send small bits of information, but it’s limited — you can’t fit much data inside a URL.

Q: What do we mean by CORS. Why can it be a headache?

CORS stands for Cross-Origin Resource Sharing.

It’s a browser security rule that blocks web pages from sending data to another domain unless that domain explicitly says it’s okay. For example, your website can’t easily send data to Zapier unless Zapier’s server allows it.
That’s why some methods (like the simple Image tag) work easily, while others (like certain POST requests) need special settings — otherwise, the browser stops them. That’s what we mean by a “CORS headache.”

Q: What is preflight?

A preflight request is a small “check-in” your browser makes before sending real data — like asking, “Hey Zapier, are you okay with me sending this?” If Zapier doesn’t reply correctly, your request fails. It’s part of the CORS security process. Using techniques like navigator.sendBeacon helps avoid this extra step, which is why it’s preferred for smooth, reliable data sending.

Q: What is sendBeacon? What is navigator.sendBeacon?

sendBeacon is a browser feature that lets your site send small pieces of data quietly in the background — even if the user closes the page immediately afterward.

Think of it as a “reliable courier” that drops off your tracking info right before the tab closes.
navigator.sendBeacon is just how the code calls that courier — it’s the technical command behind it.
It’s widely used for analytics and conversion tracking because it’s dependable and doesn’t get blocked easily.

What are throttle, retries, QA, and PII scrubbing?

  • Throttle: Slowing down how often requests are sent to avoid flooding servers (like pacing emails instead of sending a thousand at once).
  • Retries: Automatically trying again if a request fails — useful when a network hiccup stops a webhook.
  • QA (Quality Assurance): Testing your setup to make sure every event fires correctly and no data goes missing.
  • PII scrubbing: Removing or masking personally identifiable information (like emails or names) before data is sent — a key privacy safeguard for compliance.

GDPR & privacy checklist

Not legal advice but this is the practical starter list we use.

Roles & accountability

  • Know your role: You (the merchant/site) are typically the controller; your destinations (e.g., Zapier) act as processors. Controllers must implement and demonstrate compliance (Art. 5(2) accountability). Keep records of what you send and why.

Lawful basis & consent

  • Measurement vs. marketing: If a webhook sends data for analytics/ops that rely on cookies or identifiers, ensure you have an appropriate lawful basis. For EU users, many setups rely on consent—align your GTM firing rules with consent status (Consent Mode / CMP).
  • Purpose limitation: Only use the data for the purpose you state (e.g., reconciliation/refunds). Don’t repurpose without a fresh basis.

Data minimization & PII

  • Send the minimum: Prefer anonymous IDs (transaction_id) over personal data. If you must send PII, hash it client-side and scrub downstream (e.g., remove query params, mask values). Document your retention and deletion approach.

International transfers

If you post to a US service like Zapier, ensure you have a valid transfer mechanism. Zapier participates in the EU-US Data Privacy Framework (DPF) and provides a DPA and TIA—reference these in your docs and vendor reviews.
Zapier

Security of processing

Contract on security measures (DPA), and implement technical/organizational controls: HTTPS, signatures, access controls, and periodic reviews.

Data subject rights & transparency

  • Update your privacy notice to explain that checkout events may be sent to processors via webhooks for analytics/operations (refund reconciliation, error alerts, etc.).
  • Ensure you can honor rights (access, deletion) by being able to locate and remove records in your destination store.

A practical “go/no-go” before you launch

  • Do we need every field in this payload?
  • Does our CMP/Consent Mode gate the webhook firing correctly?
  • Is the destination covered by a DPA and a valid transfer mechanism (e.g., DPF*)?
  • Are payloads signed and timestamped? Do we handle retries and duplicates?
  • Are logs sanitized and retention defined?

*If your vendor participates in the DPF (Zapier does), it means they’ve committed to GDPR-level data protection standards.

If you can tick those off, you’re in strong shape—both technically and from a GDPR point of view.

0 Comments

    Leave a Reply