Ad spend to revenue, in one event stream
Meta, TikTok, Google Analytics and Search Console — read on a schedule, normalised to one envelope, delivered next to your leads and payments. Cost per lead and ROAS stop being an export-and-spreadsheet project.
In short
- Four pull sources: meta-ads, tiktok-ads, google-analytics, google-search-console.
- One event per settled day per source:
ad.spend_reported,web.traffic_reported,seo.performance_reported— money always in cents. - Joined with lead events and payment events, the funnel ratios are divisions between metrics that already sit side by side.
- Connections are one credential each: an access token for the ad networks, a service-account key for Google — pasted once, stored encrypted, returned by no route.
- Days are read once, after they settle. Restatements are not chased, and that policy is written on every source page.
What each source contributes
| Source | Event | The numbers | Read |
|---|---|---|---|
| Meta Ads | ad.spend_reported | spend_cents, impressions, clicks, reach | daily, 1-day settle |
| TikTok Ads | ad.spend_reported | spend_cents, impressions, clicks, reach | daily, 1-day settle |
| Google Analytics 4 | web.traffic_reported | active_users, sessions, page views — or your metric list | daily, 2-day settle |
| Search Console | seo.performance_reported | clicks, impressions, ctr_permille, avg_position | daily, 3-day settle |
| GoHighLevel | lead.created, deal.won | amount_cents, pipeline stage | push, instant |
| Stripe | payment.succeeded | amount_cents, currency | push, instant |
Where teams land it
| Goal | How |
|---|---|
| Spend and revenue in the warehouse | Route both event types to an S3-compatible bucket or a queue destination — one object per event, signed |
| A daily budget alert | Filter ad.spend_reported on {"metrics.spend_cents": {"gt": 50000}} to a Slack-bound endpoint |
| Networks compared on one axis | Both networks emit the same event type — group by the provider attribute on your side |
| SEO regression watch | Filter seo.performance_reported on falling clicks; the events carry position, so a rank slide is visible in the payload |
Questions
Is this a marketing dashboard?
No. It is the layer under one: verified, normalised events — spend, traffic, search, leads, revenue — delivered wherever you already work. Point them at a warehouse and chart there; point them at a webhook and alert; point them at a bucket and keep them forever.
How do the ratios work if providers report money differently?
That is the point of the normalisation: Meta reports whole units as strings, TikTok
reports strings, Stripe reports cents, GoHighLevel reports whole units — and every connector
converts at its own boundary, so spend_cents and amount_cents are
the same kind of number. Cost per lead is a division, not a data-cleaning project.
How fresh are the numbers?
Each source reads a day once, after the provider stops revising it — one day for the ad networks, two for GA4, three for Search Console. This is the durable daily record; for minute-by-minute in-flight numbers, the providers’ own consoles remain the right tool, and this page does not pretend otherwise.
What about attribution?
Each network reports its own attributed numbers and each arrives labelled by provider. HookGet does not re-attribute — dedupe across networks is a modelling decision that belongs in your analysis, made honest by having every network’s claim in one place, in one unit.