Most service businesses running ads never send custom conversion events back to Meta or Google. They run the campaign, generate leads, close some, lose some, and that's where the loop ends. The platforms never find out what actually happened.
That's the gap I've been building against. Sending real outcomes back to the ad platforms is, in my opinion, the most efficient path to lower ad costs and better lead quality. It's also the part almost nobody does, because doing it manually is tedious enough that it just doesn't happen.
So I automated about 95% of it. The remaining 5% is a single button click from the business owner — close, no show, no fit — and the rest moves on its own.
Think of the ad platform as a matchmaker. It takes users on one side, businesses on the other, and tries to make the right connection. Every time someone clicks your ad, the algorithm is running a test: is this the right kind of user for this business?
Without custom conversion events, you're letting it run the test forever without ever grading it. You took the test, you never got the score back, so you never know if you passed or failed. The algorithm keeps guessing.
When you send the outcome back — especially a closed deal with the actual revenue attached — the loop closes. The algorithm learns which users converted into real money, not just which users filled out a form. More of those users start showing up. The match gets tighter. Costs drop because the randomness drops.
There are three players in every ad transaction: the user, the business, and the platform. Each one has a dream outcome.
The user wants their problem solved. The business wants a paying customer. The platform wants both of those things to happen, because if the user has a bad experience or the business loses money, both stop using the platform.
Google and Meta have more incentive than people realize to make this work. But they can only optimize toward signals they actually receive. If the only signal you give them is "form filled," they'll keep sending form-fillers. If you give them "$4,200 in revenue closed," they'll start hunting for people who look like the ones who paid you $4,200.
Here's the part most ad runners miss. A form fill is not a conversion. A booked call is not a conversion. A closed deal with a real dollar value attached — that's the conversion the algorithm should be optimizing toward.
When FormLock fires a custom conversion event with the actual revenue value, you're not just telling Meta "this worked." You're telling it how much it worked. The algorithm starts weighting users by predicted lifetime value, not by predicted form-fill likelihood. That's a completely different optimization target.
This is why some businesses say "ads don't work for us." They do work. The platforms just don't know what working looks like for that specific business, because nobody ever told them.
Every payload that gets sent to Meta and Google also gets stored internally, scored, and used to build a learning system that's unique to each FormLock account. No industry averages. No outside data. Just your leads, your outcomes, your patterns.
The engine looks at five dimensions: attribution (UTMs, click IDs, source), behavioral (time on page, scroll depth, time spent in each form field), device, contact, and platform signals. Each lead gets a priority score — high intent, medium, low — based on how their data compares to past leads who closed, no-showed, or weren't a fit.
A deterministic agent runs on a cron schedule, emails the account holder with any leads that haven't been logged with an outcome, and waits for the click. Close, no show, no fit — one button. If it's a close, a small popup captures the revenue value. That value goes back to Meta, back to Google, and back into the learning system.
So on a Monday morning when you're staring at 25 weekend leads and don't know who to call first, the system already ranked them. And every outcome you log makes the next ranking sharper.
That's the loop. The algorithm sends users. The business closes some. The outcomes go back. The algorithm sends better users. Run that long enough and the test stops being a test — it just becomes routine.