Manuel Porras

All work / PPC monitoring console

Case study · Daily operations

One look every morning instead of a login per ad account

A monitoring console for a US marketing agency for home-service businesses: the whole client portfolio and each client, with trends, traffic lights and alerts. I use it every morning.

In short: Many clients with several ad platforms each meant a separate login, separate numbers and a separate definition of a lead for every platform. I built a read-only collector for Google Ads, Local Services Ads, Microsoft Ads and GA4 and a password-protected console with a portfolio view and a client view, traffic lights, trends and alerts; a PPC controller agent proposes, a person decides. I check it every morning — and in an audit, the real cost per lead was about 60 % above the reported one, roughly $270 instead of $170.

DailyI check it every morning
2 levelsportfolio and single client
0write access to any ad platform
~60 %real cost per lead above the reported one — in an audit

The problem

Many clients, several ad platforms each — Google Ads (Search and Performance Max), Google Local Services Ads and Microsoft Ads. Every platform has its own login, its own numbers and its own idea of what counts as a lead.

Daily values alone are noise. What matters is the direction: is a budget going to overshoot this month? Is the cost per lead drifting up for three weeks? Is a credit card about to expire and stop the ads?

What it shows

  • Portfolio level: spend this month, blended cost per lead, how many clients are green, yellow or red, real versus junk leads, and how fresh the data is.
  • Client level: budget so far versus plan and forecast with a traffic light, cost per lead versus target, leads by source (verified versus platform conversion), call-tracking health (number insertion, callers from outside the service area), landing-page status, and whether conversion tracking is clean.
  • Trends, not just today: weekly and monthly lines and bars; Google Ads and Local Services Ads shown separately.
  • Alerts: cost per lead too high or suspiciously low, budget pacing, a payment method that needs renewing — among others by e-mail.
ClientBudget MTD vs. planCPL vs. targetCall trackingStatus
Acme HVAC50 %$64 / $80DNI ✓🟢
Beta Plumbing44 %— (LSA new)DNI ✓🟢
Gamma Electric193 % projected$142 / $95DNI missing🔴
Delta Heating72 %$71 / $85DNI ✓🟢
Illustration with invented sample data (fictional clients). The real console shows real clients and is not public.

How it is built

Google Ads LSA Microsoft Ads GA4 · calls read-only APIs Collector on the server daily cron · keys stay here one data file · aggregates only run failed → no deploy Console (password-protected) portfolio level · client level · trends Me, every morning+ alerts by e-mail PPC controller agenttriage → recommendation
Access keys never reach the browser — it only loads the data file. A failed collection run keeps the last good version live.
  1. Collect. A collector on the server reads the platforms once a day — Google Ads, Local Services Ads, Microsoft Ads, GA4 and tracking health.
  2. Build one file. Everything goes into a single data file. Only aggregates, no personal data.
  3. Deploy atomically. The file is published to a password-protected static page. Access keys stay on the server; the browser only ever loads the data file.
  4. Fail safe. If collecting fails, nothing is deployed — the last good version stays live instead of a half-empty dashboard.

A real case: the platform numbers were flattering

In an audit across a portfolio of US home-service clients, a large share of the conversions Google reported turned out to be proxies, duplicates or spam. The real cost per lead was about 60 % higher than the reported one — roughly $270 instead of $170.

That is why the console never shows one lead number. It separates verified leads from platform conversions and flags conversion tracking that counts proxies or junk. A cost per lead you can trust is worth more than a cost per lead that looks good.

Real case, anonymized and rounded. Client names are not shown; names in the examples on this page (such as Acme HVAC) are invented.

Rules it follows

  • Read-only on every ad platform. The console can look, never change.
  • No personal data. Aggregates only.
  • No invented numbers. If a target is missing, it says “no target set” instead of estimating one.
  • A failed run does not deploy. Stale but correct beats fresh but wrong.

A dashboard that guesses is worse than no dashboard. Missing data has to look missing.

The agent behind it

Behind the console sits a PPC controller agent. It works across all clients, reads the client register live, triages pacing and anomalies and writes recommendations. An account manager decides and makes the change — the agent itself has no write access.

It is the same pattern as the rest of the fleet: agents see everything they need, propose, and a person acts where a mistake costs money.

Technology

Node.jsGoogle Ads API (GAQL)Local Services AdsMicrosoft Ads reportsGA4cronstatic site + authClaude Code agent