On this page
- What ad operations automation is
- Who it is for, and who it is not for
- What we actually build
- How it works technically
- How much autonomy the system gets
- The build process stage by stage
- What you get at handover
- Where these projects go wrong
- What it costs to run once live
- How to tell whether you need this
- How to start
What ad operations automation is
Ad operations automation is a system that performs the mechanical work of running paid media: building campaigns from a structured brief, checking them before launch, moving budget to hold pacing, pausing what breaches a written rule, and assembling the reporting with the reasoning attached. It is not a bidding algorithm and not a strategist. It is a deterministic rules engine with a language model attached for the parts that need writing, and an approval gate on anything that moves real money.
The distinction that decides whether these builds survive is where the decision lives. A budget correction is arithmetic against a target, and arithmetic belongs in code a person can read. A commentary explaining why spend moved is writing, and writing is what a model is good at. Systems that blur the two produce fluent explanations for decisions nobody can reconstruct.
Every action goes through the platform APIs, never a browser automation pretending to be a person. Each write carries an idempotency key, stores the value it replaced, and lands in a change log that can be filtered and reverted. Our test for a finished build: six months from now, can someone answer why is this ad set paused in under a minute without asking anybody.
- Two enginesA rules engine decides what changes. A model writes the copy and the explanations. Keeping them separate is most of the design.
- Per action classAutonomy is granted by how much spend a wrong decision can move in 24 hours, not by how confident anyone feels.
- Every write loggedThe rule that fired, the values at the time, the previous value and the approver, so a revert is one click.
- Shadow mode firstThe same loop with writes disabled. It proposes while humans decide, and the disagreements are the specification.
Who it is for, and who it is not for
This is for teams where the checking work has quietly become a job, and where the account structure is consistent enough for a rule to bind to. If you run one account with nine campaigns, two good alerts and a Monday habit get you most of the way, and the money is better spent on creative.
| Your situation | Verdict | Why |
|---|---|---|
| Five or more accounts across two or more platforms | Good fit | Engineering cost is per platform, not per account. It amortises across every account you add. |
| Someone spends the first hour of every day checking pacing and pulling numbers | Good fit | That hour becomes a scheduled job with a written policy behind it. |
| Spend small enough that a bad budget move costs less than an hour of engineering | Not a fit | Maintenance will cost more than the errors it prevents. Use platform alerts. |
| Account naming differs everywhere by accident | Fix first | Rules select by pattern and label. There is nothing to select on yet. |
| You want the system to decide positioning | Not a fit | It applies your policy consistently. It has no view on your market and should not pretend to. |
Three conditions that have to be true first
- A naming convention that holds, or the willingness to rename the account first. Rules bind to patterns, and an account named by whoever happened to be in it that week gives a rule nothing to grip.
- One agreed definition of a conversion, owned by a named person. Most arguments that follow an automated pause are older arguments about measurement, surfacing because something acted on the number.
- Somebody who will read the approval queue. A gate nobody opens becomes a backlog, and a backlog becomes a person approving twenty items unread, which is worse than full autonomy because it looks like control.
Who should not buy this
- Accounts under active restructure. Wait until the shape stops moving, then automate the shape you settled on.
- Teams whose real constraint is creative volume rather than operations. That is a content production engine, a different build.
- Organisations where no single person can be named as owner after handover. Decide that before commissioning anything, from us or anyone.
- Anyone who wants the model to have the final say on spend. We will not build it, and the reason is in the failure modes below.
What we actually build
Six components. The model appears in two and neither is a decision maker. Most of the value sits in the parts that look like plumbing, because the errors that cost real money are mechanical rather than strategic.
The campaign builder
It takes a structured brief, a sheet row or a form submission, and produces the whole object tree: campaign, ad group, audience, ads, tracking parameters, negative lists, names following the convention. It validates first and writes second, so a missing conversion action fails in the sheet rather than half way through creating objects in a live account.
The pre-launch assertion suite
Checks that run against built objects before anything is enabled. The landing page returns 200 on the exact URL with parameters attached. The tracking template is well formed. The conversion action is attached and has received data recently. Geo targeting is not on the platform default. The budget is in the account currency. Each check is one line of code and one line in the report, and this suite usually pays for the project first.
The pacing job
Once a day, before anyone logs in, it reads spend to date against the period target, computes the daily rate needed to land on target, and applies or proposes the change. It caps a single step, commonly at twenty percent, because a platform handed a tripled budget spends it fast and then behaves oddly for a day while its own pacing recalibrates.
The rules engine and the anomaly watch
Rules are written policy, versioned in git: an entity type, a metric window, a minimum sample, a threshold, an action, a cooldown, an autonomy class. Rules catch conditions you thought of. The anomaly watch catches the rest: spend at several times the trailing median for that hour of that weekday, tracking gone silent while clicks continue, a step change in CPM, a bulk disapproval. Anomalies page a person rather than acting, because an anomaly is something your policy has no opinion about yet.
Drafting, with an editor still in the loop
The model writes headline and description variants against a brief, a banned-claims list and the platform character limits, then stages them as paused drafts for a human to approve. In regulated categories nothing model-written goes live until a compliance sign-off is recorded against that draft, because the account holder carries the liability for a claim and a model cannot.
The change log and approval queue
One table and one small interface: every proposal, the rule that produced it, the values at the time, the previous value, the approver, and a revert that writes the old value back. Reporting and reconciliation sit beside it, usually sharing a build with reporting automation. Clients ask for this least during scoping and use it most after launch.
If the native rules genuinely express your policy, use them and keep the money. This build earns its cost when your rules need data the platform cannot see, or the same policy has to apply identically across three platforms and nine accounts.
How it works technically
Five layers: ingestion, the metric layer, the state store, the decision loop and the write path. The interesting engineering is in the last two, and so are most of the bugs that reach production.
Ingestion and the metric layer
Reporting APIs are pulled on a schedule into a warehouse, raw first and modelled second, so redefining a metric does not mean refetching two years of history. Your own conversion source lands in the same place. One metric layer then defines cost per qualified lead exactly once, and every rule, alert and report reads that definition. When rules each compute their own version they drift, and the first symptom is two dashboards disagreeing.
State, and why a stale cache hurts
Rules evaluate against the current account tree: what is enabled, what the budget is now, which labels are attached. That state refreshes on a schedule and again immediately after every write. A rule firing against a stale snapshot will set a budget a human corrected twenty minutes ago, the human corrects it back, and the rule fires again tomorrow. Fighting your own operators is the fastest route to being switched off.
The decision loop and the write path
Evaluate, propose, classify, gate, write, verify, log. Every proposal exists as a record before it exists as an action, which makes shadow mode simply this loop with the write step disabled. Writes carry an idempotency key derived from the rule id, the entity id, the date and the target value. Retries use exponential backoff with jitter, three attempts, then the change lands in a dead letter queue a named person reads. A verification read confirms the value landed, because an accepted request and an applied change are different events.
A daily change budget caps the blast radius of a bad deploy: past the cap the system halts and pages rather than being confidently wrong at scale. The two ideas that separate an automation you can leave running from one you have to watch are covered in idempotency in automation and rate limits, retries and backoff.
{
"policy_version": "2026-08-01",
"change_budget": { "max_writes_per_day": 25, "on_exceed": "halt_and_page" },
"metric_source": {
"spend": "platform.cost",
"conversions": "warehouse.crm_qualified_lead",
"reconcile_window_days": 14,
"tolerance_pct": 8
},
"classes": {
"0": { "writes": false, "approval": "none" },
"1": { "writes": true, "approval": "none", "max_spend_moved_per_day": 50 },
"2": { "writes": true, "approval": "notify_only", "max_spend_moved_per_day": 400, "window": "09:00-17:00" },
"3": { "writes": true, "approval": "human_queue" },
"4": { "writes": false, "approval": "forbidden" }
},
"rules": [
{
"id": "pause_spender_with_no_conversions",
"class": 2,
"entity": "ad_group",
"when": { "window_days": 30, "min_clicks": 120, "min_spend": 300, "conversions_lte": 0 },
"action": { "type": "pause", "store_previous_state": true },
"cooldown_days": 30,
"exclude_labels": ["brand", "always-on-test", "new-launch"]
},
{
"id": "period_pacing_correction",
"class": 2,
"entity": "campaign",
"when": { "pace_ratio_outside": [0.9, 1.1], "days_remaining_gte": 5, "min_days_live": 7 },
"action": {
"type": "set_daily_budget",
"formula": "(target_period_spend - spend_to_date) / days_remaining",
"max_step_pct": 20,
"store_previous_state": true
}
},
{
"id": "conversion_tracking_silence",
"class": 0,
"entity": "account",
"when": { "conversions_last_hours": 0, "clicks_last_hours_gte": 100 },
"action": { "type": "page", "channel": "ads-oncall", "severity": "high" }
}
],
"safety": {
"idempotency_key": "sha256(rule_id + entity_id + date + target_value)",
"kill_switch_path": "config/HALT",
"verify_after_write": true,
"retry": { "attempts": 3, "backoff": "exponential", "jitter": true, "on_final_failure": "dead_letter" }
}
}Read that file as a contract rather than a config. Every number in it is an argument somebody should have to win: why 120 clicks and not 40, why a twenty percent step cap, why brand campaigns are excluded from the pause rule. When those arguments live in a file with a commit history, the account survives the person who set it up.
- Pacing ratio
- Spend to date divided by the spend that should have occurred by this point in the period at an even daily rate. 1.0 is on target, 1.2 is overspending.
- Blast radius
- The maximum money a single automated change can move before a human sees it, stated per action class as a currency figure per day and enforced by the policy file rather than by good intentions.
- Idempotency key
- A token derived from the content of a change and attached to the request, so a retried or duplicated call is applied once. Without it, a rate limit retry can double-apply a budget change.
- Shadow mode
- Running the full decision loop with writes disabled, recording what the system would have done. Disagreements between its proposals and human decisions become the tuning list before go-live.
How much autonomy the system gets
Autonomy is granted per action class, never per system, and it is earned through shadow-mode agreement rather than granted by the calendar. Classification is by money at risk in a day, the only measure that stays honest when someone senior asks why the machine was allowed to do that.
The ChatGPTalker Blast Radius Ladder
Five classes of ad account action, ordered by how much spend a wrong decision moves before a human notices. Each class carries its own approval rule, and an action moves up a class only after it has been observed disagreeing with humans and being right.
Reporting, alerting, anomaly notices, proposals with no write path. Blast radius is zero, so it is granted on day one. If a system cannot earn its keep at class 0, more autonomy will not save it.
Pausing one ad, adding a negative keyword, moving a bid modifier inside a stated band. Money at risk in 24 hours is capped at a figure you set. Applied automatically and reviewed weekly.
Budget moves inside a campaign, pausing an ad group, re-enabling something a rule paused. Applied inside working hours only, under the change budget cap, with an immediate notification.
Creating campaigns, changing targeting, swapping conversion actions. Proposed only, approved by a human. The cost of a structural mistake is not the spend, it is every downstream rule pointing at the wrong entity.
Billing, account access, tracking configuration, and any brand or regulatory claim in ad copy. The system may draft and propose. It may not apply, regardless of how well it performs below.
It lives in the repository beside the rules, it is reviewed whenever spend changes materially, and moving an action up a class is a pull request with a name attached. That is the whole governance model, and it is small enough that people follow it.
The build process stage by stage
Six stages. The first two contain no automation at all, and the fourth is where the project usually discovers what it is really about.
- Read-only audit and baseline
An inventory of every campaign, every native automated rule already running, every naming pattern and conversion action, plus a baseline: manual changes per week, month-end pacing error, reporting time. Without it you cannot later tell whether the build worked.
- Structure and naming convention
Agree the convention, then apply it in bulk. A document and an edit, not engineering, and the highest-value hour of the project. Anything outside it is invisible to the system, so the convention check becomes a permanent daily rule.
- Ingestion, metric layer and state store
Platform reporting and your conversion source in one place, metrics defined once, state refresh built. Nothing acts yet, but every number the system will act on is visible and reconciled.
- Rules in English, then in code, running in shadow
Policy drafted in plain language with whoever makes these calls by hand today, then implemented, then run with writes off. Two or three thresholds always turn out wrong, and one rule usually encodes a preference nobody could previously articulate.
- Autonomy granted class by class
Class 1 first, class 2 after a quiet week, class 3 stays in the queue unless there is a reason to promote it. Each promotion is a written decision with a date and a name on it.
- Handover and supervised running
Documentation, runbook, a recorded walkthrough, then a period where we watch alongside your team. The failure to plan for is the slow one, where nobody reads the digest for three weeks and a rule quietly pauses something that mattered.
The pressure to skip shadow mode always comes from the same place: the build looks finished. It is the only stage producing evidence about your specific account rather than about ad operations in general, and every project that skipped it spent the saved fortnight later, in production, with an audience.
What you get at handover
Everything runs in your accounts, on your infrastructure, under your credentials. If a handover leaves part of the system inside a vendor account, you have not bought a system. You have rented one at build prices.
Credentials, repository and alerting move to your side. We keep read access only for the supervision period, and it expires on a date rather than when someone remembers.
Your team edits a threshold, opens the pull request and confirms the effect in the change log. If that is uncomfortable, the documentation is wrong and we fix it.
Every number in the policy file checked against what actually happened, then quarterly, owned by your side.
Where these projects go wrong
The failures are consistent and none of them are about the model. Five we have caused, inherited or watched from close enough to learn from. A sixth, the scheduled job that silently stops and fires no alert because alerts are wired to errors, is why you alert on the absence of a successful run rather than on failures.
Automating on a metric nobody agreed on
The platform reports a conversion at click time inside its own attribution window. Your CRM records a qualified lead when a human marks it. The numbers differ, sometimes badly, and a pause rule reading the wrong one will switch off a campaign that is profitable on the definition that pays salaries.
Rules that fire on tiny samples
A rule that pauses anything with zero conversions after forty clicks will eventually pause almost everything, because low-volume entities spend most of their life in that state. Every threshold rule needs a minimum sample and a minimum spend before it is allowed an opinion, and both belong in the policy file where they can be argued with.
Two automations fighting over the same lever
The platform has its own rules. A bidding strategy may be adjusting toward a target. Someone may have a script running from three years ago that nobody remembers. Several actors then adjust the same budget on different schedules, each reacting to the others. Inventory everything that can write to the account in week one.
Retry storms and double-applied changes
You hit a rate limit. The client retries without an idempotency key. The platform had already accepted the first request. Now a budget has been set twice, or a step-based change has compounded. Backoff with jitter, a bounded retry count and content-derived idempotency keys are the reason the system can be trusted overnight.
Giving the model decision authority
A model asked whether to cut a budget produces a fluent, structured, plausible answer with reasons. Those reasons are generated alongside the answer rather than derived from it, and they are equally fluent when the answer is wrong. Use the model to explain a decision the rules made. Do not use it to make the call.
Loud failures get fixed the same day. The costly pattern is a rule slightly wrong for six weeks, applying consistently, inside its permitted blast radius, generating no alerts at all. The weekly digest, the threshold review and the disagreement log exist to catch exactly that.
What it costs to run once live
Four cost lines, and the biggest is not the one people ask about. Model tokens are usually the smallest number here. Maintenance is the largest, and it is the line most proposals leave out.
| Cost line | What drives it | How it scales |
|---|---|---|
| Model tokens | Drafting, summarising and commentary only. Decisions are code and cost nothing per run. | With entities you write about, not with spend. |
| Infrastructure | Scheduler, warehouse storage, queue, a small internal interface. | With data volume and retention. Ad spend does not affect it. |
| Platform API access | Most advertising APIs do not charge per call, but they enforce rate limits and several require a developer token. | Fixed per platform. Check current developer terms yourself. |
| Maintenance | API version deprecations, threshold reviews, new rules, changes to your conversion definitions. | With platforms covered and the rate of change in your business. |
The token arithmetic is worth doing yourself, because it is usually reassuring and it stops the conversation drifting into vague anxiety about AI costs. Take the entities written about per day, the tokens each call consumes, and the price per million your provider charges today. Model prices move, so take those figures from the provider's own pricing page rather than from any article, including this one.
The defaults are round numbers chosen to be edited, not anybody's real prices. Put in your own provider figures and your own volume.
If your figure comes out large, the cause is almost always that the system re-sends the same context on every call. Cache what does not change, send diffs rather than full states, and read token cost arithmetic before accepting a quote with a large token line in it.
Advertising APIs deprecate versions on published cycles and old versions eventually stop answering. Somebody has to watch the changelog, pin the version, test the upgrade and ship it. Get an hours-per-quarter figure in writing. A vendor quoting zero maintenance is either new to this or planning to bill it later as an emergency.
How to tell whether you need this
The threshold is not a spend figure. It is whether the same decision gets made repeatedly, from the same data, using criteria a person could write down. If the criteria cannot be written down, automation is premature and the first job is finding out what they actually are.
Fewer than three ticks and the useful next step is not a build. It is a week spent writing down what you currently decide and why, which is most of what an AI readiness audit does and which you can do yourself with a document and some discipline.
Take the single check that would have caught your most expensive recent mistake and write it as one scheduled script that emails you when it fails. If that alone changes how the week feels, the larger build has a strong case. If nobody reads the email, you have learned something more useful than a proposal would have told you.
How to start
The first engagement is read-only and short. We do not ask for write access until there is a written policy both sides have argued about, because write access before agreement is how vendors end up owning mistakes they had no way to prevent.
- Send the account structure, the platforms, the rough monthly spend and a description of the morning routine today. That is enough to say whether this is a fit.
- We run a read-only audit of one account, about a week, and return the rule inventory, the naming assessment, the automations already writing to the account, and the baseline.
- You get a build shape with a stage plan and a cost, or a written recommendation not to build.
- If it proceeds, the pre-launch assertion suite ships first. It is small, read-only until you enable it, and it tends to find something in week one.
To understand the shape of the work first, the neighbouring builds are workflow automation for the connective tissue and systems integration for the API layer underneath.
ChatGPTalker. Ad Operations Automation: Build, Launch, Pause and Report. chatgptalker.com/services/ad-operations-automation/