All posts
Performance Ads

Google Ads Agent That Catches Broken Tracking

An agent that watches your Google Ads conversion feed and tells you the day it breaks, instead of the month you notice the revenue gap.

August 10, 2026·10 min read·by Olexander Cheberko
Table of contentstap to expand

An AI agent is only as good as the data underneath it. The highest-value agent for a paid account is not the one that writes headlines. It is the one that watches your conversion tracking and tells you the moment it breaks, because a broken conversion feed wastes budget silently for days before anyone opens a report and notices. Here is how to build that agent, and the traps that make a naive version cry wolf until you mute it.

Quick answer

A monitoring agent for Google Ads is a scheduled workflow that reads your account and your outcome data, checks a handful of failure signals, and pings you on Telegram when one fires. The build is mostly deterministic. The one place a model earns its keep is the judgment call: is this a real drop, or just the attribution window being quiet? Get that judgment right and the agent is trustworthy. Get it wrong and you will turn the alerts off within a week.

What a monitoring agent actually watches

A campaign-writing agent is a demo. A watchdog is a system. The signals worth watching are the ones that fail quietly:

  • Conversions dropping to zero. A tag breaks, a form endpoint changes, a consent banner update blocks the pixel, and conversions stop landing while spend keeps running.
  • Offline uploads silently failing. The click-to-outcome loop breaks at the upload step, so Google stops learning which clicks became customers.
  • A conversion action slipping into observational. It still shows in reports but no longer feeds bidding, so the account quietly optimizes on nothing.
  • Call imports double-counting. A built-in call import and your own upload both fire, and the account inflates.
  • Cost per conversion outside its normal band for that day of week, which usually means one of the above already happened.

The build

The shape is a scheduled workflow, not a chat bot. On self-hosted n8n:

Schedule trigger
every hour
Read sources
Ads API + CRM / EHR / upload log
Compute signals
vs day-of-week baseline
Anomaly?
no
Log and sleep
maybe
Model judgment: real drop or quiet window?
quiet window
Log and sleep
real drop
Alert on Telegram
what broke + since when
The whole thing is one scheduled workflow. The single judgment call, real drop or quiet window, is the one place the model earns its keep.

The deterministic part reads the numbers and compares them to a baseline. The model call is small and specific: given the metric, the attribution window, and the day of week, decide whether this reading is a genuine failure or an expected lull. That single judgment step is the difference between an agent you trust and one you silence.

Here is the core of the check as a Code node, before the model ever sees it:

// n8n Code node: flag only readings that clear the noise floor
const nowConv = $json.conversions_last_24h;
const baseline = $json.dow_baseline;          // same weekday, trailing 8 weeks
const spend = $json.spend_last_24h;
 
const drop = baseline > 0 ? 1 - nowConv / baseline : 0;
 
// Spend still running but conversions collapsed is the loud signal.
const suspicious = spend > 0 && drop >= 0.7;
 
return [{
  json: {
    suspicious,
    drop: Math.round(drop * 100),
    spend,
    note: suspicious ? "conversions collapsed while spend continues" : "within range",
  },
}];

Only the suspicious readings go to the model for the real-or-window judgment. Everything else is logged and ignored, which keeps both the token cost and the false alarms down.

The traps that make naive monitoring useless

This is where the real expertise lives, and it is why most homegrown alerts get muted:

  • The attribution window. Web conversions are credited back to the click time, so the last few hours always look empty even when nothing is wrong. An agent that does not model the window will alert every single evening. Baseline by day of week and hour, not against a flat number.
  • Observational actions do not show in the main column. If you only read the primary conversions column, a healthy account can look broken. Read the action status too.
  • Double counting hides a break. A call-import and a manual upload both firing can mask a real drop in web conversions, because the total still looks fine. Watch the channels separately, not just the sum.
  • Reporting lag in the API. The API itself finalizes recent numbers over time, so the freshest hour is always provisional. Treat the last few hours as soft, not hard.

Miss these and the agent is worse than nothing, because a muted alert is an alert you trusted once and stopped reading.

The failure the agent cannot see: its own

There is one failure a monitoring agent is uniquely bad at catching, and it is its own. If the agent runs on a cloud scheduler, do not assume the schedule is honest. On one build set to run dozens of times a day, a full day of logs showed only about a third of the runs actually firing, with a gap of more than five hours overnight. Every run that did fire succeeded, so nothing looked broken, and the whole time the dashboard and every answer it produced claimed it refreshed twice an hour.

That is the worst kind of failure: not a crash, but a gap between what the system promises and what it does, that nobody was checking. The fix is to move the clock to somewhere cron is honest and keep a single daily run in the original scheduler as a floor. Then a dead external trigger costs you a day of freshness, not silent, indefinite staleness. And the agent should report its own last-run time in every alert and export, so a stalled watchdog is visible instead of assumed alive.

Configured runsActually ran
011220510152023
Schematic on synthetic data. The scheduler was set to run twice an hour, the flat line. What actually fired is the lower curve, roughly a third of it, with a dead patch overnight, while the panel still claimed it refreshed twice an hour.

Giving it access without giving it your data

A watchdog needs numbers from wherever your outcomes live, and for a healthcare account that is a server holding patient records. Do not hand the scheduler a key to that server. If the job were ever hijacked, that key is a shell on the machine with the patient data. Reverse the direction instead: the server pushes aggregates out to a tiny receiver, and the agent reads from the receiver. Two tokens, and the one that lives in the agent is read-only and touches no patient data. Even a full compromise of the agent's secrets cannot put a false number into a report or reach a single record.

Patient server
pushes aggregates out
Tiny receiver
holds the write token
Agent
read-only, no PHI
Reverse the flow: the server pushes aggregates out, the agent only ever reads.

Make the read-only property structural, not a line in the prompt. The agent's set of tools should contain nothing that can write: no bid change, no budget edit, no delete. A prompt can be talked around with enough persistence, a function that does not exist cannot. And if your organization forbids downloading service-account keys, treat that as a hint, not an obstacle: identity federation hands the job a short-lived token and leaves no key file anywhere. One trap on the way in, federation issues a broad token by default that the analytics APIs reject for insufficient scope, so ask for exactly the read scopes you use and no more.

Making it reliable, and honest

Two things separate an agent you can leave running from one you babysit.

First, it must refuse to make things worse. A dropped connection returns a short answer that looks like a quiet, successful day, and if the agent overwrites its history with that, it silently erases what it knew. Guard against it: refuse to replace stored data when the new response is materially shorter than the last, unless a human forces it.

// refuse a suspiciously short refresh; a dropped connection looks like "quiet"
if (previous && newRows < previousRows - TOLERANCE && !forced) {
  refuse(`had ${previousRows} rows, got ${newRows}, keeping the old copy`);
}

Three rules keep network errors from turning into false calm. Put a deadline on every request, or a half-open socket will hang a run until it burns the whole job budget, and a hang you have turned into an error is one the pipeline already knows how to survive. Retry only transport failures, never response codes, because retrying a permission error just turns an access problem into a quiet zero. And an optional source that fails must not sink the run: keep the last copy and mark it stale, never zero it, because a zero reads as "collapsed" when the truth is "unknown".

Total revenueAd-attributed revenue
01.2k2.4k3.6k4.9kd1d5d9d13d17d21tracking on
Schematic on synthetic data. Before tracking went live the ad-attributed line does not exist. It is unknown, not zero, so the line begins rather than dropping to the floor, the difference between an honest dashboard and a pretty one.

Second, the agent must not mislead in the act of reporting. Freshness is per source, not one averaged date that lies about the laggiest feed, so ship each source's own timestamp and lag with a short reason (the ad platform being "one day behind" is an unclosed day, not a collection delay). And the rules for reading a number travel with the number: a machine-readable note on every alert and export saying which comparisons are invalid, which figure has its own window, and where a zero means "not measured", attached to the data, not buried in documentation nobody opens. A number that gets misread does not get better by arriving sooner, it just gets misread faster.

Why an agent instead of a static alert

A static threshold cannot tell a real drop from a quiet window, so it either fires constantly or is set so loose it misses the actual break. The judgment in the middle, weighing the window, the day, and the spend together, is a genuinely ambiguous call, and that is precisely the kind of decision a language model handles well when you wrap it in a deterministic workflow that fetches the data and delivers the alert. The model decides one thing. The workflow does everything else. That split is what makes it reliable enough to leave running.

The honest limit

A watchdog tells you the tracking broke. It does not fix the pipeline underneath, and it is only as trustworthy as the data it reads. If your conversions were never tied to real outcomes in the first place, a monitoring agent will faithfully report that a number you should not trust has not changed. The agent sits on top of solid measurement. It does not replace it.

That measurement layer, tying every ad click to the outcome it actually produced, is the conversion tracking I build for practices running paid search. The monitoring agent is the natural thing to put on top once the data underneath is real.

Tags

AI agentsGoogle Adsconversion trackingmonitoringn8n

Frequently asked questions

What is the most useful AI agent for a Google Ads account?

Not one that writes ads. One that watches your conversion tracking and tells you the moment it breaks. A broken conversion feed wastes budget silently for days, so an agent that catches it early pays for itself faster than any creative tool.

Why not just use a rules-based alert instead of an agent?

Because the hard part is judgment, not thresholds. A naive rule like 'no conversions in 24 hours, alert' fires constantly, since web conversions lag behind clicks by the attribution window. The value is a step that can tell a real drop from a normal quiet window, which is exactly where a model earns its place inside an otherwise deterministic workflow.

Does the monitoring agent need access to my ad account?

It needs read access to the Google Ads API and to whatever holds your outcomes (your CRM, EHR, or the offline-conversion upload log). It never needs to change bids or budgets. A watchdog reads and reports, it does not touch the account.

Can this run self-hosted?

Yes, and for a healthcare or privacy-sensitive account that matters. The whole thing runs on self-hosted n8n plus one model call for the judgment step, so no third party sits between your account data and the alert.

What does it alert on that a person would miss?

Conversions dropping to zero, offline uploads silently failing, a conversion action slipping into observational, a call-import double-count, and cost per conversion moving outside its normal band for the day of week. These are the quiet failures nobody notices until a monthly report looks wrong.

How do you know the monitoring agent itself is still running?

You make it report its own last-run time in every alert and export, and you do not trust a cloud scheduler to fire on time. Cloud cron often runs best-effort, so a job set to run many times a day can quietly fire far less, while every run that does happen succeeds and nothing looks wrong. Move the clock to somewhere cron is honest, keep one daily run as a floor, and surface the last-run time so a stalled watchdog is visible instead of assumed alive.

Need something like this built?

Free 15-min discovery call. I'll listen, ask honest questions, and tell you if I can help.

More in Performance Ads