What to automate first, and what to keep human
Not every task deserves automation. Three criteria filter the list quickly. A task is a good candidate when it is repeatable (same steps every time), low-risk (a mistake is cheap to undo or cannot reach production) and verifiable (you can check the output against a number, a list or a GAM field).
| Automate first | Automate with a human approval | Keep human |
|---|---|---|
| Morning delivery and pacing report | Targeting changes on a live line item | Pricing and yield strategy |
| Under-delivery and budget alerts | Archiving unused ad units | Commercial negotiation, make-goods |
| Targeting and key-value checks before push | Activating or pausing line items in batches | Launching a campaign with no review |
| Inventory hygiene audit (read-only) | Creating ad units or placements | Anything you could not explain to the advertiser |
The pattern is always the same: read first, propose second, write last. An agent that only reads and summarizes gives you value on day one with no risk to the network.
The setup in one paragraph
You need an AI agent that can call Google Ad Manager through a controlled interface. With OrbiAds, that interface is an MCP server (or the CLI): the agent does not write SOAP or REST calls itself, it picks from a catalogue of named tools such as reporting, line_items, targeting and inventory, each with typed parameters. If the concept is new, read what a Google Ad Manager MCP server is, then follow the MCP quickstart. Connect a network with read access first.
Workflow 1: reporting (the morning delivery check)
- Inputs: the GAM network, a date range (yesterday and month-to-date), and the thresholds you care about.
- What the agent does: runs
reporting.check_underdelivery_alerts(default threshold 0.8 on the delivery indicator) andreporting.check_budget_alerts(default 95% spent), then pulls detail withfetch_delivery_reportorrun_gam_report. It ranks the problems and writes a short summary. - Human control point: none is needed for the run itself, because the workflow is read-only. The human decides what to escalate. Run it for the first two weeks next to your manual check and compare the two.
- Output: a short message or a CSV (
export_report_csv,get_report_download_link) with flagged line items, their delivery indicator and a suggested next check. A step-by-step version with Claude is in the daily report guide.
Workflow 2: targeting validation before anything is pushed
- Inputs: a trafficking brief or a line item draft: ad units or placements, geo, key-values, sizes.
- What the agent does: checks that every key and value exists (
targeting.list_custom_targeting_keys,search_custom_targeting,get_custom_targeting_values), that the ad units exist and are active (targeting.search_ad_units), and that the combination can serve (targeting.get_inventory_forecast). For a line item that already exists it callsline_items.verify. - Human control point: the agent reports a pass or a list of problems. Nothing is created until a person reads that list. Silent key-value typos are the classic failure: a value that does not match the ad requests targets nothing, and the line item simply does not deliver. Details in targeting validation and the key-values guide.
- Output: a checklist per line item: each targeting element, found or missing, active or not, forecast available or not.
Workflow 3: inventory hygiene and unsold inventory
- Inputs: the ad unit tree, a look-back window (for example 90 days) and your naming rules.
- What the agent does: lists ad units with no traffic (
inventory.find_inactive_ad_units, 1 to 365 days, default 90), runsinventory.audit_inventoryoraudit_skill.hygiene_checkfor structural issues, and pullsreporting.fetch_inventory_reportto see where inventory goes unsold. See unsold inventory in GAM. - Human control point: the audit is read-only. Archiving (
inventory.archive_inactive_ad_units) is a write: it defaults todry_run = trueand returns a preview plus aconfirmation_token. A person reads the list of ad units before confirming. Google's documentation states that an archived ad unit becomes ineligible for delivery and leaves the targeting picker, so a wrong archive has real consequences. - Output: a list of candidate ad units to archive, a list of structural findings, and a list of unsold-inventory hotspots.
A worked example: an under-delivering line item, end to end
The numbers below are illustrative, invented to show the shape of the workflow. They are not a customer result, and the tool output is simplified.
Step 1: detect (read-only)
At 08:00 the agent runs the under-delivery check. GAM exposes a deliveryIndicator on each line item, with an expectedDeliveryPercentage and an actualDeliveryPercentage. The check flags items whose actual-to-expected ratio falls below the threshold.
| Line item | Type | Expected | Actual | Ratio | Flag |
|---|---|---|---|---|---|
| ACME_Autumn_ROS_300x250 (id 4821330) | STANDARD | 62% | 41% | 0.66 | below 0.8 |
| ACME_Autumn_Video_Preroll | SPONSORSHIP | 55% | 54% | 0.98 | ok |
| Brand_Sport_Takeover | SPONSORSHIP | 70% | 66% | 0.94 | ok |
Step 2: diagnose (read-only)
The agent reads the line item (line_items.get_full, line_items.verify) and checks its targeting. Google's troubleshooting guide lists targeting that does not match ad requests, insufficient inventory and overbooking among the common causes, and the agent works through them in that order. In this example it finds that the line item targets the key-value section=sport, while the site tags its pages with section=sports.
{
"lineItemId": "4821330",
"finding": "targeted value does not match ad requests",
"targeted": {"key": "section", "values": ["sport"]},
"valuesInNetwork": ["sports", "news", "finance", "sport"],
"suggestedChange": {"key": "section", "values": ["sport", "sports"]},
"risk": "low: adds an existing value, removes nothing"
}
Step 3: propose (dry run)
The agent calls line_items.update_targeting with dry_run = true (the default). Nothing changes in GAM. The response contains a preview of the change and a confirmation_token.
Step 4: human approval
The trafficker reads the proposal: one value added, nothing removed, no other line item touched. They also check that widening the targeting does not collide with an exclusivity agreement. It does not, so they confirm.
Step 5: apply
The agent repeats the call with dry_run = false and the token. The operation is logged with tenant, timestamp and job identifier, and can be read back with audit.query_audit_log.
Step 6: verify
The agent re-runs line_items.verify right away, then checks the delivery indicator after the next reporting cycle. A fix is only a fix when the number moves: if the ratio has not improved after a day or two, the agent reports it instead of stacking more changes.
| Check | Before | After |
|---|---|---|
| Actual vs expected delivery | 41% vs 62% | Goal: ratio back above 0.8 within a day or two |
| Site tags matched by the targeting | 1 of 2 values | 2 of 2 values |
How to measure whether it works
Do not trust a percentage from a vendor, including us. Measure your own baseline for two weeks before you automate anything, then compare. Four indicators are enough:
- Time spent on recurring reports: minutes per day on the morning check, counted by the person doing it.
- Trafficking error rate: line items that needed a correction after going live, divided by line items created, per month.
- Time to fix a delivery issue: from the moment an under-delivery shows up in GAM to the moment a fix is confirmed.
- Alert precision: of the alerts the agent raised, how many a human judged relevant. If it is low, tighten the thresholds before you widen the scope.
An example of assumptions, to adapt: if the manual morning check takes 25 minutes and reviewing the agent's summary takes 5, you gain 20 minutes per working day. That is arithmetic on your own inputs, not a promise.
Guardrails and common pitfalls
- Start read-only.
check_credentialsreports whether the session can write. Stay on reads until the reports match what your team sees. - Use the dry run for every write. Write actions such as
line_items.update,update_targetingandarchive_inactive_ad_unitsdefault todry_run = trueand need aconfirmation_tokenfrom the preview. - Scope the network. If you have access to several networks, confirm the active one (
network.get_network_info,list_accessible_networks) before any write. Acting on the wrong network is the most expensive mistake. - Give least privilege. GAM roles still apply: the agent acts on behalf of a user and cannot do more than that user's role allows. Google requires specific permissions even to archive ad units. See the security documentation.
- Keep an audit trail and review it weekly during the first month.
- Do not automate what you cannot verify. If there is no number or GAM field to check the result against, keep a human in the loop.
- Do not batch before you trust. Single line items first, then batches (
pause_batch,activate_batch).
Next steps
- Pick one of the three workflows and run it read-only for a week.
- Connect your network with the getting started guide or the MCP quickstart.
- Add the validation step from targeting validation before your next push.
- See how the Ad Ops automation platform packages these workflows for teams.
Google sources: Troubleshoot line item delivery, Deactivate or archive an ad unit, Target key-values and the LineItem reference (v202605).
