How to Automate Offline Conversion Uploads with Make
Make handles the messy parts Zapier charges you for. Here is a working scenario for offline conversions, including the hashing.

This post walks through a Make scenario that sends offline conversions to Google Ads and Meta, including the hashing and deduplication that Zapier makes awkward.
Make is the better tool for this job at almost any real volume, and it is the one I reach for on client builds.
When this fits
You have more than a trickle of conversions and per task pricing matters.
You need real data shaping: hashing, conditional routing, batching.
You are comfortable with a slightly steeper interface than Zapier.
Why Make suits this better
Operations are cheaper than tasks at volume, and this is a high volume, low complexity job.
Routers let one scenario send to several platforms with different rules, instead of one Zap per destination.
Iterators and aggregators let you batch conversions into a single API call rather than one call each.
Built in crypto functions handle SHA256 without a separate step.
Let’s implement it
Step 1: trigger
Either a CRM watch module on deal stage change, or a scheduled search for deals updated since the last run. The scheduled search is more robust because it survives a missed webhook.
Step 2: filter
Only continue when the stage matches and the click ID is present. Filtering early keeps your operation count down.
Step 3: shape the data
Use a Set Variable module to build the fields you need:
Conversion time formatted with timezone for Google Ads.
Value as a plain number.
Hashed email: lower, trim, then sha256.
Hashed phone in E.164, then sha256.
Do the normalising inside the same expression as the hashing so the two can never drift apart.
Step 4: route to each platform
Add a router. One branch writes a row to a Google Sheets tab for the scheduled Google Ads import. Another posts to the Conversions API for Meta. A third can handle Microsoft Ads if you run it.
Each branch gets its own filter, so a deal with no fbclid does not waste an operation on Meta.
Step 5: write back
Update the CRM record with an uploaded flag and a timestamp. This is what prevents duplicates, and it is the step people skip.
Step 6: handle errors
Add an error handler to each branch that logs failures somewhere you will see them, a sheet or a Slack message. Silent failures are the default otherwise, and you will find out months later.
Batching, if you have volume
If you send hundreds a day, use an aggregator to collect rows and send them in batches rather than one call each. It cuts operations dramatically and both APIs prefer it.
Before you finish
Run it once on a single test deal and inspect every module’s output bundle.
Confirm the hash matches one generated independently.
Confirm the uploaded flag was written back.
Re run on the same deal and confirm the filter blocks it.
Check the error handler actually fires by feeding it a deliberately bad row.
FAQ
Make or Zapier?
Make for anything ongoing at volume. Zapier if you already live there and volume is low: the Zapier version.
Can Make call the Google Ads API directly?
Yes, with an HTTP module and OAuth set up. The sheet route avoids that entirely and is usually enough.
How do I avoid double sending?
The write back flag in step five, plus a filter that excludes flagged records. Belt and braces, because both will eventually be needed.
Simplest possible alternative?
No CRM at all, and you want the simplest possible version? I wrote a full walkthrough of that for Stape using nothing but a spreadsheet: Google Ads offline conversion tracking without a CRM. Click to read it here.
Need this built properly?
Make is the tool I use for this on real client builds. I set up and repair tracking for ecommerce stores and lead generation businesses, so the numbers in your ad accounts match the money in your bank account.
Have a look at what I do, or book a call and we can go through your setup together.



















