Most contractors can tell you what they spent last month and what they closed last month. Almost none can draw a line between the two. We built our own tracking so that line is never a guess.
In outdoor living, months can pass between the tap and the signature. Most tracking gives up somewhere in the middle.
A homeowner taps your ad in April. He gets an estimate in May. He signs in June, after two design revisions and a financing conversation. By then nobody remembers which ad started it, and the ad account has long since stopped counting.
So the month-end review turns into an argument. The ad account reports 62 form fills. The CRM reports four signed jobs. Nobody can say whether those four came from the ads, from a referral, or from the truck sitting in a driveway on a busy street. And next month's budget gets set on a feeling.
Meanwhile the ad platform is learning from whatever you send back to it. If the only thing it ever hears is somebody filled out a form, it goes and finds more people who fill out forms. It is extremely good at that. It has no idea which of them wrote a check.
Four habits that look like measurement and are not.
Impressions, clicks, cost per lead, a screenshot of the ads manager. Every one of those describes the ad. None of them describe your business.
The platform is told a lead happened and nothing else, so it chases the cheapest form fill in your zip code. That is exactly the homeowner you do not want on your calendar.
What happened after the estimate, quoted, sold, walked away, never travels back to the ad platform. The algorithm gets no signal about who actually buys, so it never learns.
Somebody types job sources in by hand, when they remember, from what the homeowner said on the phone. That is not tracking. That is a memory test.
This is the part no other agency in this trade wants to build, because it is engineering work rather than reporting work.
When a homeowner submits on your funnel, the browser pixel fires and a second copy of the same event goes server to server, from our own tracking worker straight to Meta. Both carry the same event ID, so Meta counts one lead and not two.
Ad blockers, iOS privacy settings, and browser scripts that fail to load stop being holes in your data. This runs on the Meta Conversions API, it is live on six client ad accounts today, and every new client now launches with it rather than getting it retrofitted later.
Live on six client accountsA form fill and a booked estimate are different things, so we count them as different things. When the homeowner picks a time, a separate booking event fires with the same identity attached.
That one change lets the ad platform be pointed at booked estimates instead of form fills. It is the difference between a busy inbox and a full calendar.
Every opportunity carries what happened to it: quoted, quote value, sold, contract value. Our attribution engine reads that record on a daily sync and matches each closed job back to the lead record, the funnel, and the campaign that created it.
That match is what makes cost per booked job a real number instead of a rounded guess.
When a project closes, the result goes back to Meta as a conversion event carrying the real dollar value of the job. The algorithm stops guessing what a good lead looks like and starts learning from the ones that turned into signed contracts.
This is the newest piece of the system. It is live on the first account and rolling out across the rest.
Closing the loopFriday you get cost per booked estimate, cost per booked job, and what we are moving budget toward next week. The pipeline sits in your portal if you want to look at it yourself. There is no 40 page dashboard, because nobody opens those twice.
Closed-loop attribution is a data engineering problem, not a marketing one. It needs a server-side event pipeline, an identity chain that survives the weeks between the click and the close, and a CRM that gets read every day. Most agencies in this trade sell media buying and report what the platform hands them. We built the pipeline because cost per booked job was the only number worth being judged on.
We can only publish these because the tracking counts them. Every figure below is a sum out of client records, not a projection.
Those are sums across every client account, pulled on 2026-08-20 from the same client records the tracking reads: ad spend on one side, booked estimates and signed projects on the other. The two averages move month to month. We update them when they move, and we do not round them up.
The number to watch on your own account is the last one. Cost per lead tells you how cheap the ad was. Cost per closed project tells you what the marketing actually cost you per job you built.
Anything that comes through the funnel is tracked end to end. A phone call straight off an ad is harder, and we handle it with a tracked number plus a source question at intake.
We will tell you which part of your pipeline is measured and which part is inferred. We are not going to pretend the whole thing is airtight when part of it runs through your cell phone.
That is most of the reason it exists. The server-side events use Meta's own Conversions API, which is a supported integration, and customer details are hashed before they leave the funnel.
What changes is reliability, not what gets collected. When the browser pixel gets blocked, the server copy still lands, and the shared event ID keeps the two from double counting.
The reporting is useful in week one. The optimization takes longer.
The platform needs a run of booking events before it can learn anything from them, so plan on several weeks of booked estimates accumulating first. Closed-job data arrives later still, because your sales cycle is measured in weeks. That is the honest version, and it is why we ask for 90 days to find the pattern.
Yes. You get a portal with your pipeline in it, and the Friday report on top of it so you know what changed and what we are doing about it. The report exists to interpret the numbers, not to be the only place you can see them.
Then the report says that, in week three rather than month six.
The whole point of measuring to the signed job is that it delivers bad news early enough to act on. We would rather kill a campaign that is producing estimates nobody closes than defend it because the cost per lead looked good.
On the call we will walk through how the tracking gets installed on your account, what it can measure in your setup, and what it cannot. You will see the same report our clients get on Fridays.
Month to month. No annual contracts.