Tally is a form platform that offers unlimited forms, unlimited responses, and webhook support even on its free plan. Unlike Typeform, most features are available at no cost. But without proper setup, form data won’t flow accurately into your analytics tools and CRM systems.
This guide covers end-to-end conversion tracking for Tally forms: postMessage events, Google Tag Manager integration, hidden fields, UTM parameters, webhook configuration, and CRM data flow through automation tools.
Tally Conversion Events
Tally communicates form interactions to the outside world through two mechanisms: postMessage events (free, works with all embed types) and dataLayer events (requires GA4 integration, Pro).
postMessage Events (Free)
When Tally is embedded or used as a popup, it sends events to the parent page via postMessage. You can capture these with JavaScript:
window.addEventListener("message", function (event) {
if (event.data && typeof event.data === "object") {
switch (event.data.event) {
case "Tally.FormLoaded":
// formId
break;
case "Tally.FormPageView":
// formId, page
break;
case "Tally.FormSubmitted":
// id, respondentId, formId, formName, createdAt, fields[]
break;
case "Tally.PopupClosed":
// formId
break;
}
}
});
The Tally.FormSubmitted event carries the full form data: respondentId, formName, and a fields[] array with all field values. This lets you forward form submissions to GTM, GA4, or your own analytics system.
dataLayer Events (Pro)
When the GA4 integration is active, Tally pushes these events via dataLayer.push():
Tally.FormPageView: Fires each time a form page is viewedevent_category: Page URLevent_label:Page [X](page number)
Tally.FormSubmitted: Fires on form submissionevent_category: Page URLevent_label: Form title
dataLayer events require an active GA4 integration. If you want to use GTM but don’t need GA4 data collection, you can enter a dummy Measurement ID (G-XXXXXXXXXX).
Google Tag Manager Integration
Tally doesn’t have a direct GTM connection button. GTM setup can be done two ways:
Method 1: postMessage to GTM (Free)
For embedded or popup forms, capture postMessage events and push them to the dataLayer:
window.addEventListener("message", function (event) {
if (event.data?.event === "Tally.FormSubmitted") {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "tally_form_submitted",
tallyFormId: event.data.payload.formId,
tallyFormName: event.data.payload.formName,
tallyRespondentId: event.data.payload.respondentId,
});
}
});
Create a Custom Event trigger in GTM for tally_form_submitted. Attach GA4 Event, Google Ads Conversion, or any other platform tags to this trigger.
Method 2: Code Injection with GTM (Pro)
If you’re using Tally Pro’s custom domain feature, paste both GTM snippets (<head> and <body>) into the Code Injection field. In this case, dataLayer events are captured directly by GTM.
Trigger configuration in GTM:
- Trigger type: Custom Event
- Event name:
Tally.FormSubmitted - Data Layer Variable: Use
eventModel.event_labelto access the form title
Cross-domain Considerations
Tally forms are hosted on tally.so by default. This means:
- iframe embed: Third-party cookie restrictions (Safari, Firefox) may prevent GA4/GTM tracking inside the iframe. The
postMessagemethod is more reliable. - Custom domain (Pro): Forms are served from your own domain, preserving cookie context and eliminating cross-domain issues.
- GA4 cross-domain: Add
tally.soas an additional domain in your GA4 data stream settings.
Get the Tally Starter Kit: 4 walkthrough videos, a ready-to-clone template with UTM tracking built in, and a Claude prompt to configure forms for your use case.
Get the Free Starter KitEnriching Data with Hidden Fields
Creating hidden fields in Tally is free and unlimited. Type /hidden in the form editor to add a hidden field.
Usage
Hidden field values are passed via URL parameters:
https://tally.so/r/FORM_ID?source=email&ref=newsletter
https://tally.so/r/FORM_ID?source=linkedin&campaign=q1-launch
Multiple parameters are separated with &. Values appear in the Submissions table alongside regular responses.
Automatic Forwarding in Embedded Forms
For embedded Tally forms, URL parameters from the parent page are automatically forwarded to the form. If your page is example.com/register?utm_source=google, a utm_source hidden field in the form automatically receives the value google.
Adding an originPage hidden field automatically captures the page path (e.g., /register) where the form was filled out.
Passing Data Between Forms
You can carry hidden field values across forms by appending them to redirect URLs. This is useful for multi-step flows (registration > onboarding > survey) where you need to preserve user context.
UTM Parameters
Tally doesn’t have a separate “UTM Tracking” toggle. UTM tracking is handled through hidden fields:
- Create these hidden fields in the form editor:
utm_source,utm_medium,utm_campaign,utm_term,utm_content - Share the form link with UTM parameters:
https://tally.so/r/FORM_ID?utm_source=google&utm_medium=cpc&utm_campaign=brand
- In embedded forms, UTM parameters from the parent page URL are automatically forwarded
In the webhook payload, hidden fields are delivered with the HIDDEN_FIELDS type. You can map these fields to CRM properties in your automation tool.
Get the Tally Starter Kit: 4 walkthrough videos, a ready-to-clone template with UTM tracking built in, and a Claude prompt to configure forms for your use case.
Get the Free Starter KitWebhook-based Conversion Tracking
One of Tally’s strongest and completely free features is webhook support. Every form submission sends a JSON payload to your specified endpoint.
Webhook Setup
Go to Integrations > Webhooks in the form settings and add your endpoint URL.
Webhook features:
- Trigger: POST request on every new form submission
- Format: JSON payload with
eventType: "FORM_RESPONSE" - Security: Optional signing secret generates a
Tally-Signatureheader (SHA256 HMAC, base64) - Custom headers: Add custom HTTP headers to each webhook request
- Timeout: Endpoint must return 2XX within 10 seconds
- Retry: Failed requests are retried at 5min, 30min, 1hr, 6hr, and 1 day intervals
- Limit: Unlimited webhook URLs per form
Payload Structure
{
"eventType": "FORM_RESPONSE",
"createdAt": "2026-03-27T10:00:00.000Z",
"data": {
"responseId": "abc123",
"formId": "FORM_ID",
"formName": "Contact Form",
"fields": [
{
"key": "question_email",
"label": "Email",
"type": "INPUT_EMAIL",
"value": "user@example.com"
},
{
"key": "question_utm",
"label": "utm_source",
"type": "HIDDEN_FIELDS",
"value": "google"
}
]
}
}
Webhook Signature Verification
When a signing secret is configured, each request includes a Tally-Signature header. Verify on your endpoint:
import crypto from "crypto";
function verifyTallySignature(payload, signature, secret) {
const hash = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("base64");
return hash === signature;
}
Automation and CRM Integration
Tally doesn’t have direct CRM integrations. However, through webhooks and automation tools, you can connect to virtually any CRM.
Native Integrations
Tally’s built-in integrations:
- Google Sheets
- Notion
- Airtable
- Coda
- Slack, Discord
- Linear
- Webhooks
CRM Connection via Automation Tools
Use Zapier, Make, or n8n to push Tally form data to HubSpot, Salesforce, Pipedrive, or any other CRM.
Example Zapier flow:
- Trigger: Tally > New Submission
- Action: HubSpot > Create/Update Contact
- Mapping: Map Tally fields (email, name, utm_source, etc.) to HubSpot properties
You can also send data directly to a CRM API via webhooks. This eliminates automation tool costs but requires endpoint development and maintenance.
Tally vs Typeform: Automation Comparison
| Feature | Tally | Typeform |
|---|---|---|
| Webhooks | Free, unlimited | Free, limited |
| Hidden Fields | Free, unlimited | Free |
| GTM (direct) | Pro (code injection) | Pro (code injection) |
| GTM (postMessage) | Free | Free (dataLayer) |
| HubSpot integration | Zapier/Make/webhook | Native |
| Google Sheets | Native | Native |
| Zapier/Make | Free | Free |
Testing and Verification
After completing the setup, run through these checks:
- postMessage: In the browser console, use
window.addEventListener("message", (e) => console.log(e.data))to verify form events are firing - GTM Preview: Check the dataLayer for
tally_form_submitted(postMessage method) orTally.FormSubmitted(code injection method) - Hidden fields: Append
?source=test&utm_source=testto the form URL, submit, and verify values appear in the Submissions table - Webhook: Submit a form and check the webhook event log for successful delivery. Verify the payload structure on your endpoint
- CRM: Verify that the contact created through your automation tool has the correct source information
In embedded forms, third-party cookie restrictions may prevent GTM/GA4 from working inside the iframe. The postMessage method bypasses this issue and works reliably across all modern browsers.
- 01 Tally sends free events via postMessage; dataLayer events require GA4 integration (Pro)
- 02 The postMessage method bypasses third-party cookie restrictions in iframe embeds and works reliably across all browsers
- 03 Hidden fields are free and unlimited; in embedded forms, parent page URL parameters are automatically forwarded
- 04 Webhook support is free: JSON payload on every submission, signing secret for signature verification, and automatic retry mechanism
- 05 Tally has no native CRM integration; connect to HubSpot, Salesforce, or other CRMs via Zapier, Make, or n8n
+ How do I set up Tally conversion tracking with GTM?
Two methods. Free method: capture postMessage events with JavaScript and push to GTM via dataLayer.push(). Pro method: paste GTM snippets into the Code Injection field using the custom domain feature. In both cases, create a Custom Event trigger in GTM.
+ How does the Tally webhook work?
Every form submission sends a JSON POST request to your specified endpoint. The payload includes form data, hidden fields, and respondent information. SHA256 HMAC signature verification is available via signing secret. Failed requests are automatically retried at intervals from 5 minutes to 1 day.
+ Do Tally hidden fields work automatically in embedded forms?
Yes. In embedded Tally forms, URL parameters from the parent page are automatically forwarded to the form. If your page is example.com/register?utm_source=google, a utm_source hidden field in the form automatically receives the value google.
+ What is the main difference between Tally and Typeform?
Tally offers webhooks, hidden fields, and unlimited forms for free. Typeform has native HubSpot integration while Tally connects to CRMs through automation tools. For GTM integration, Tally offers the free postMessage method while Typeform fires dataLayer events directly.