# How we keep watch over our ad performance

Our ads agent reads Google Ads and Meta Ads each day, spots pacing problems, CPA and ROAS drift and weak ads or keywords, and posts ranked fixes to Slack. It never edits budgets, campaigns or ads.

Canonical page: https://themachine.myapps.ai/use-cases/ad-performance

Ad budgets rarely blow up. They leak. By day three of the month one campaign is
already spending faster than its plan allows. Cost per acquisition edges up a
little each day for a week, and the trend only shows when somebody finally pulls
the chart. An old keyword that stopped converting keeps eating money that could
go to the ones still pulling their weight. There's no single alarm here, just a
slow drip spread over two ad platforms, and nobody has the hours to read every
line of both each morning.

So we gave the job to an agent on Machine. Each day it pulls spend and results
from Google Ads and Meta Ads and posts a ranked list of findings, with suggested
fixes, to Slack. It doesn't change a single budget, campaign or ad. Suggesting is
all it does.

- **Team:** Machine
- **Runs on:** A scheduled run once a day
- **Connected systems:** Google Ads · Meta Ads · Slack
- **Mode:** Reads only · suggests only · a single Slack post each day

## The problem

Any one of these issues is simple to spot when you're actually looking: a
campaign off its budget pace, CPA or ROAS sliding, an ad or keyword that's lost
its touch. The catch is that they're scattered across two platforms with two
different dashboards, and reviewing every live campaign in both, every single
day, falls apart the moment real work shows up. When the weekly review finally
notices a campaign that has burned through its whole month's budget by day ten,
or a keyword now costing twice as much per conversion, that money is gone.

The standard remedies fall short. Each platform's own alerts use their own
thresholds and can only see their own account. A spreadsheet review once a week
is careful, but seven days gives a pacing slip or a CPA jump plenty of room to
grow. And bidding or budget tools that make changes by themselves take away the
very thing a marketing team wants to hold on to: the call.

## What we built

Each day a scheduled trigger on Machine starts a fresh **session**: a new cloud
computer (a sandbox) used only for that run. The agent pulls spend and results
from Google Ads and Meta Ads. It compares each campaign's pace with its monthly
target, measures how far CPA and ROAS have moved from recent performance, and
picks out weak ads and keywords plus any odd jumps in spend or click-through.
Then it writes up suggestions in priority order, such as pausing a particular ad,
moving budget to something that's working, or adding a negative keyword, and
posts that ranked list to Slack. Neither ad platform gets a single write.

## How it works

### Start a fresh run every day

A **cron trigger** (a timer) wakes the agent once a day, and every wake-up
creates a brand-new **session** in its own sandbox. That's one day, one run, one
throwaway computer. Because nothing is kept from the day before, pacing and drift
are always worked out from what both platforms show right now.

### Write down how you judge an ad

The rules sit in a **skill**: the playbook the agent carries with it and that you
keep improving. It defines when a campaign counts as off pace, how big a CPA or
ROAS swing is worth raising, what makes an ad or keyword "underperforming" and
how a good suggestion should read. Want a tighter threshold or a new kind of
anomaly to look for? You edit the skill once, instead of repeating yourself in
chat.

### Give it read-only access to the ad accounts

The agent uses **connectors**: scoped connections to your tools, with keys held
on the server so the model never touches a raw token. Through them it gets:

- **Google Ads numbers**: spend, clicks, conversions and cost per acquisition
for each day, broken down by campaign, ad and keyword.
- **Meta Ads numbers**: the same figures, covering Facebook and Instagram
placements.
- **A Slack post**: one daily message with the ranked findings and suggestions.

It can't write to either ad platform at all. Budgets, campaigns and ads are out
of its reach.

### Keep the agent's hands off the controls

Everything the agent does comes down to reading two ad accounts and posting in
Slack. It may **recommend** pausing an ad, moving money to a stronger campaign or
adding a negative keyword, but it never pauses, edits or shifts spend on its own.
Your marketing team keeps both the decision and the click that carries it out.
Credentials are stored encrypted in the **Secrets Manager** and only handed to
the agents you grant them to.

### Read the ranked list over coffee

The daily post sets out what deserves a look: campaigns running ahead of or
behind budget, ads and keywords whose CPA or ROAS is heading the wrong way, weak
performers that might be worth pausing, and anything that looks strange. Every
item comes with its numbers and one concrete suggested move. Your team reads it
and picks what to change.

> **The pattern**
> A daily **cron** opens a fresh session with read-only **connectors** into
> Google Ads and Meta Ads, and the optimization rules sit in a **skill**. The
> agent studies spend and results on both platforms and its only output is the
> Slack post. Pauses, budget moves and keyword changes are always suggestions,
> never actions.

## Guardrails

Because the agent sees live spend on two ad platforms, its access is narrow and
flows one way:

- **Isolation.** Each run gets its own sandbox. The session can reach only
  Google Ads and Meta Ads, and the Slack post is the one thing that leaves it.
- **Scoped secrets.** The Google Ads and Meta Ads credentials are stored
  encrypted in the Secrets Manager, delivered into the sandbox when the run
  starts, and only handed to the agents you grant them to.
- **Recommend-only.** No write access exists on either ad platform. The agent
  can't touch a budget, pause a campaign or edit an ad. Reporting and
  suggesting are its whole job.
- **Everything is code.** The optimization rules, the thresholds and the
  permissions for each platform are files in your repo. They're versioned, and
  you change them through a reviewed **change request**, not a dashboard toggle.

## The outcome

- **Every day:** Fresh look at spend and results on both platforms
- **Recommend-only:** No automatic pauses or budget moves, ever
- **2 platforms:** Google Ads and Meta Ads covered in a single post

Pacing, the CPA and ROAS trend and the hunt for weak performers used to mean
opening two dashboards. Now they show up as one ranked Slack message each
morning, and every finding brings its figures and a clear suggestion. The agent
reads and advises. Your marketing team still decides what gets paused, moved or
excluded.
