Ringba Webhook Says ‘Success,’ Google Match Rate Sits at 40%: The Pre-Hash Normalization Step Killing Your Enhanced Conversions Setup for Call Tracking Platforms

Article title on dark teal background with green accents, about Ringba webhook success and 40% Google match rate.

Share This Post

TL;DR

  • A green “delivered” status in Ringba, Invoca, or CallRail does not mean Google Ads accepted the conversion for Smart Bidding. The call platform reports webhook delivery. Google reports match rate, and the two numbers diverge.
  • The silent failure is phone format. Google hashes +15551234567 on its side. If your call platform hashed (555) 123-4567 or 5551234567, the SHA-256 outputs do not line up and the row drops with no error.
  • Four schema fields decide your match rate: email_address, phone_number, the address tuple, and gclid. A partial address payload (postal code only) is read as an incomplete tuple, not a missing one.
  • The fix is a pre-hash normalization layer between the dialer and Google’s ConversionUploadService, not a toggle inside Ringba, Invoca, or CallRail.
  • If your gclid passthrough is clean, Offline Conversion Imports is worth A/B testing against Enhanced Conversions for Leads. For publisher-sourced pay-per-call traffic where gclid does not survive the hop, EC for Leads is the only viable path.

Questions this article answers:

Your Call Platform Reports Success. Google Ads Reports Match Rate. They Are Not the Same Event.

The webhook log inside Ringba, Invoca, or CallRail tells you the call platform sent the payload. It does not tell you Google accepted it for bidding. Those are two different events on two different systems, and the gap between them is where most call accounts lose their Smart Bidding signal.

Here is what is actually happening. The call platform fires its webhook. Google’s API returns a 200 OK. The call platform marks the conversion as delivered. Meanwhile, Google’s matcher takes the hashed user data, applies its own normalization rules to the click-side values, and compares hashes. When the hashes do not line up, the row drops from the match pool. No hard error. No red flag in the call platform UI. Just a quietly lower match rate buried inside the Google Ads conversion diagnostic.

The whole google ads enhanced conversions setup for call tracking platforms problem comes down to this: Enhanced Conversions for Leads was built around website lead flows, where the Google tag or a tag manager can capture user-provided data on a form fill and pass it cleanly to the upload. Call platforms inherited the API spec without inheriting that normalization layer. They hash whatever string format the publisher landing page or the IVR captured, and the SHA-256 output does not line up with what Google hashed on its side.

Four fields decide your match rate: email_address, phone_number, the address tuple, and gclid. Get them wired correctly and match rate climbs. Get any one wrong and you bleed bidding signal. The rest of this article maps each field, shows where Ringba, Invoca, and CallRail each break it, and gives you the normalization layer that fixes it.

What Match Rate Actually Means, and Where the Real Number Hides

Match rate is the percentage of uploaded conversions that Google tied back to an ad click using the hashed user data you sent. The math is simple: conversions Google matched divided by conversions you uploaded with user-provided data.

Key Concept: Smart Bidding does not optimize toward conversions you reported. It optimizes toward conversions Google could attribute, which means matched conversions. If 200 calls upload and 80 match, Smart Bidding is learning from 80 events, not 200. Cut your match rate in half and you cut your usable bidding signal in half, regardless of what your conversion column shows.

How to read the conversion action diagnostic

The match rate for a conversion action lives inside Google Ads under Goals, then Conversions, then click the conversion action, then the Diagnostics tab. It is not on the main conversion summary screen. You will see counts for matched conversions and a percentage match rate for the user-provided data you uploaded.

In our experience, most call accounts running below 50% match rate are sitting on unmatched rows, not malformed ones. That is the silent failure mode. A malformed payload throws a partial failure error you can see in the API response. An unmatched one does not, because Google has no way to know whether the user simply did not click an ad or whether your hash format is wrong.

“Received” in your call platform is not “matched” in Google’s endpoint

The call platform’s webhook log shows HTTP response codes. A 200 from Google’s ConversionUploadService confirms the API accepted the request at the transport level. It does not by itself confirm there were no partial_failure errors inside the response body, and it does not confirm the hashes matched a click. Matching happens asynchronously, downstream of the API response. Google’s own guidance is to check the partial_failure_error block and the offline data diagnostics, not just the HTTP status, before assuming an upload was accepted as intended.

This is the single most common misread when auditing a call account. Operators see green checkmarks in Ringba or Invoca and assume the integration is working. The integration is transmitting. It is not necessarily matching. Two separate questions. Only the diagnostic inside Google Ads, plus the partial_failure block in the API response, answer the second one.

Portrait process-flow infographic in teal and green outlining Google Ads enhanced conversions setup for call tracking.
The google ads enhanced conversions setup for call tracking platforms process, step by step.

The Schema Fields Google’s Match Endpoint Compares, and the Normalization It Applies

Google’s user-provided data spec for Enhanced Conversions defines hashable identifiers the matcher uses: email, phone, and the address tuple (first name, last name, postal code, country). Each one has a normalization step Google applies before hashing on its end. If your call platform hashed a different string shape, the outputs will not align and the row drops.

Email: lowercase, trim, and the Gmail dot rule

Per Google’s user-provided data formatting guidelines, email addresses should be lowercased and trimmed of whitespace before hashing. For Gmail addresses, Google treats dots in the local part as ignored characters for delivery, so John.Smith@Gmail.com and johnsmith@gmail.com route to the same inbox. Stripping dots from the local part of Gmail addresses before hashing is a common normalization step operators use to align with how Gmail handles those addresses.

Most call platforms lowercase and trim. Few handle the Gmail dot rule. For pure pay-per-call traffic this is moot because email is rarely collected on the call. For hybrid form-then-call flows, it is a quiet source of dropped matches.

Phone format: E.164 or nothing

For Google’s Enhanced Conversions upload, phone numbers should be in E.164 format before SHA-256 hashing: a plus sign, the country code, then the national number with no spaces, dashes, or parentheses. A US number looks like +15551234567. Google’s Enhanced Conversions for Leads documentation is explicit on this. Google applies E.164 normalization to the click-side phone before hashing, so your hash must come from the same string shape or the match fails.

This is where most of the match-rate damage in call accounts originates, in our experience. The publisher landing page captures the phone in whatever format the user typed. The call platform passes that string into its hasher untouched. The webhook fires successfully. Google’s matcher hashes +15551234567 from the click side, gets a different output, and drops the row. The webhook log still says “delivered.”

Operator Note: If the inbound caller ID is the only phone you have (the caller never submitted a form), use the caller ID as your phone field, force it to E.164 with the country code prepended, and hash that. This is the standard flow in pay-per-call and it works, as long as the E.164 conversion runs before the hash.

The address tuple: all four fields, or none

Google’s matcher reads the address tuple as a group: first name, last name, postal code, and country code. The fields are designed to work together. A payload that includes only postal code, with no name fields, gives the matcher far less to work with than a full tuple and offers little upside over sending phone alone.

This happens constantly. A call platform captures ZIP from the IVR, the integration drops it into the address block, and the field adds noise instead of signal. The cleaner pattern: either capture and forward all four address fields, or omit the address block entirely. Half-populated address blocks tend to add payload weight without adding match signal.

GCLID is not hashed, and integrations keep hashing it anyway

The Google Click ID (gclid) is the click identifier Google appends to the landing page URL when someone clicks an ad. It is passed through to the conversion upload as a plain string. It is never hashed. Some call platform integrations hash everything that looks like an identifier by default, which destroys the gclid.

If the gclid arrives at Google’s endpoint hashed, it cannot be matched to a click. The row drops. Check your call platform’s hashing rules and confirm gclid is on the bypass list.

Where Ringba, Invoca, and CallRail Each Break the Schema

Each call tracking platform has a specific point in its configuration where the schema typically breaks. Knowing your platform’s failure mode is faster than auditing every field.

Ringba: the publisher landing page injects whatever it captured

Ringba captures the inbound phone from the call itself and from any URL parameters or tags the publisher passes. The phone Ringba forwards to Google is whatever string was passed in. If the publisher’s landing page form captured (555) 123-4567 and passed it as a URL parameter into the Ringba target, that is what gets hashed.

Ringba’s UI shows the webhook delivered successfully because the payload was well-formed. The format mismatch is invisible at the platform level. The fix is a transformation in the webhook payload, before it reaches Google, that forces every phone string to E.164. For deeper context on Ringba’s routing logic, see our Ringba call routing rules walkthrough.

Invoca: check the integration payload, not the source field

Invoca uses Signals to fire conversions. The hashed user data attached to the signal is pulled from the call record’s contact fields. Invoca formats E.164 internally for most flows, but the integration to Google Ads can be configured to send the raw caller ID format, which on some carriers arrives with country code missing or with formatting characters intact.

Check the signal’s outbound payload configuration and confirm the phone field is being forced to E.164 in the integration, not in the source field. Source fields vary by inbound carrier. The integration is where you get a consistent format.

CallRail: native integration versus custom webhook

CallRail offers a native Google Ads integration and a generic webhook. The native integration handles E.164 normalization on most US numbers. The webhook does not.

If you are running the native CallRail-to-Google-Ads integration on US traffic, your phone normalization is probably fine. If you are running a custom webhook (for international traffic, custom routing, or to add fields the native integration does not support), you own the normalization. The webhook hashes what you tell it to hash. For a side-by-side look at how these platforms differ on the routing side, see our Ringba vs Retreaver vs Invoca operator guide.

Build a Pre-Hash Normalization Layer Between Your Dialer and Google Ads

The fix is middleware that sits between the call platform’s webhook and Google’s ConversionUploadService. Its job is to normalize every field to Google’s spec before the hash runs. Host it on a serverless function: a Google Cloud Function, AWS Lambda, or similar.

The middleware performs four transformations in order:

  1. Phone to E.164. Strip every non-digit character. If the result is 10 digits, prepend +1. If 11 digits starting with 1, prepend +. For non-US traffic, use the country code captured in the call record. Reject anything that does not parse to a valid E.164 string.
  2. Email lowercase, trim, Gmail dot-strip. Lowercase the entire string. Trim whitespace. If the domain is gmail.com or googlemail.com, strip dots from the local part.
  3. Address tuple validation. If all four fields (first name, last name, postal code, country) are present, include the address block. If any one is missing, omit the entire address block. Never send a partial.
  4. GCLID passthrough. Pass the gclid as a plain string. Do not hash it. Do not URL-encode it. Do not strip it.

Then hash each user-data field with SHA-256, lowercase the hex output, and post to Google’s API. Check the response body for partial_failure_error on every call, not just the HTTP status.

Why this lives outside the call platform

The call platform’s hashing logic is shared across every buyer and every integration. You cannot rewrite it. A serverless function gives you a place to enforce Google’s exact spec without asking your call tracking vendor to ship a feature. It also gives you a single audit point when match rate drops. One file. One log. One place to check.

The normalization layer is also the right place to enforce consent flags. Before forwarding any record, check whether the consent flag from the call platform indicates TCPA-compliant consent was captured. If not, skip the upload. This keeps consent enforcement out of your campaign config and inside the data layer where it belongs. For the broader compliance picture, see our 2026 TCPA lead buyer checklist.

When to Test Offline Conversion Imports Against Enhanced Conversions for Leads

Offline Conversion Imports (OCI) matches conversions to clicks using the gclid. Enhanced Conversions for Leads matches using hashed user data. When gclid is clean and persistent, OCI can match deterministically and, in some operator tests, has outperformed EC for Leads on match rate. Other operators see EC for Leads recover conversions OCI misses, especially across cross-device journeys. The honest answer: A/B test both on your own traffic before committing.

The decision starts with three questions:

  1. Does your landing page capture the gclid from the URL on every visit?
  2. Does the gclid persist through to the call event (in a hidden form field, URL parameter passed to the dialer, or session cookie)?
  3. Does your call platform forward the gclid to Google’s upload?

Three yeses, OCI is worth testing. Any no, lean EC for Leads.

Why publisher pay-per-call traffic structurally favors EC for Leads

Publisher traffic in pay-per-call flows rarely carries a clean gclid through to the call. The user clicks a publisher’s ad, lands on the publisher’s page, and the publisher’s tracking strips or rewrites URL parameters before the call fires. Gclid does not survive the hop.

For this inventory, EC for Leads with hashed phone is the practical path. Match rates will be lower than form-lead accounts because email is not collected. That is a feature of the data, not a misconfiguration.

Match rate, Smart Bidding stability, and the feedback loop

Across call-driven accounts, Smart Bidding tCPA stability tends to degrade as match rate drops. The bidding model loses signal volume, learning windows stretch, and day-over-day CPA variance widens. There is no Google-published threshold here. But if your match rate is sitting in the 40s and your tCPA is swinging 30%+ week-over-week, the two are related. Fix the match rate first, then evaluate the bid strategy. For the broader troubleshooting framework, see our six-layer diagnostic for Enhanced Conversions for Leads.

A 20-Minute Diagnostic to Audit Your Own Setup

Run this sequence before changing anything. Each step maps to one of the schema fields.

  1. Pull the match rate. Google Ads, Goals, Conversions, click the conversion action, Diagnostics tab. Note the matched conversion count and the percentage for the last 30 days.
  2. Pull the last 100 webhook payloads from your call platform’s webhook log. You need the raw outbound payload, before hashing if your platform exposes it.
  3. Spot-check phone format. Is every phone in E.164 (+1 followed by 10 digits, no formatting)? If half are formatted with parentheses or dashes, you found the leak.
  4. Spot-check email normalization. Lowercase? Trimmed? Any Gmail addresses with dots in the local part still hashed as-is?
  5. Verify the address tuple. Either all four fields present or no address block at all. Reject any payload with postal-code-only.
  6. Confirm gclid is present and unhashed. It should appear as a plain alphanumeric string in the payload, not a 64-character hex hash.
  7. Check API responses for partial_failure. Not just 200. The partial_failure_error block tells you which rows Google rejected before matching even ran.

Whichever check fails first is where to start. If multiple fail, fix phone formatting before anything else. Phone carries the most weight in call-driven EC matches.

Frequently Asked Questions

Why does Ringba show a successful webhook while Google Ads shows a low match rate?

Ringba’s webhook log shows HTTP delivery status. Google’s match rate shows hash alignment, which is a separate event downstream of the API response. A 200 OK from Google’s endpoint means the request was accepted at the transport level. It does not mean the hashed user data matched a click, and it does not by itself rule out partial_failure errors in the response body. A common cause of low match rate is a phone number hashed in a pretty format (with parentheses or dashes) instead of E.164.

What is the correct phone number format for Google Ads Enhanced Conversions?

For the Google Ads Enhanced Conversions upload, phone numbers should be in E.164 format before SHA-256 hashing: a plus sign, the country code, then the number with no spaces, dashes, or parentheses, per Google’s formatting guidelines. A US number looks like +15551234567. Google applies E.164 normalization on its side before hashing the click-side phone, so your hash must come from the same string shape.

What is the difference between Enhanced Conversions for Leads and Offline Conversion Imports for call campaigns?

Enhanced Conversions for Leads matches conversions to clicks using hashed user data (phone, email, address). Offline Conversion Imports matches using the gclid click identifier. OCI is deterministic and can produce higher match rates when gclid passthrough is reliable. EC for Leads is the better path when gclid is unreliable, which is most pay-per-call publisher traffic. Test both on your own traffic before committing.

Where do I find the real match rate in Google Ads?

In Google Ads, go to Goals, then Conversions, click the conversion action, and open the Diagnostics tab. The match rate for user-provided data appears there. It is not on the main conversion summary screen.

Does forwarding a partial address lower match rate?

Google’s matcher reads the address tuple (first name, last name, postal code, country) as a group. A postal-code-only payload offers the matcher far less than a full tuple and adds little over sending phone alone. Either include all four address fields or omit the address block entirely.

Can phone number alone carry the match for pay-per-call traffic?

Yes, but typically at a lower rate than phone plus email combined. Pay-per-call accounts that only have caller ID generally see lower match rates than form-lead accounts that capture both phone and email. That is a feature of the data available on the call, not a misconfiguration. The fix is making sure phone is normalized to E.164 before the hash, not adding email that was never collected.

We’re media buyers and lead-gen operators sharing what we see in the field. This isn’t legal advice. TCPA consent rules vary by state and vertical, so talk to an actual attorney before changing your consent flows or vendor contracts.

If you are spending $25k to $500k a month on call-driven acquisition and your match rate is sitting well below 70%, your Smart Bidding model is making decisions on a fraction of your actual conversion volume. Our pay-per-call team runs this exact audit across insurance, home services, financial services, and mortgage accounts. We can spec the normalization layer, choose between EC for Leads and OCI for your traffic mix, and route exclusive call inventory if you are scaling past what your current setup can absorb. Book a free strategy call and let’s talk about your vertical and your volume.

For related reading, see our six-layer diagnostic for Enhanced Conversions for Leads, the TCPA lead buyer checklist, and the simplified Consent Mode update that is costing US lead-gen advertisers matched conversions right now.



Ready to put this into action?

Picture of SHANE MCINTYRE

SHANE MCINTYRE

Founder & Executive with a Background in Marketing and Technology | Director of Growth Marketing.