What does a deep Google Ads audit of an online store by UPLIFY look like?
A real (anonymized) deep Google Ads audit of an online store by UPLIFY: 24 findings, full methodology, action plan and a 90-day roadmap. Prepared by the AI operator Nestor AI; a manager approves it.
Comprehensive Google Ads audit of an online store.
A real audit of a real UPLIFY client — fully anonymized. Niche, brands, domain and all IDs are hidden; all analytics, methodology, structure and actual metrics are preserved unchanged.
The audit in 90 seconds.
- Web purchases can be trusted (Ads↔GA4 discrepancy just 4.7%), the phone channel is nearly invisible to Smart Bidding.
- The new campaign with no exclusions for the 16 occupied cities — a compliance hole (P0).
- Active campaigns exceed the ROAS target by 3-4× — there is room to scale once margins are confirmed.
- Brand demand of ~4 800 queries/mo is not split into a dedicated campaign — blended ROAS is flattered.
- The feed is “thin”: 412 of 2 969 offers with issues, on average 9 of 25+ attributes filled in.
- Geo exclusions for occupied cities on the new campaign.
- Test conversion purchase_test — out of primary.
- Calls/leads → conversions in Ads (runbook in §3).
- Measurement: Smart Bidding will see phone sales.
- Waste: cut waste on geo / products / duplicate SKUs.
- Scale: 3-4× headroom on tROAS + underfunded top regions.
- Margins/targets not provided (client_input) → ₴ scaling blocked until confirmed.
- Merchant item-level limited by access rights → product conclusions at feed level.
- New campaign <30 days → read with a conversion-lag adjustment.
- 100% of spend covered: 5/5 campaigns, 13/13 asset groups, all 23 regions, all 14 conversion actions.
- Every finding comes with evidence (GAQL / GA4 / Merchant) and a confidence %.
- Ads↔GA4 reconciliation at value level, independent validation of the report.
Data limitations — read these first.
- STEP-0 not completed by the client: no margins, target CPA/ROAS, stock or promo calendar → budget-scaling conclusions are narrowed (client_input). This does not block the audit — it only narrows the relevant conclusions.
- Merchant is connected, feed read (≈2 969 offers); item-level statuses limited by access rights (2 968 in unknown) → product conclusions at feed level + a roadmap to lift the limitation (§6).
- PMax API: no per-asset conversions / search IS / placement cost → asset-level waste/scale is presented via impressions/CTR, not cost-proof.
- Conversion lag: new campaign (category B) <30 days, large share of UNKNOWN lag → the recent window is under-credited, confidence lowered.
- GSC unavailable — organic cross-check limited (not a blocker; we worked with Ads + GA4 + Keyword Planner).
Store profile + Claim Ledger.
An online store of mid-to-high ticket products for the home, ≈1 480 unique SKUs × 2 languages. High-ticket, high-consideration demand (long decision cycle), pronounced seasonality across two product lines, an active phone order channel. The site is bilingual UA/RU — so SKU duplication in the feed is deliberate localization, not an error.
free delivery above a threshold · official dealer → manufacturer warranty · installment / split payment · after-sales service · state support program.
“#1 / best / cheapest / market leader” · savings guarantee as an unconditional promise · any superlative without proof.
specific % discounts in copy (they change) · “1-day delivery” · free service.
Account state at a glance.
Measurement verdict — “web purchases can be trusted, the full funnel — with an adjustment”. Web conversion value in Ads (₴1 012 010) nearly matches GA4 (₴966 281) — a ~4.7% discrepancy, below the 15% threshold. But the phone/lead path is heavily under-counted: 1 488 hover_phones + 814 form_start in GA4 vs ~5 in Ads — Smart Bidding sees only part of the conversions.
Compliance / geo
P0The new active campaign (category B) lacks exclusions for the 16 occupied cities, which are set on 4 other campaigns. Budget waste + non-delivery risk → add the exclusions.
Measurement
P1The test conversion is still primary and records conversions (double counting); phone/lead conversions are heavily under-counted → Smart Bidding optimizes only toward web-purchase.
Growth / hygiene
P23-4× ROAS headroom → room to scale (after margins); category B groups have no search-themes / signals; callouts / snippets / price / promotion are missing.
24 findings — each with evidence.
P0 — critical now · P1 — significant, this week · P2 — this month's plan · P3 — hygiene.
| # | Area | Finding | Sev. | Conf. |
|---|---|---|---|---|
| F1 | Geo / compliance | The new campaign (cat. B) targets the whole country with no exclusions for the 16 occupied cities, which are set on 4 other campaigns. Fact verified via GAQL. | P0 | 95% / 80% |
| F2 | Measurement | The purchase_test conversion has primary_for_goal=true and recorded a conversion on the new campaign → double-counting risk. | P1 | 90% |
| F3 | Measurement / leads | Phone/leads under-counted: 1 488 hover_phones + 814 form_start (GA4, 30d) vs ~5 in Ads. Smart Bidding does not optimize toward calls. | P1 | 75% |
| F4 | Structure / naming | Inconsistent campaign and group naming (a typo in the brand, default Russian group names) — off-standard. | P3 | 95% |
| F5 | PMax signals | Both groups of the active campaign (cat. B) have 0 search-themes and 0 audience signals → PMax learns blind. | P2 | 95% |
| F6 | PMax creative | One group is empty (ad_strength=POOR, no headlines/media); the other is AVERAGE, with a slang/truncated headline. | P2 | 85% |
| F7 | Extensions | No callouts, structured snippets, price or promotion on any campaign — despite a strong set of ALLOWED offers. | P2 | 90% |
| F8 | Product / feed | Duplicate SKUs across the RU/UA feeds split impressions and budget: one language version converts, the duplicate has 0 conv and burns budget (5 SKUs confirmed). | P2 | 80% |
| F9 | Product / waste | Top-spend products with no conversions (4 items, ₴1 602 / ₴737 / ₴548 / ₴516, 0 conv) — candidates for isolation into a low-priority listing group. | P2 | 70% |
| F10 | Geo performance | 5 regions with spend and no conversions (≈10.6% of spend, 0 conv) — watchlist; don't cut blindly (small sample). | P2 | 60% |
| F11 | Geo concentration | Kyiv = 29% of spend (ROAS 10 / 5.6); top-ROAS regions (40 / 35 / 48 / 31 / 27) underfunded → room for concentration. | P2 | 65% |
| F12 | Budget / strategy | Active campaigns exceed the ROAS target by 3-4×, budget is not fully spent → room to scale / lower tROAS (after margins). | P2 | 70% |
| F13 | GA4 hygiene | GA4 sources include dev/spam referrers (localhost:8000, 127.0.0.1, a spam domain) with no internal-traffic filter. | P3 | 90% |
| F14 | Channels / incrementality | An independent paid channel outside Google Ads drives ₴665 646 in revenue from 1 049 sessions → affects Ads attribution. | P2 | 80% |
| F15 | Merchant | 1 product disapproved (legal takedown, RU+UA); 2 968 offers in unknown (diagnostics rights — see §6). | P3 | 70% |
| F16 | Devices (CTV) | Minor spend on Connected TV with no conversions (~₴62) — immaterial, monitor. | P3 | 80% |
| F17 | Funnel | Sharp drop from view_item (24 683) → add_to_cart (123) over 30d — typical for high-consideration, points to a phone/offline path. | P2 | 65% |
| F18 | Merchant / feed | The feed is “thin”: 412 of 2 969 offers with item-level issues (no GTIN, short titles, boilerplate descriptions, watermarked photos, price mismatch) — §6a. | P1 | 85% |
| F19 | Structure / brand | No branded Search campaign despite ~4 800 brand queries/mo: brand runs through PMax (pricier, no control) and inflates blended ROAS. | P1 | 85% |
| F20 | Structure / SKU | One PMax “for everything”: top-30 SKUs drive 68% of spend, but are mixed with a ~1 450 SKU tail → Smart Bidding averages the bids. | P1 | 80% |
| F21 | Signals / audiences | Not a single category-level audience signal: viewers of category A products are not fed as a signal into the category A campaign. | P2 | 90% |
| F22 | Measurement | Enhanced Conversions disabled — without hashed first-party data, matching typically loses 5-15% (especially cross-device). | P2 | 85% |
| F23 | PMax / mix | ≈38% of the active campaign's impressions are Display/YouTube placements with 0.1% CTR and zero conversions — a candidate for channel cleanup. | P2 | 70% |
| F24 | Search queries | ≈14% of Shopping traffic spend goes to queries outside new-product purchase intent (used, repair, spare parts) → account-level negatives. | P2 | 75% |
ADD before REMOVE.
| Prio. | What | Expected effect |
|---|---|---|
| P0 | Exclude the 16 occupied cities on the new campaign (copy from the 4 others) | Eliminate non-delivery / waste; compliance |
| P0 | Remove purchase_test from primary (secondary / archive) | Clean purchase count, no double counting |
| P1 | Connect call/lead measurement as a conversion in Ads (runbook below) | Smart Bidding “sees” phone sales |
| P1 | Add search-themes + audience signals to cat. B groups | Better PMax learning and targeting |
| P1 | Add callouts / snippets / price / promotion to the 2 active campaigns | CTR / ad quality, SERP coverage |
| P2 | Fill or disable the empty asset group (POOR) | Remove dead weight, raise ad_strength |
| P2 | Test: ↓tROAS on active campaigns OR ↑budget +10-25% (after margins) | More volume while preserving profitability |
| P2 | Resolve RU/UA SKU duplicates in the feed (supplemental / custom_label) | Less impression/budget cannibalization |
“Call measurement” runbook — to avoid the “calls in GA4, 0 in Ads” gap
- In GA4, mark call_phones + form_start/submit as key events (one per session for a call).
- Import into Ads as conversion actions; count = One for the call.
- Keep on secondary (observe) until quality is confirmed — don't push straight to primary, so the current tROAS isn't broken.
- After 7-14 days reconcile Ads ↔ GA4; if a CRM is available — reconcile call→sale.
Success criteria, monitoring and rollback.
Every change is controlled: the control metric, observation window and rollback trigger are defined before implementation. A “before” snapshot is stored; rollback is a single action.
| Change | Control metric | Window | Rollback trigger |
|---|---|---|---|
| Geo exclusion of 16 cities | Impressions/conversions in remaining geos stable | 7 days | Conversions drop >15% outside the excluded geos (unlikely) |
| purchase_test → secondary | Purchase conversion count (minus duplicates) | 7 days | Primary conversions drop >20% → check the tags |
| Calls → Ads conversions | Ads ↔ GA4 ↔ CRM reconciliation on count/quality | 7-14 days | Junk calls >30% → keep secondary, raise the duration threshold |
| Search-themes + cat. B signals | Campaign ROAS, share of new users | 14 days | ROAS −10% two weeks in a row → remove the added signals |
| Brand Search (§3e) | Total brand conversions PMax+Search; brand CPC | 14-21 days | Total conversions drop >10% → return brand to PMax |
Target structure map before → after.
| Campaign | Status | Action | Mode |
|---|---|---|---|
| Category A (PMax) | ENABLED · ROAS 15.2 | KEEP + signals/extensions; test ↑budget / ↓tROAS | phased / experiment |
| Category B (PMax, new) | ENABLED · ROAS 10.9 | PROTECT geo exclusions + signals + fill the groups | direct + phased |
| “Everything else” + B | PAUSED · ROAS 7.3 | INVESTIGATE why paused; possible consolidation | question for the client |
| Category C (electric) | PAUSED · ROAS 0.27 | KEEP PAUSED weak unit economics | do_nothing |
| Category D (niche) | PAUSED · ROAS 31.6 (84 clicks) | INVESTIGATE little data, high return; relaunch for the season | experiment |
📐 Experiment design: PMax experiment 50/50. Conversions are few (8-9/mo), so a significant read of the ROAS effect takes 6-10 weeks per arm; read with a confidence interval, not a point estimate. Scaling is phased (+10-15% per step); “success” only with ≥20-30 conversions per arm.
The 90-day roadmap.
Foundation
P0: geo exclusions + test conversion out of primary. Call measurement, GA4 filters, fix the disapproved product.
ADD
Signals for cat. B groups; callouts / snippets / price / promotion; fill the empty group; naming.
Tune
Let PMax learn on clean conversions; test ↓tROAS (experiment); monitor lag.
Prune
SKU duplicates and waste products in the feed; decisions on weak geos based on accumulated data.
Scale
After margins — scale into top-ROAS regions; relaunch the niche campaign for the season.
Brand Search + Winners / Long tail.
1 · Split out Brand Search
F19Brand queries (~4 800/mo) are the highest intent and the cheapest click, but are currently served by PMax with no copy control and inflate blended ROAS. Steps: brand core as exact/phrase → exclude brand from PMax (negative list) → read brand/generic separately.
2 · Winners / Long tail split
F20Top-30 SKUs = 68% of spend and ROAS 15+, but mixed with a ~1 450 SKU tail. Via supplemental feed (reversible): PMax Winners (~60% of budget, aggressive tROAS) / PMax Catalog (~35%) / Low-priority (waste + duplicates, ~5%).
3 · Seasonal track for cat. B
SEASONIn a shared campaign the seasonal peak competes with evergreen exactly when demand is most expensive. A separate campaign + custom_label_2=season: raise the budget 2-3 weeks before the peak — and wind it down just as controllably.
Migration is phased to avoid resetting learning: W1 — labels in the supplemental feed; W2 — Winners on ~20% of budget in parallel; W3-4 — shift budget based on actual ROAS. Every step comes with a “before” snapshot and a rollback trigger (§3a).
Copy analysis with verdicts.
Keyword Planner (UA, real volumes/mo): category B — top query 49 500, then 18 100 / 8 100 / 2 400 / 1 900 / 880; category A — top 12 100, then 2 900 / 2 400 / 1 900 / 1 300 + brand queries 1 900 / 1 600 / 720 / 590. High-volume brand queries are a reserve for search-themes and a future Search campaign.
| Type | Copy (by category) | Verdict | Reason |
|---|---|---|---|
| H | Buy [category A] | KEEP | EXCELLENT, intent-match |
| H | Economical [category A] for the home | KEEP | Benefit, grounded |
| H | Best [products A] for the home | REPLACE | Superlative “best” → “from an official dealer” (trust) |
| H | Top [subcategory A] | REPLACE | “Top” is weak → “[subcategory] −15%” (benefit, grounded on the LP) |
| H | [Category A] + warranty | KEEP | Service/warranty confirmed in ALLOWED |
| H | Best prices on [cat. B slang] | REPLACE | Slang/truncation + superlative → “[category B] in stock” |
| H | [Category B], top series | KEEP | Intent (2 400/mo) |
| H | (no brand hook) | ADD | Brand query demand 1 900/mo → “[brands]” (social proof) |
| H | (no service hook) | ADD | Service query demand 880/mo → “Warranty & service” |
⚙️ Executable copy-replacement cards are generated by the COPY-HOOKS live engine (the “Copy” tab in OS) — this is analysis only. In PMax, assets are not judged by conversions (per-asset conv=0 always).
Prompt cards for new images.
Ready to paste into a generator for the weak/empty group. Each is a draft concept and needs brand/legal review. The product is masked; the technique is as in the real report.
1 · Product in a modern interior
1.91:1 · pmax/display · photorealism2 · Product in a home interior
1:1 · pmax · trust3 · Seasonal comfort
4:5 · discovery/display · desire4 · Studio trust-shot
1.91:1 · clean e-commerce · premiumGA4 audiences + category signals.
Base audiences (GA4 → Ads)
Buyers 90d — exclusion from prospecting + LAL signal · Cart abandoners 30d — remarketing (currently no RM audiences in PMax signals) · High-intent — view_item ≥2 or hover_phones/form_start without a purchase · Engaged ≥N — for LAL.
The principle of signal match
A signal must match the campaign's product mix — a “generic” audience applied to all campaigns dilutes PMax learning. Category-level signals today — zero (F21).
| Audience (GA4) | Condition | Signal target |
|---|---|---|
| Category A viewers, 30d | view_item where item_category=A, no purchase | Category A campaign (audience signal) |
| Category B viewers, 30d | same for B | Category B campaign |
| Cart without purchase, by category | add_to_cart − purchase, by item_category | Matching campaign — the warmest signal |
| Cat. A buyers → cross-sell | cat. A purchase within 180d | Category A accessories campaign (repeat purchase) |
Merchant supplemental feed: custom_label_0 = margin_tier · custom_label_1 = performance (bestseller / 0-conv) · custom_label_2 = season · RU/UA SKU deduplication. Supplemental only — never products.insert.
A deep dive into the feed.
This is what a product breakdown looks like with full Merchant rights (item-level): for each issue type — how many offers, what it threatens, how to fix it. Total: 412 of 2 969 offers (≈14% of the feed).
| Issue | Offers | Risk | How to fix |
|---|---|---|---|
| No GTIN/MPN | 187 | Limited performance, weaker matching | GTIN from the supplier; where missing — honestly set identifier_exists=false |
| Short title without attributes | 94 | Doesn't match long-tail queries | Template: [Category] [Brand] [Model] [Key attribute] |
| Boilerplate supplier description | 61 | Duplicated content → weaker relevance | Rewrite the top-50 by spend; the rest in phases |
| Watermarked / low-quality photos | 38 | Disapproval risk + lower CTR | Clean pack shots (GMC requirements) |
| Site price ≠ feed | 19 | Suspension risk for price mismatch | More frequent feed refresh + monitoring |
| “Phantom” out-of-stock | 12 | Lost impressions | Reconcile stock statuses, fix the sync |
| Disapproved (legal) | 1 | Product not shown at all | Remove the claim from the page + re-review |
Risks and caveats.
- Low conversion volume (8-9/mo per campaign): read tests with a confidence interval over 6-10 weeks, not a weekly point.
- Conversion lag: high-ticket demand converts slowly — recent-window estimates are systematically understated.
- The phone channel is invisible until call measurement is in place — ROAS judgments cover web purchases only.
- ₴ scaling is blocked until the client confirms margins/targets — the minimum-evidence rule.
- Item-level Merchant conclusions require full access rights — until then they are narrowed, not final.
- Seasonality: week-over-week comparisons are valid only with category A/B seasonal windows taken into account.
Coverage + summary.
| Campaign | Status | Spend ₴ | Conv. | Value ₴ | ROAS | Target |
|---|---|---|---|---|---|---|
| Category A | ENABLED | 51 135 | 25.0 | 775 813 | 15.2 | 3.7 |
| Category B | ENABLED | 8 419 | 9.0 | 91 331 | 10.9 | 4.7 |
| Other + B | PAUSED | 13 120 | 8.0 | 95 902 | 7.3 | 14.0 |
| Category C | PAUSED | 11 270 | 1.0 | 3 042 | 0.27 | 14.0 |
| Category D | PAUSED | 1 451 | 2.0 | 45 922 | 31.6 | 14.0 |
| Total | 85 396 | 45.0 | 1 012 010 | 11.9 |
| Geo (top) | Spend ₴ | ROAS | Signal |
|---|---|---|---|
| Kyiv city | 16 648 | 10.0 | top spend, strong |
| Region H | 3 929 | 40.6 | ⭐ underfunded |
| Region G | 4 594 | 35.1 | ⭐ underfunded |
| 5 regions | ≈9 000 | 0 | ❌ watchlist (0 conv) |
Coverage: campaigns 5/5 (100% of spend) · asset groups 13/13 · geo — all 23 regions + Kyiv · all 14 conversion actions. GAQL: campaign · conversion_action · campaign_criterion LOCATION · geographic_view · segments.device/lag · asset_group · shopping_performance_view. Reconciliation: Ads 1 012 010 ↔ GA4 966 281 → +4.7% (web-purchase). Data — live read-only.
How this audit was made.
This report was prepared by Nestor AI — our AI operator in UPLIFY OS: senior-level analysis using our own methodology, with independent validation (20 review notes incorporated). All proposed changes are approved by a manager — nothing is applied automatically; every change is reversible and logged.