Paperform Conversion Tracking: Google Ads, GA4 & Meta Pixel
Do you embed a Paperform on your website and need to track form submissions as conversions in Google Ads, Google Analytics 4, or Meta Pixel?
You’re in the right place.
Paperform loads as an iframe — a mini-website from another domain embedded inside yours. That causes a classic tracking problem that trips up most marketers and developers. This guide covers the correct solution: a postMessage listener in Google Tag Manager.
The Iframe Problem: Why Standard Tracking Doesn’t Work
When someone fills out your Paperform and submits it, that “thank you” confirmation happens inside the Paperform iframe at paperform.co — not on your website.
Your Google Analytics tag, your Meta Pixel, your Google Ads conversion tag — they all live on your domain. They don’t know anything happened inside the iframe.
What breaks if you ignore this
- Google Analytics: zero form submission data, or wildly wrong attribution
- Google Ads: conversions not recorded → your campaign looks like it’s not working → you pause it → you lose leads
- Meta Pixel: your audiences don’t grow, lookalike campaigns underperform
The root issue: cross-domain iframe isolation. The iframe and your page can’t directly share data. They can only communicate via the browser’s postMessage API.
The Correct Solution: postMessage Listener in GTM
Paperform sends postMessage events to the parent window during the form lifecycle. Here’s what actually arrives in the browser (captured from a real submission):
// Form submitted — this is the conversion event
paperform:{"details":{"form_id":"69fce4c2b20e93f380049d04","eventName":"SubmittedForm","payload":{"submission_id":"69fce5e29dc9f15f54026abd","submitted_at":"2026-05-07 19:20:02","total":0,...}},"action":"analytics","id":"xstrr2sh"}
// Submission data — fires immediately after, contains field values
paperform:{"details":{"submission_id":"69fce5e29dc9f15f54026abd","data":[{"label":"What's your email?","value":"user@example.com","type":"email",...}]},"action":"submission","id":"xstrr2sh"}
Two things to note:
- Messages are strings, not objects. They start with
paperform:followed by JSON. - The conversion trigger is
action: "analytics"+eventName: "SubmittedForm"— not a type field.
Your job: parse these strings and push the conversion to your dataLayer.
Google Tag Manager is the right place to do this. Here’s exactly how.
Step-by-Step: Paperform Conversion Tracking with GTM
Step 1: Add the postMessage Listener Tag
In GTM, create a Custom HTML tag:
Tag name: Listener — Paperform Submission
HTML:
<script>
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function(e) {
if (typeof e.data !== "string") return;
if (e.data.indexOf("paperform:") !== 0) return;
if (e.origin.indexOf("paperform.co") === -1) return;
var parsed;
try { parsed = JSON.parse(e.data.slice(10)); } catch(err) { return; }
if (parsed.action === "analytics" &&
parsed.details &&
parsed.details.eventName === "SubmittedForm") {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "paperform_submitted",
paperformId: parsed.id,
paperformFormId: parsed.details.payload.form_id,
paperformSubmissionId: parsed.details.payload.submission_id,
paperformTotal: parsed.details.payload.total
});
}
}, false);
</script>
Trigger: All Pages (DOM Ready)
Why DOM Ready? The listener needs to be attached before any iframe loads. DOM Ready fires early enough.
Step 2: Create a Custom Event Trigger
In GTM, go to Triggers → New:
- Trigger type: Custom Event
- Event name:
paperform_submitted - Name:
Custom Event — paperform_submitted
This trigger will fire whenever the dataLayer push from the listener lands.
Step 3: Add Your Conversion Tags
Now add tags that fire on the paperform_submitted trigger. One tag per destination.
Google Analytics 4 — Event Tag
- Tag type: Google Analytics: GA4 Event
- Event name:
generate_lead(orform_submit, or whatever fits your setup) - Trigger:
Custom Event — paperform_submitted
Google Ads — Conversion Tag
- Tag type: Google Ads Conversion Tracking
- Conversion ID + Label: from your Google Ads account (Tools → Conversions)
- Trigger:
Custom Event — paperform_submitted
Meta Pixel — Event Tag
If you use Meta Pixel via GTM:
- Tag type: Custom HTML
- HTML:
<script> fbq('track', 'Lead'); </script> - Trigger:
Custom Event — paperform_submitted
Step 4: Test Before Publishing
Use GTM Preview mode (the “Preview” button in the top right):
- Open your page with the Paperform embed
- Fill out and submit the form
- In the GTM debug panel, look for the
paperform_submittedevent firing - Verify your conversion tags appear in the “Tags Fired” section
Also check the browser console. After submission you should see the dataLayer push if you run:
window.dataLayer
Step 5: Publish
When Preview confirms everything fires correctly:
- Click Submit in GTM
- Add a version name:
"Add Paperform submission tracking" - Publish
From this point, every Paperform submission on your site sends a conversion to your chosen platforms.
Common Issues and Fixes
The event isn’t firing
Check origin filtering. If you have a custom domain connected to Paperform (e.g. forms.yoursite.com), the origin in the postMessage will be your custom domain — not paperform.co. Update the origin check:
// Instead of:
if (event.origin.indexOf('paperform.co') === -1) return;
// Use your custom domain:
if (event.origin.indexOf('forms.yoursite.com') === -1) return;
// Or remove origin filtering entirely (less secure, but fine for debugging):
// (remove the origin check line)
Duplicate conversions
Each Paperform submission fires SubmittedForm once, so duplicates are unlikely with this method. If you do see doubles (e.g. two forms on one page both firing), add a submission ID check:
if (parsed.action === "analytics" &&
parsed.details &&
parsed.details.eventName === "SubmittedForm") {
var submissionId = parsed.details.payload.submission_id;
var dedupeKey = "pf_tracked_" + submissionId;
if (sessionStorage.getItem(dedupeKey)) return;
sessionStorage.setItem(dedupeKey, "1");
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "paperform_submitted",
paperformId: parsed.id,
paperformSubmissionId: submissionId
});
}
Multiple Paperforms on one site
The paperformId dataLayer variable carries the form slug (e.g. xstrr2sh). Create a Data Layer Variable in GTM:
- Variable type: Data Layer Variable
- Variable name:
paperformId
Then use it as a condition in your triggers if you want different conversions per form.
Beyond Basic Tracking: Enhanced Conversions
Basic tracking tells Google Ads that a conversion happened. Enhanced Conversions tell it who converted — hashed email, name, phone. This improves attribution significantly, especially on iOS where cookie-based tracking is unreliable.
Paperform fires a second postMessage immediately after SubmittedForm with action: "submission". It contains the actual field values:
// The submission data message — fires right after SubmittedForm
paperform:{"details":{"submission_id":"...","data":[
{"label":"What's your email?","value":"user@example.com","type":"email"},
...
]},"action":"submission","id":"xstrr2sh"}
You can catch this in the same listener and push the email to the dataLayer for use in an Enhanced Conversions tag. The submission_id matches across both messages so you can correlate them.
That’s a deeper setup — but the listener you’ve already built is the foundation for it.
What About Paperform’s Built-In Integrations?
Paperform has native Google Analytics and Facebook Pixel integrations. Do not use them for conversion tracking on embedded forms.
Here’s why: those integrations fire from Paperform’s servers or Paperform’s domain — not yours. The conversion has no connection to your website’s cookies, sessions, traffic sources, or click IDs.
Result: an “orphan” conversion with no attribution. You see a number go up, but you can’t tell if it came from your Google Ads campaign, your Instagram post, or a direct visit. Useless for optimizing ad spend.
The GTM postMessage method fires from your website, so it inherits your full tracking context. That’s the only way to get correct attribution.
Need This Done Properly?
If Google Tag Manager isn’t your thing, or you want a bulletproof setup with enhanced conversions, proper deduplication, and GA4 funnel tracking — get in touch.
Or check the shop for prebuilt GTM setups for other form platforms.