Seven documented Google Ads API behaviors that corrupt reporting without ever erroring: metrics.conversions summing every action, all_conversions vs conversions confusion by campaign type, name-based filters breaking on renames, target ROAS living at two levels, conversion type fields contradicting their names, change history's limited window, and ads-side product counts retaining ghosts.
The Google Ads API rarely errors when you misuse it. It answers the question you literally asked, which is often not the question you meant, and the wrong number flows downstream looking exactly like a right one. These seven traps come from production accounts. Every one produced a confidently wrong report before a rule caught it.
metrics.conversions is a rollup, not a count of anything specific.Unsegmented, it sums every conversion action in scope: purchases, sign-ups, calls, whatever exists. On one account this inflated reported conversions 6.5x, because sign-ups were riding along with purchases in one number. The query was valid. The number was true. It just wasn't the number anyone thought it was. Fix: segment by conversion action, always, and define per report which actions are allowed to count.
all_conversions and conversions are different columns, and campaign type decides which one you need.Read Performance Max cost-per-acquisition from the wrong one and it looks roughly 3x better than reality; Search read from the other drifts too. This is documented behavior, not a bug, and almost nobody operationalizes it. Fix: a standing rule mapping column to campaign type, applied by default, so the answer cannot depend on who ran the query.
campaign.name fails silently the day someone renames.No error, no warning. The query returns zero rows for that campaign from the rename forward, and your report just quietly loses a campaign. We watched a mid-quarter naming-convention change that would have done exactly this to every name-based pull. Fix: filter on campaign.id, or on what a campaign is (advertising_channel_type), never on what it is currently called.
Campaign-level and ad-group-level targets can disagree on the same day in the same account, and the bidding system is honoring one of them. Any report that reads a single level is guessing which. Fix: pull both levels, know the precedence, report the effective target.
An action can be named after a server-side tracking vendor and still be, per its type, an ordinary client-side tag. We found exactly that on an audit: the label promised one measurement architecture, the configuration delivered another. Fix: query the type field across every action in the account and reconcile it against what each name implies. Trust the enum, not the string.
change_event only exposes a limited recent window, requires explicit date bounds, and caps how many rows a query returns. Ask for more than it holds and you get a partial answer or a failed query, and either way you are not reconstructing last year from it. Fix: treat change history as a recent-forensics tool, and archive anything you will want longitudinally the day it happens.
The ads-side reporting view retains historical inactive products. One account's ads view claimed roughly 8,291 products; Merchant Center, queried directly, held 4,076 active. Every catalog decision reasoned from the bigger number was reasoning about ghosts. Fix: Merchant Center is the source of truth for what is live; the ads view is the source of truth for what has spent.
The pattern is the same seven times: the API is precise, and precision without definitions produces confident nonsense. The connection is easy now; Google even gives away an official MCP server for it. What no one gives away is the rulebook that decides what each field is allowed to mean in your reports. Read: the live-query stack hub →
Are these bugs?
No. Every one is documented or by-design behavior. That is what makes them dangerous; nothing ever errors.
Does the free official MCP server avoid these?
No tool avoids them, ours included. They are semantics, not access. The fix layer is written rules applied on every query.
Which one should I check first?
Trap 1. If more than one conversion action feeds your headline number and they are different kinds of events, everything downstream is suspect until you segment.