← All Guides

Tally Form Tracking with Google Tag Manager: Send Embedded Tally Submissions to GA4 and Google Ads

Tally forms are embedded in an iframe, but Tally posts a Tally.FormSubmitted message on success. Learn how to capture it in Google Tag Manager, push the form ID to the dataLayer, and fire GA4, Google Ads and Meta conversions.

Atiqul Islam
Written by Atiqul Islam

Tracking & analytics specialist. 278+ GTM, GA4 and server-side tracking projects for clients in the US, UK and Australia.

Rather not do this yourself? I set this up for clients every week. Free 15-minute audit, no obligation.

Book a Free Audit

Tally is a free, fast form builder that many startups and agencies now use instead of Typeform. Like other hosted builders, it runs in an iframe, so your site's Google Tag Manager cannot see submissions directly. Tally solves this better than most: on submission it posts a structured message to the parent page that includes the form ID and the submitted fields.

This guide shows how to catch that message in GTM and send the conversion to GA4, Google Ads and Meta.

What Tally Sends

When a respondent submits an embedded Tally form, the iframe posts a message to the parent window. The message is a JSON string with an event of Tally.FormSubmitted and a payload containing formId, respondentId and a fields array with each question's label and value.

Step 1: The Listener

Create a Custom HTML tag named Listener - Tally Submit and fire it on All Pages or on the pages with the embed:

<script>
(function () {
  window.addEventListener('message', function (e) {
    if (!e.origin || e.origin.indexOf('tally.so') === -1) { return; }
    var data = e.data;
    if (typeof data === 'string') {
      try { data = JSON.parse(data); } catch (err) { return; }
    }
    if (!data || data.event !== 'Tally.FormSubmitted') { return; }

    var payload = data.payload || {};
    var email = '';
    var phone = '';
    (payload.fields || []).forEach(function (field) {
      var type = (field.type || '').toUpperCase();
      if (type === 'INPUT_EMAIL' && field.value) { email = String(field.value).trim().toLowerCase(); }
      if (type === 'INPUT_PHONE_NUMBER' && field.value) { phone = String(field.value).trim(); }
    });

    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      event: 'form_submit_success',
      form_tool: 'tally',
      form_id: payload.formId || '',
      response_id: payload.respondentId || '',
      user_email: email || undefined,
      user_phone: phone || undefined
    });
  });
})();
</script>

Only the email and phone are read from the fields. Everything else in the payload stays out of the dataLayer.

Step 2: Variables and Trigger

Data Layer Variables: form_id, response_id, user_email, user_phone. Custom Event trigger: form_submit_success, with a form_id condition if you have several forms.

Step 3: Tags

Step 4: Store the Click ID in Tally

In the Tally form, add a hidden field named gclid. Tally fills hidden fields from URL parameters on the embed URL. Add a small script on your page that appends ?gclid= with the stored click ID to the Tally embed src before the iframe loads, or use Tally's option to pass through the parent page's URL parameters. Once each response carries the click ID, you can export qualified leads and upload them to Google Ads as offline conversions.

Step 5: Test

  1. GTM Preview on the page with the Tally embed. Submit a test response.
  2. Confirm form_submit_success appears with form_id, response_id, and the email and phone if you included those fields.
  3. Confirm one fire each of GA4, Google Ads and Meta.
  4. Check the Google Ads request in a tag debugger such as the Insighter Debugger extension for the conversion label and hashed user data.
  5. If you set up the hidden field, open the response in Tally and confirm the gclid value.

Common Problems

Summary

Tally gives you the cleanest hosted-form tracking of the bunch: a single structured message with the form ID and fields. One listener in GTM turns it into a dataLayer event you can send to GA4, Google Ads and Meta with Enhanced Conversions attached.

Frequently Asked Questions

Does this work with the Tally popup and the inline embed?

Yes. Both load the form in an iframe and both post the same Tally.FormSubmitted message to the parent page.

Can I get the respondent's email for Enhanced Conversions?

The Tally.FormSubmitted message includes the submitted fields in its payload, so you can read the email from it and pass it to Google Ads for Enhanced Conversions. Be deliberate about which fields you use and never push free-text answers to the dataLayer.

Can I store the Google click ID with the response?

Yes. Tally supports hidden fields that can be filled from URL parameters. Pass the gclid into a hidden field and you can upload qualified leads as offline conversions later.

Tally also offers a Google Analytics and Meta integration. Which should I use?

Tally's built-in integrations fire inside the iframe and do not carry your site's Google Ads click identifier reliably. The parent-page listener in this guide fires in your site's context and attributes correctly.

Nothing arrives when I test. What do I check?

Log window messages in the console and submit the form. You should see a message containing Tally.FormSubmitted. If you see nothing, confirm the embed is a Tally iframe and not a redirect link to tally.so.

Want This Done Right the First Time?

Book a free 15-minute audit call. I'll review your setup, show you what is broken, and tell you exactly what it takes to fix it.

Chat Now