Category: Conversion Tracking

Setting up tracking pixels, UTMs, and offline conversions

  • ActiveCampaign and WordPress Lead Tracking

    ActiveCampaign is one of the most widely used CRM and email automation platforms for small and mid-size service businesses. Its combination of contact management, deal pipelines, and marketing automation makes it a practical all-in-one choice.

    But like most CRMs, ActiveCampaign has an attribution gap: it records that a lead arrived, but not which campaign, keyword, or ad brought them there. The UTM parameters and click IDs that identify your best-performing channels stay in the browser and never make it into the contact or deal record.

    This guide covers how to close that gap — from UTM capture through hidden form fields to custom ActiveCampaign fields, deal-level reporting, and offline conversion upload to Google Ads and Meta.

    The Attribution Gap in ActiveCampaign

    When a visitor lands on your WordPress site from a paid ad, the URL looks something like this:

    https://yoursite.com/contact/?utm_source=google&utm_medium=cpc&utm_campaign=roofing-leads&gclid=abc123

    The UTM parameters identify the source, channel, and campaign. The gclid (Google Click ID) ties the visit to a specific ad click for offline conversion reporting.

    What happens to those values? By default, they disappear the moment a form is submitted. ActiveCampaign receives a name, email, and phone number — but nothing about where the lead came from.

    The result: you know you got a lead. You have no way to know it came from the campaign costing $80 per click, or from an organic search that costs nothing. You cannot see whether the leads from one campaign close at twice the rate of another. You cannot tell Google Ads which clicks are turning into paying clients.

    Step 1: Capture UTMs in First-Party Cookies

    The fix starts with a JavaScript snippet that runs when a visitor first lands on your site and stores UTM parameters in first-party cookies before they navigate to your contact page or anywhere else.

    The snippet captures six values:

    • utm_source — the traffic source (google, facebook, email)
    • utm_medium — the channel (cpc, organic, social)
    • utm_campaign — the campaign name
    • utm_term — the keyword that triggered the ad
    • utm_content — the specific ad or creative variant
    • gclid and fbclid — Google and Facebook click identifiers for offline conversion upload

    The cookie persists for 30 days, so a visitor who clicks your ad on Monday and fills out your form on Thursday still carries their original source data.

    You can install this snippet via Google Tag Manager (one GTM tag, fires on all pages), WPCode (a free WordPress code injection plugin), or directly in your theme’s functions.php. GTM is generally the cleaner path since it keeps tracking code version-controlled without requiring theme edits.

    Full implementation details in UTM Parameter Tracking on WordPress.

    Step 2: Create Custom Fields in ActiveCampaign

    ActiveCampaign supports custom fields at two levels: on the contact record and on the deal record. You want both.

    Contact-level fields capture attribution for every lead and enable email segmentation by source. Deal-level fields carry attribution through the pipeline so you can filter and report on revenue by channel.

    Contact-level custom fields to create:

    • Lead Source (stores utm_source)
    • Lead Medium (stores utm_medium)
    • Lead Campaign (stores utm_campaign)
    • Lead Term (stores utm_term)
    • Lead Content (stores utm_content)
    • Landing Page
    • GCLID
    • FBCLID

    To create these: go to Contacts > Manage Fields, add each as a Text field. Note the field IDs — you will need them when mapping form fields to AC fields.

    Deal-level custom fields:

    Go to Deals > Manage Fields and add a “Lead Source” field at minimum. You can mirror the full set if you want campaign-level deal filtering. These fields get populated automatically via an automation (Step 4), not by the form submission itself.

    Step 3: Connect Your WordPress Forms to ActiveCampaign

    There are three reliable paths for getting form submissions — including hidden UTM fields — into ActiveCampaign from WordPress.

    Option A: WordPress Form Plugin with Native AC Integration

    This is the cleanest approach for most setups. Several form plugins have built-in ActiveCampaign integrations that map form fields directly to AC contact fields:

    • Gravity Forms with the ActiveCampaign Add-On: full field mapping, supports hidden fields pre-populated from cookies via a small JS snippet
    • WPForms with ActiveCampaign integration: similar capability, simpler setup
    • Fluent Forms with AC integration: lightweight option with solid field mapping support

    The workflow: add hidden fields to your form (one per UTM value), use JavaScript to populate them from the stored cookies on page load, then map each hidden field to the corresponding AC contact field in the plugin’s integration settings.

    Option B: ActiveCampaign’s Native WordPress Plugin

    ActiveCampaign’s official WordPress plugin lets you embed their hosted forms directly on pages. These forms support hidden fields, but they render in an iframe — which can complicate hidden field injection. Test carefully before relying on this path for attribution capture.

    Option C: Webhook to the ActiveCampaign API

    For full control without a form plugin dependency, you can POST form data directly to ActiveCampaign’s Contacts API. Your form fires a webhook on submission; a Zapier zap or server-side function creates or updates the AC contact with all attribution fields included.

    More setup, but complete flexibility. This path also makes it straightforward to handle duplicate contacts (look up by email first, then update rather than create).

    For a deeper comparison of all three paths across CRM platforms, see CRM Integration for WordPress.

    Step 4: Copy Attribution to Deals via Automations

    When a contact is created from a form submission, an ActiveCampaign automation can immediately create a deal and copy attribution fields from the contact to the deal record.

    Build this automation in the Automations builder:

    1. Trigger: Contact is created (or submits a specific form)
    2. Action: Create a deal in your pipeline with the contact’s name and source info as the deal title
    3. Action: Update deal field “Lead Source” = contact field “Lead Source”
    4. Repeat the Update action for each field you want mirrored (campaign, medium, GCLID, etc.)

    This runs at the moment of contact creation, so attribution is on the deal from day one. The sales team sees the source in the deal card without having to cross-reference the contact record.

    Step 5: Build Deal-Level Attribution Reports

    Once deal-level fields are populated, you can filter your pipeline by channel and see which sources are generating actual revenue — not just lead volume.

    Two views worth building:

    Open pipeline by source: Filter deals by the “Lead Source” field to see how much pipeline value is sitting from Google Ads vs. organic vs. referral. This shows you where your best-value prospects are coming from before deals close.

    Won deals by campaign: Filter closed-won deals by “Lead Campaign” to compare revenue by campaign. A campaign generating $40K in won deals at a $6K cost looks completely different from one generating 30 leads at $120 each with a 5% close rate.

    ActiveCampaign’s built-in reporting is limited, but deal-view filtering on custom fields is enough to make channel-level spend decisions without exporting to a spreadsheet. For deeper reporting, export won deals with attribution fields to a Google Sheet and build a simple pivot table.

    Step 6: Close the Loop with Offline Conversion Upload

    If you are running Google Ads or Meta Ads, you can push won deals back to the ad platforms as offline conversions. This tells the platforms which clicks actually turned into clients — not just form fills.

    Google Ads: When a deal is marked won in ActiveCampaign, trigger an automation that fires a webhook containing the stored gclid and a conversion event name. A Zapier zap catches this and uploads the conversion to Google Ads via the Conversions API. Google attributes the closed client back to the specific campaign, ad group, and keyword that drove the click — and Smart Bidding learns to favor the placements that generate revenue, not just form submissions.

    Meta Ads: The same process applies using the fbclid stored in the deal record. Send the event to Meta’s Conversions API when a deal closes. This improves Meta’s optimization signal and reduces underreporting caused by iOS privacy restrictions.

    Full setup details in Google Ads Conversion Tracking on WordPress and Meta Ads Conversion Tracking on WordPress.

    The Full Stack, End to End

    Here is what the complete attribution chain looks like for an ActiveCampaign and WordPress setup:

    1. Visitor clicks a Google Ads ad; URL contains UTM parameters and gclid
    2. JavaScript fires on landing and stores utm_source, utm_medium, utm_campaign, utm_term, gclid in first-party cookies (30-day expiration)
    3. Visitor fills out your contact form; hidden fields are populated from the cookies
    4. Form plugin sends the contact to ActiveCampaign with all attribution fields mapped to custom contact fields
    5. ActiveCampaign automation creates a deal and copies attribution fields to the deal record
    6. Sales team works the deal in the pipeline with full source and campaign visibility
    7. Deal is marked won; automation fires a webhook with gclid to Google Ads offline conversion upload
    8. Google Ads Smart Bidding now optimizes for closed clients, not form fills

    The same chain works for Meta Ads (fbclid), organic search (utm_medium=organic), email campaigns (utm_source=email), and any other channel with UTM tagging.

    Related Guides

  • UTM Parameter Tracking on WordPress: How to Capture Lead Source Data and Keep It

    If you are running paid ads and relying on your ad platform’s dashboard to tell you which campaigns are generating leads, you are missing part of the picture. Ad platforms count clicks. UTM parameters let you count what happens after the click: form submissions, phone calls, and ultimately closed deals.

    This guide covers how UTM parameter tracking works on WordPress, how to pass UTM data through to your lead records, and how to use that data to make better decisions about where to spend your marketing budget.

    What UTM Parameters Are (and Why They Matter)

    UTM parameters are small tags you append to a URL. When someone clicks a link with UTM tags, those values land in the URL bar, and your tracking tools can read them. A tagged URL looks like this:

    https://example.com/landing-page/?utm_source=google&utm_medium=cpc&utm_campaign=summer-promo

    The five standard UTM parameters:

    • utm_source — where the traffic is coming from (google, facebook, email, newsletter)
    • utm_medium — the type of traffic (cpc, organic, social, email)
    • utm_campaign — the specific campaign name (summer-promo, brand-search, retargeting)
    • utm_content — the specific ad or link variant (useful for A/B testing)
    • utm_term — the keyword that triggered the ad (usually auto-populated by Google Ads)

    When these values are in the URL, GA4 can attribute the session to the right source. But GA4 only sees the session — it does not see the lead form submission in the context of the original source unless you capture and store the UTM data yourself.

    The Core Problem: UTMs Die When Someone Submits a Form

    Here is the gap that most WordPress sites have. A visitor arrives from a Google Ads click. Their URL has utm_source=google and utm_campaign=brand-search. They spend 3 minutes on your site, then submit a contact form. That form submission lands in your inbox or CRM with their name, email, and message — but no UTM data. You cannot tell whether this lead came from Google Ads, organic search, or a direct visit.

    Multiply this across 50 leads a month and you have a marketing team making budget decisions based on incomplete information.

    The solution is a two-step process: capture the UTM values when someone first lands, and carry them through to the form submission.

    How to Capture UTM Parameters in WordPress

    Step 1: Store UTMs in a first-party cookie on landing

    When a visitor arrives with UTM parameters in the URL, a small JavaScript snippet reads those values and saves them in a first-party cookie. That cookie persists for 30 days (or whatever window you set), so even if the visitor leaves and comes back without UTMs in the URL, you still have the original attribution data.

    The script runs on page load, checks for UTM values in the URL, and writes them to cookies only if they are present (so a returning visitor’s original attribution is not overwritten by a direct visit).

    // Capture UTMs on first touch, store in cookies for 30 days
    (function() {
      var params = new URLSearchParams(window.location.search);
      var utms = ['utm_source','utm_medium','utm_campaign','utm_content','utm_term'];
      utms.forEach(function(key) {
        var val = params.get(key);
        if (val) {
          document.cookie = key + '=' + encodeURIComponent(val) + '; path=/; max-age=2592000; SameSite=Lax';
        }
      });
    })();

    Add this to your WordPress site via a plugin like WPCode, through your theme’s functions.php, or through Google Tag Manager as a Custom HTML tag triggered on All Pages.

    Step 2: Pull UTM cookies into hidden form fields

    Your contact form (whether it is Gravity Forms, WPForms, Contact Form 7, or another plugin) should have hidden fields that read the UTM cookie values and include them in the submission. When someone submits the form, the UTM values travel with the lead data.

    Hidden field setup (in Gravity Forms as an example): add a Hidden field for each UTM parameter and set its default value to a JavaScript snippet that reads the corresponding cookie. Most form plugins support dynamic default values via a parameter name or a short code.

    The pattern: each hidden field reads its cookie value on page load and populates automatically. The user never sees these fields. The form submission includes both the visible data the user entered and the UTM attribution data you captured in the background.

    Passing UTM Data to Your CRM or Email Platform

    Once UTM values are in your form submission, they need to land somewhere useful. A few options:

    • Email notification: the simplest path — your form sends a notification email that includes all field values. The UTM fields show up alongside name, email, and message. Works immediately with no integration.
    • CRM via Zapier or native integration: map the UTM hidden fields to custom fields in your CRM. Now each deal record shows source, medium, and campaign. When a deal closes, you can trace it back to the originating campaign.
    • Google Sheet as a lead log: route form submissions to a sheet with columns for all UTM parameters plus timestamp, name, email, and message. A simple way to see lead source distribution without a CRM.

    What to Do With UTM Data Once You Have It

    UTM data becomes valuable when you connect it to outcomes, not just volume. A few questions it lets you answer:

    • Which campaigns generate the most leads? Basic source/medium/campaign breakdown. Google Ads vs. organic vs. Facebook vs. email.
    • Which campaigns close at the highest rate? If you track deal outcomes in a CRM, you can pull close rate by utm_campaign. A campaign generating 20 leads at 5% close rate is worth less than one generating 8 leads at 40% close rate.
    • Which keywords drive qualified leads vs. browsers? utm_term populated from Google Ads auto-tagging tells you exactly which search query preceded each lead. You can pause terms that generate volume but not closed business.
    • Which ad variants convert better? utm_content lets you tag individual ads or email links differently. If Ad A and Ad B send equal traffic but Ad A generates twice the form submissions, that is a clear signal.

    gclid vs. UTM: Which Should You Use?

    Google Ads appends a gclid (Google Click ID) to URLs automatically when auto-tagging is enabled. This is separate from UTM parameters and is used for Google’s internal attribution. You should use both.

    • UTM parameters give you source/medium/campaign data that works across platforms and integrates with GA4, your CRM, and any reporting tool you use.
    • gclid enables offline conversion upload to Google Ads — where you send lead outcome data back to Google so its algorithm can optimize toward closed deals, not just form submissions.

    The right setup captures both: UTMs go into cookies and then form fields for your own reporting, while gclid is captured separately for offline conversion sync back to Google Ads.

    Common WordPress Implementation Pitfalls

    • UTMs lost on redirect: if your landing page URL redirects (www to non-www, HTTP to HTTPS, or a tracking redirect), UTM parameters can be stripped. Audit your redirect chain and make sure parameters pass through.
    • Form caching stripping values: some caching plugins prevent JavaScript from running correctly on form pages, which means hidden fields do not populate. Add form pages to your cache exclusion list.
    • Cookie consent blocking the script: if you have a GDPR consent banner that delays non-essential scripts, UTM capture may not fire until after the user accepts. For most service businesses in the US this is not a live issue, but it is worth knowing.
    • Session-scoped storage losing first touch: using sessionStorage instead of cookies means attribution is lost if the user closes their browser and returns later. Use cookies with a 30-day window for first-touch attribution.
    • Overwriting first touch on return visits: your capture script should check whether a UTM cookie already exists before overwriting. If someone clicks an organic result in week 2, you do not want to overwrite the paid ad click from week 1 that actually drove the engagement.

    UTM Tracking as Part of a Larger Attribution Stack

    UTM tracking solves the first-party data capture problem: you own the lead source data, it lives in your CRM, and it survives the gap between ad click and form submission. But it is one layer of a full attribution stack.

    • UTMs tell you source, medium, and campaign at the session level
    • Offline conversion upload connects closed deals back to campaigns in Google and Meta
    • Phone call tracking via DNI (dynamic number insertion) captures attribution for callers who never submit a form
    • Revenue attribution pulls closed deal values back into your reporting so you see revenue by source, not just lead count

    For WordPress businesses running paid search and wanting a turnkey version of this stack — UTM capture, form submission tracking, offline conversion sync, and closed-loop revenue reporting — Sales Provenance is built to handle all of it natively, without requiring a data engineer or a CRM dependency.

    Related reading: Google Ads conversion tracking on WordPress — how to set up website conversions, capture gclid, and upload offline conversions. And closed-loop reporting for WordPress — connecting ad spend to closed deal value.

  • Meta Ads Conversion Tracking on WordPress: Pixel, CAPI, and Offline Conversions

    Meta Ads conversion tracking on WordPress works differently from Google Ads, and the difference matters for how you optimize your campaigns. This guide covers the full setup: the Facebook pixel for website events, the Conversions API for server-side reliability, and the offline conversion approach that tells Meta which leads actually became paying clients — not just which ones filled out your form.

    The pixel versus the Conversions API

    Meta offers two ways to track conversions: the browser-based pixel and the Conversions API (CAPI). They are not alternatives — they are complements, and running both is the right approach for a WordPress business.

    • The Facebook pixel is a JavaScript snippet that loads in the visitor’s browser and fires events as they navigate your site. It captures form submissions, thank-you page views, and button clicks. The limitation is that it depends on the browser: ad blockers suppress it, iOS 14+ privacy changes reduce its reach, and browser crashes or navigations that happen before the script fully executes cause missed events. On a well-implemented WordPress site with GTM, the pixel typically captures 60 to 80 percent of actual conversions.
    • The Conversions API sends event data directly from your server to Meta’s servers, bypassing the browser entirely. It does not get blocked by ad blockers or affected by browser privacy settings. CAPI does not replace the pixel — it supplements it by capturing the conversions the pixel misses. The combination of pixel plus CAPI, with deduplication enabled, consistently outperforms pixel-only tracking on both match rate and event volume.

    Running both with event deduplication (using a shared event ID) is the current Meta best practice and the setup that gives your campaigns the most accurate conversion signal.

    Step 1: Install the pixel and configure standard events

    The pixel installs via Google Tag Manager or a Meta-provided WordPress plugin. GTM gives you more control and is preferred for most setups:

    1. In Meta Events Manager, create a pixel and copy the base code.
    2. In GTM, create a Custom HTML tag with the pixel base code, firing on All Pages.
    3. Create a separate tag for the Lead event, firing on your thank-you page (the same trigger you use for Google Ads conversion tracking). The Lead event is the right standard event for contact form completions — it is more specific than PageView and is what Meta’s ad delivery algorithm optimizes toward when you run Lead Generation campaigns.
    4. Publish the GTM container and verify in Meta Events Manager’s Test Events tool by submitting a test form and confirming the Lead event fires.

    If you are running contact forms on WordPress with WPForms, Gravity Forms, or Contact Form 7, the thank-you page redirect approach (the same one recommended for Google Ads) is the most reliable trigger for the Lead event. Form submission JavaScript triggers vary in reliability across plugins; the redirect does not.

    Step 2: Add the Conversions API for server-side reliability

    The Conversions API requires sending event data to Meta’s API endpoint from your server. On WordPress, there are a few implementation paths:

    • The Meta Business Extension / WordPress plugin provides a built-in CAPI integration. It connects your WordPress site to Meta’s server and sends pixel events server-side automatically. This is the easiest path if you do not need deep customization — install, connect your Meta account, enable CAPI, and the plugin handles deduplication.
    • Custom server-side implementation via a webhook or server function gives you more control over which events send, what customer data is included, and how deduplication is handled. This is the right approach if you are capturing lead source data (UTMs, gclids) and want to pass that data alongside the conversion event for richer attribution.
    • GTM Server-Side container can route pixel events through a server-side GTM container before sending to Meta, providing some of the benefits of CAPI with a GTM-familiar interface. More infrastructure to maintain but good for organizations already using server-side GTM.

    Whichever path you choose, enable event deduplication by passing a consistent event_id that matches between your pixel and CAPI implementations. Without deduplication, Meta counts the same conversion twice — once from the browser and once from the server — inflating your reported conversion numbers.

    Step 3: Pass customer data for better match rates

    Meta matches your conversion events to Meta user accounts using customer data: email address, phone number, name, and location. The more data you pass, the higher the match rate — and match rate directly affects how many of your conversions Meta can attribute to your ads.

    On a contact form submission, you typically have the lead’s email address and phone number. Include these in your CAPI event payload, hashed with SHA-256 (Meta requires hashing for privacy compliance). The pixel can also pass this data client-side via the fbq('track', 'Lead', {em: hashedEmail}) call, though server-side via CAPI is more reliable because it does not depend on the user’s browser.

    Passing hashed email and phone consistently is the single highest-leverage improvement most WordPress businesses can make to their Meta conversion tracking match rates. Match rates of 40 to 60 percent are common without customer data; 70 to 90 percent are achievable with it.

    Step 4: Offline conversions — the step that actually optimizes toward revenue

    Website and CAPI conversion tracking tells Meta who submitted a form. Offline conversion tracking tells Meta who became a paying client. The difference is the same as with Google Ads: if your business closes 1 in 8 leads, Meta’s “optimize for conversions” bidding will try to get you more form fills, not more clients, unless you tell it which form fills converted.

    Meta’s offline conversions API accepts customer records from your closed deals — matched against the lead’s email, phone, or name — and attributes each won customer to the original ad click that generated the lead. Your campaigns can then optimize toward a Purchase or CustomEvent that represents a closed client, rather than a Lead event that represents a form submission.

    The implementation requires:

    • A way to track which leads become clients (a CRM, a spreadsheet with a “closed” field, or a lead management interface in your WordPress backend).
    • A process for uploading closed deals to Meta periodically — weekly manual uploads via Meta Events Manager, or automated via the offline conversions API when a deal is marked won.
    • Customer data from the original lead (email or phone) for Meta to match the offline event to the original ad interaction.

    Businesses that implement offline conversion feedback to Meta consistently report that their campaigns shift toward higher-quality leads over time, even at the same budget. The algorithm is optimizing toward a stronger signal.

    How this compares to Google Ads conversion tracking

    The workflow is similar: capture UTM parameters and source data at the point of form submission, track the lead through to a closed sale, and feed the won outcome back to the ad platform. The technical implementation differs (gclid for Google, fbclid or customer data matching for Meta), but the attribution strategy is the same. If you have already implemented Google Ads offline conversion tracking on WordPress, most of the infrastructure you built — UTM capture, lead management, closed-deal tracking — applies directly to Meta with relatively minor additions.

    For a detailed walkthrough of the Google Ads side of this, see Google Ads conversion tracking on WordPress. For the broader picture of how closed-loop attribution works across channels, closed-loop reporting on WordPress covers the full workflow.

    How Sales Provenance fits

    Sales Provenance handles the data infrastructure that both Google Ads and Meta Ads offline conversion tracking require: capturing source data (UTMs, fbclid, gclid) at form submission, storing it with each lead in your WordPress database, providing a lead management interface to track which leads close, and syncing the won outcomes back to both platforms as offline conversions. The pixel and CAPI setup is separate (Meta-side configuration), but the lead-to-client matching and offline conversion sync is what SP is built to handle.

    If you are running both Google and Meta ads and want a single system that closes the attribution loop for both, revenue attribution on WordPress explains how the pieces fit together.

  • How to Set Up Google Ads Conversion Tracking on WordPress (The Right Way)

    Setting up Google Ads conversion tracking on WordPress sounds straightforward until you realize that “conversion tracking” actually refers to two different things — and most WordPress businesses are only doing one of them. This guide covers both: the website conversion tracking that most people set up, and the offline conversion tracking that actually tells Google which clicks turned into paying clients. The second one is harder to implement, but it is where most of the optimization value lives.

    Two ways to track Google Ads conversions on WordPress

    The distinction matters because Google uses conversion data to optimize your campaigns. What you feed it determines what it optimizes toward.

    • Website conversions track actions that happen on your site: form submissions, thank-you page visits, button clicks, phone call clicks. These are easy to set up and give Google a signal for every lead that comes in. The problem is that leads are not revenue. If 100 people fill out your form and 8 become paying clients, Google’s “maximize conversions” bidding does not know which 8 — it just tries to get you more form fills, regardless of quality.
    • Offline conversions close the loop. You capture the Google click ID (gclid) when the lead arrives, match it to the customer after they close, and send that won outcome back to Google as a conversion. Now Google knows: these specific clicks, these specific keywords, this specific audience segment produced paying clients. Its bidding algorithm can optimize toward that signal instead of toward raw lead volume.

    Most WordPress businesses do the first. The ones that do the second get meaningfully better results from the same ad spend.

    Step 1: Set up website conversion tracking

    Start here if you have not already. You need Google Tag Manager installed on your WordPress site and a Google Ads account linked to it.

    The most reliable method for form submission tracking on WordPress is the thank-you page approach:

    1. Create a dedicated thank-you page (e.g., /thank-you/) that contact form submitters are redirected to after submitting.
    2. In Google Tag Manager, create a trigger: Page View firing on URL contains /thank-you/.
    3. Create a tag: Google Ads Conversion Tracking, using your conversion action ID and label from Google Ads. Set it to fire on the thank-you page trigger.
    4. Publish the GTM container and verify in GTM’s Preview mode by submitting a test form and confirming the tag fires.

    The alternative — using form submission events directly — requires custom dataLayer pushes that vary by form plugin (Contact Form 7, WPForms, Gravity Forms each work differently). The thank-you page redirect is more reliable and plugin-agnostic.

    For phone calls, use Google’s forwarding number in your Google Ads call extension. This gives you call tracking without any tag setup, though it only captures clicks from your ads, not organic or direct calls.

    Step 2: Capture the gclid at form submission

    This is the step that makes offline conversion tracking possible. When someone clicks a Google ad and lands on your site, Google appends a gclid parameter to the URL. You need to capture that parameter and store it alongside the lead’s form submission data.

    The implementation has three parts:

    • Read the gclid from the URL on page load. A small JavaScript snippet reads gclid from the URL query string and stores it in a first-party cookie with a 90-day expiration. This handles the case where someone clicks your ad, bounces, and returns days later — the cookie persists across sessions.
    • Add a hidden field to your contact form. A hidden form field named gclid reads from the cookie on page load and populates automatically. When the form submits, the gclid travels with the lead data to wherever your form stores submissions.
    • Store the gclid with the lead record. Your form plugin or CRM needs to save the gclid value alongside the lead’s name, email, phone, and other contact fields. If you are not storing it, you cannot match it to a sale later.

    The same approach applies to UTM parameters (utm_source, utm_campaign, utm_term): capture them from the URL on landing, store in cookies, pass via hidden fields, save with the lead. This gives you full source attribution even when Google Ads is not involved.

    Step 3: Match leads to clients and upload offline conversions

    When a lead becomes a paying client, you match the gclid stored on their lead record to a Google Ads offline conversion upload. Google matches that gclid to the original click and counts it as a conversion — a won customer, not just a form fill.

    There are two ways to send offline conversions to Google:

    • Manual CSV upload — in Google Ads, go to Tools > Conversions > Upload. Prepare a CSV with three columns: Google Click ID, Conversion Name, Conversion Time (and optionally Conversion Value). Upload it. Google processes the file and attributes the conversions to the original clicks. This works for businesses that close a manageable number of deals per month and are willing to run the upload on a regular schedule (weekly is common).
    • API upload (automated) — using Google’s Ads API or a platform that integrates with it, you can send offline conversions automatically as soon as a deal is marked won in your system. This eliminates the manual step and keeps Google’s data current without a weekly reminder. It requires either custom development or a tool that handles the API connection for you.

    Either way, the conversion data feeds Google’s smart bidding algorithms: Target CPA and Target ROAS bidding can now optimize toward clients, not leads. The improvement in campaign efficiency is typically significant — you are giving the algorithm a fundamentally better signal to work with.

    The WordPress-specific challenge

    WordPress does not have native lead-to-sale tracking. It accepts form submissions, but it does not natively store UTM parameters or gclid values, does not have a built-in CRM to mark deals won, and does not connect to Google Ads for offline conversion uploads. Each of those steps requires either custom development, a plugin, or a third-party integration.

    The most common failure mode is partial implementation: a business sets up form tracking in GTM, captures some UTM parameters, but never builds the gclid capture-and-store step or the offline conversion upload. The result is website conversion data flowing to Google, but no closed-loop signal. Google optimizes toward form fills and the business wonders why lead quality is inconsistent.

    The full stack — gclid capture, UTM storage, lead records with source data, closed-deal matching, offline conversion upload — requires deliberate implementation. Once it is in place, it runs automatically and compounds over time as Google’s algorithm accumulates more closed-customer signal.

    How Sales Provenance handles this on WordPress

    Sales Provenance is built to implement this entire workflow natively on WordPress, without custom development. It installs as a WordPress plugin, captures gclid and UTM parameters automatically on every landing page visit, stores them with every form submission, provides a lead management interface where you mark deals won, and handles the offline conversion upload to Google Ads automatically.

    The result is the full closed-loop attribution stack — from ad click through to closed client and back to Google — running inside your WordPress site without a separate CRM, a data warehouse, or a developer on retainer. For a more detailed look at how the offline conversion piece works, see offline conversion tracking on WordPress. For the broader picture of what closed-loop attribution looks like in practice, closed-loop reporting walks through the full workflow.

    Summary: the implementation checklist

    • Install Google Tag Manager on WordPress
    • Create thank-you page + GTM trigger for website conversion tracking
    • Add gclid capture script (reads URL, stores in first-party cookie)
    • Add hidden gclid field to all contact forms
    • Confirm gclid is stored with every lead record
    • Do the same for UTM parameters (source, campaign, term, content)
    • Establish process for marking leads as won clients
    • Upload offline conversions to Google Ads (manually weekly or via API)

    Each step builds on the previous one. You can stop at website conversions and have better-than-nothing tracking. But the full stack — with offline conversion upload — is where the optimization value actually lives.

  • WordPress UTM Tracking: Why Your Setup Has a Gap (and What to Fill It)

    If you run paid ads on Google or Meta, you are already using UTM parameters. You put them on every ad link, your analytics show you which campaigns drove traffic, and the numbers look good.

    The problem shows up two weeks after a campaign ends, when you look at actual sales and try to figure out which campaign drove them. Your analytics shows sessions and leads. Your CRM shows closed deals. The two lists do not match up.

    This is the UTM tracking gap: the click data and the revenue data live in separate systems, and nothing connects them. WordPress UTM tracking solves the first half of the problem (capturing UTMs from clicks into leads). Closing the full loop — all the way to the sale — requires one more step that most WordPress setups skip.

    How UTM Tracking Works (and Where It Breaks)

    When a visitor clicks your Google Ad, the URL they land on includes UTM parameters like ?utm_source=google&utm_medium=cpc&utm_campaign=spring-campaign. Those parameters tell you where the visitor came from.

    A basic WordPress setup reads those parameters from the URL and stores them in the visitor’s browser session. When the visitor fills out a form, the UTM values get submitted along with their name and email. Your CRM or email platform records the lead source.

    This works — until it does not. Common failure points:

    • The visitor leaves and comes back. Most session-based UTM capture only survives a single browsing session. If someone clicks your ad on Monday and books a call on Thursday, the UTM is gone. First-touch or last-touch attribution is wrong.
    • Cross-device visits. Someone sees your ad on their phone, then books a call on their laptop. The UTM never makes it to the form submission.
    • The form is not your form. If you use Calendly, Typeform, JotForm, or any embedded third-party form, UTMs captured on your site often do not pass through to the submission record.
    • Phone calls. Most UTM tracking only works for form fills. A visitor who clicks your ad and calls you instead of filling a form is invisible in UTM reports — even though the ad drove the lead.

    First-Party Cookie Storage: The Fix for Multi-Session Visits

    The standard fix for losing UTMs across sessions is to write them to a first-party cookie on the visitor’s first touch, then read that cookie at form submission time even if the visit happened days ago.

    This is better than session storage. Cookies persist across sessions (you control how long — 30, 60, 90 days is common). If the visitor returns from a different source, you can decide whether to overwrite (last-touch model) or keep the original value (first-touch model).

    Most UTM tracking plugins for WordPress use this approach. The catch: even with cookies capturing UTMs correctly on your site, you still face the phone-call gap and the disconnection from actual revenue.

    The Step Most WordPress Sites Skip: Connecting UTMs to the Sale

    Let us say your UTM tracking is working. A visitor clicks a Google ad, fills out your contact form, and the lead lands in your CRM with the correct UTM values. Now what?

    If your sales cycle is longer than a day — most service businesses, most B2B — a significant amount of time passes between that lead submission and a closed deal. During that time, a salesperson works the lead, sends proposals, maybe has three calls. Eventually the deal closes, or it does not.

    Your Google Ads account records a conversion when the form was filled. It does not know whether the deal closed. When you look at campaign performance, you see cost-per-lead, not cost-per-customer. If 40% of your leads from one campaign close and 10% from another do, you are optimizing for the wrong signal.

    Closing this loop requires pushing a conversion signal back to Google or Meta when the deal actually closes — what Google calls an offline conversion import. The UTM you captured at lead submission is what lets you match the closed deal back to the original campaign.

    Phone Calls: The UTM Gap Nobody Talks About

    For any business that gets a meaningful portion of leads by phone, UTM tracking is incomplete by default. A visitor clicks your Google ad, lands on your site, and calls the number they see. There is no form fill, no UTM capture. Google Ads may record a call conversion if you are using call extensions, but the lead never hits your CRM with attribution data.

    The fix is call tracking with dynamic number insertion (DNI). A tracking system swaps the phone number displayed on your site with a unique tracking number based on how the visitor arrived. When they call, the call is matched to the UTM source and the call record is logged with that attribution data. The lead enters your pipeline with a source, just like a form fill.

    This is what a complete WordPress UTM tracking setup looks like: first-party cookies for multi-session form fills, DNI for phone calls, and offline conversion imports when deals close. The result is a report that shows you which campaigns drove revenue, not just which campaigns drove activity.

    What to Look For in a WordPress UTM Tracking Setup

    Before choosing a tool or building a setup, confirm it handles these five things:

    1. First-party cookie storage with a configurable persistence window (30+ days)
    2. UTM passthrough to form submissions — including third-party embeds if you use them
    3. Call tracking with DNI so phone leads carry the same attribution as form leads
    4. CRM logging — UTM values stored on the contact or lead record, not just in analytics
    5. Closed-loop export — a way to push a conversion signal back to Google or Meta when a deal closes, using the GCLID or FBCLID captured at the original click

    Most UTM plugins handle item 1 and sometimes item 2. Items 3 through 5 are where the standard WordPress approach falls short. They require either building a custom integration or using a platform that was designed for the full loop from the start — like Sales Provenance, which was built specifically for service businesses running paid traffic on WordPress who need to connect clicks to closed revenue.

    If you are currently looking at UTM reports and working backwards from sessions to guess which campaigns are producing revenue, the gap is fixable. The technical setup is not complex — it just has to cover all five layers, not just the first two.

  • WordPress UTM Tracking: Why Your Setup Has a Gap (and What to Fill It)

    If you run paid ads on Google or Meta, you are already using UTM parameters. You put them on every ad link, your analytics show you which campaigns drove traffic, and the numbers look good.

    The problem shows up two weeks after a campaign ends, when you look at actual sales and try to figure out which campaign drove them. Your analytics shows sessions and leads. Your CRM shows closed deals. The two lists do not match up.

    This is the UTM tracking gap: the click data and the revenue data live in separate systems, and nothing connects them. WordPress UTM tracking solves the first half of the problem (capturing UTMs from clicks into leads). Closing the full loop — all the way to the sale — requires one more step that most WordPress setups skip.

    How UTM Tracking Works (and Where It Breaks)

    When a visitor clicks your Google Ad, the URL they land on includes UTM parameters like ?utm_source=google&utm_medium=cpc&utm_campaign=spring-campaign. Those parameters tell you where the visitor came from.

    A basic WordPress setup reads those parameters from the URL and stores them in the visitor’s browser session. When the visitor fills out a form, the UTM values get submitted along with their name and email. Your CRM or email platform records the lead source.

    This works — until it does not. Common failure points:

    • The visitor leaves and comes back. Most session-based UTM capture only survives a single browsing session. If someone clicks your ad on Monday and books a call on Thursday, the UTM is gone. First-touch or last-touch attribution is wrong.
    • Cross-device visits. Someone sees your ad on their phone, then books a call on their laptop. The UTM never makes it to the form submission.
    • The form is not your form. If you use Calendly, Typeform, JotForm, or any embedded third-party form, UTMs captured on your site often do not pass through to the submission record.
    • Phone calls. Most UTM tracking only works for form fills. A visitor who clicks your ad and calls you instead of filling a form is invisible in UTM reports — even though the ad drove the lead.

    First-Party Cookie Storage: The Fix for Multi-Session Visits

    The standard fix for losing UTMs across sessions is to write them to a first-party cookie on the visitor’s first touch, then read that cookie at form submission time even if the visit happened days ago.

    This is better than session storage. Cookies persist across sessions (you control how long — 30, 60, 90 days is common). If the visitor returns from a different source, you can decide whether to overwrite (last-touch model) or keep the original value (first-touch model).

    Most UTM tracking plugins for WordPress use this approach. The catch: even with cookies capturing UTMs correctly on your site, you still face the phone-call gap and the disconnection from actual revenue.

    The Step Most WordPress Sites Skip: Connecting UTMs to the Sale

    Let us say your UTM tracking is working. A visitor clicks a Google ad, fills out your contact form, and the lead lands in your CRM with the correct UTM values. Now what?

    If your sales cycle is longer than a day — most service businesses, most B2B — a significant amount of time passes between that lead submission and a closed deal. During that time, a salesperson works the lead, sends proposals, maybe has three calls. Eventually the deal closes, or it does not.

    Your Google Ads account records a conversion when the form was filled. It does not know whether the deal closed. When you look at campaign performance, you see cost-per-lead, not cost-per-customer. If 40% of your leads from one campaign close and 10% from another do, you are optimizing for the wrong signal.

    Closing this loop requires pushing a conversion signal back to Google or Meta when the deal actually closes — what Google calls an offline conversion import. The UTM you captured at lead submission is what lets you match the closed deal back to the original campaign.

    Phone Calls: The UTM Gap Nobody Talks About

    For any business that gets a meaningful portion of leads by phone, UTM tracking is incomplete by default. A visitor clicks your Google ad, lands on your site, and calls the number they see. There is no form fill, no UTM capture. Google Ads may record a call conversion if you are using call extensions, but the lead never hits your CRM with attribution data.

    The fix is call tracking with dynamic number insertion (DNI). A tracking system swaps the phone number displayed on your site with a unique tracking number based on how the visitor arrived. When they call, the call is matched to the UTM source and the call record is logged with that attribution data. The lead enters your pipeline with a source, just like a form fill.

    This is what a complete WordPress UTM tracking setup looks like: first-party cookies for multi-session form fills, DNI for phone calls, and offline conversion imports when deals close. The result is a report that shows you which campaigns drove revenue, not just which campaigns drove activity.

    What to Look For in a WordPress UTM Tracking Setup

    Before choosing a tool or building a setup, confirm it handles these five things:

    1. First-party cookie storage with a configurable persistence window (30+ days)
    2. UTM passthrough to form submissions — including third-party embeds if you use them
    3. Call tracking with DNI so phone leads carry the same attribution as form leads
    4. CRM logging — UTM values stored on the contact or lead record, not just in analytics
    5. Closed-loop export — a way to push a conversion signal back to Google or Meta when a deal closes, using the GCLID or FBCLID captured at the original click

    Most UTM plugins handle item 1 and sometimes item 2. Items 3 through 5 are where the standard WordPress approach falls short. They require either building a custom integration or using a platform that was designed for the full loop from the start — like Sales Provenance, which was built specifically for service businesses running paid traffic on WordPress who need to connect clicks to closed revenue.

    If you are currently looking at UTM reports and working backwards from sessions to guess which campaigns are producing revenue, the gap is fixable. The technical setup is not complex — it just has to cover all five layers, not just the first two.

  • Report Move-Ins, Not Leads: How Offline Conversion Tracking Fixes WordPress Marketing

    Most WordPress businesses optimize their marketing toward the wrong finish line. They count form fills, phone calls, and quote requests, and then pour budget into whatever produces the most of them. The problem is that leads are not customers. The campaign that generates the most leads is very often not the campaign that generates the most revenue, and if you cannot tell the two apart, you are spending money to attract the wrong people.

    Offline conversion tracking is how you fix that. It closes the loop between a click and a closed sale, and it is the single highest-leverage upgrade most WordPress businesses can make to their marketing measurement.

    The gap: your ad platform stops watching at the form

    Here is what happens today on a typical WordPress site. Someone clicks your Google or Meta ad, lands on your site, and fills out a form. The ad platform records a "conversion" and pats itself on the back. From that moment on, it is blind.

    It does not know:

    • Whether that lead ever answered the phone
    • Whether they were a real prospect or a tire-kicker
    • Whether they signed, bought, moved in, or booked the job
    • How much that sale was actually worth

    So when Google or Meta optimizes your campaigns, it is optimizing toward form fills, because that is the last thing it can see. It will happily find you more of whatever kind of person tends to fill out forms, even if those people rarely become customers. You get a dashboard full of cheap leads and a sales team that quietly complains the leads are junk.

    The fix: send the real outcome back to the platform

    Offline conversion tracking feeds the truth back into the system. When a lead actually becomes a customer, you send that event, and ideally its real dollar value, back to Google and Meta. Now the platforms can optimize toward the outcome that matters: customers and revenue, not raw leads.

    The change in behavior is dramatic. Instead of chasing the cheapest form fill, the ad platform starts hunting for people who look like your actual buyers. Campaigns that produced lots of low-quality leads get throttled. Campaigns that produced fewer leads but better customers get scaled. You are finally paying for revenue instead of activity.

    How it works, step by step

    You do not need to rebuild your website. The mechanism is straightforward once the pieces are connected:

    1. Tag the click. When a visitor arrives from an ad, the platform attaches a click identifier (Google calls it GCLID, Meta has its own). You capture and store that identifier with the lead on your own domain, as first-party data.

    2. Carry it through to the lead record. When that visitor submits a form or calls, the click ID rides along into your CRM, attached to the actual person.

    3. Wait for the real outcome. Days or weeks later, that lead closes, buys, books the job, or moves in. Your team marks the deal won, usually with a dollar value.

    4. Send the conversion back. That won deal, paired with its original click ID and value, gets uploaded back to Google Ads and Meta as an offline conversion. The platform matches it to the original click and updates what it knows.

    5. Let the algorithm relearn. With real outcomes flowing in, smart bidding stops chasing cheap leads and starts chasing customers.

    Why this is hard on WordPress today

    The reason most WordPress businesses do not do this is not that it is complicated in theory. It is that the pieces live in different places that do not talk to each other.

    The click ID is captured by a tag. The lead lands in a form plugin or a CRM. The sale gets marked won in yet another system, often a spreadsheet or the owner's head. Stitching those together, holding the click ID for weeks, and uploading clean conversions back to two ad platforms on a schedule is exactly the kind of plumbing that never gets built, so it never gets built.

    That is the gap. The data exists, scattered across your tools. Nobody has connected it end to end.

    What good looks like

    When offline conversion tracking is working, your marketing reports change in a way you can feel:

    • Your reports show revenue and customers, not just leads.
    • You can finally answer "which campaign actually drives sales?" with data instead of a hunch.
    • Your ad platforms get smarter every week, because they are learning from real outcomes.
    • Your sales team stops complaining about lead quality, because the system is now optimizing for the leads they can actually close.

    This is the difference between marketing that looks busy and marketing that is accountable to the bottom line.

    Where to start

    Ask yourself one question: if I marked a deal "won" in my system today, would Google and Meta ever find out?

    For almost every WordPress business, the answer is no. The click ID was never captured, or it was captured and never connected to the sale, or the sale lives somewhere the ad platforms will never see. That broken connection is costing you, quietly, every single day your campaigns optimize toward the wrong goal.

    Closing that loop, capturing the click on your own domain, carrying it to the sale, and feeding the real outcome back to the platforms, is exactly what Sales Provenance was built to do for WordPress, without moving you off the platform you already run on.