---
name: paid_media_audit
description: Run a scored audit of paid ad accounts across search and social from plain exports, with no live account connection required: tracking health, wasted spend patterns, account structure, creative fatigue signals, budget and auction checks, one unified score, and a fix list ordered by expected impact. Use when asked to audit Google Ads, Meta Ads, TikTok Ads, LinkedIn Ads, or Microsoft Advertising, find wasted ad spend, review an account before scaling, or produce a paid media health check.
---

# Paid Media Audit

## Purpose

One vendor neutral audit for a whole paid media account, run from exports the client or the platform already provides. Other audit approaches split the job by platform and ask for a live connection to each one. This one takes CSV or spreadsheet exports plus screenshots of the settings that exports cannot show, applies one scoring rubric to every platform, and hands back a single report with a unified score and a fix list ordered by expected impact.

Scope: Google Ads, Microsoft Advertising, Meta Ads, LinkedIn Ads, TikTok Ads, YouTube and Demand Gen, and Performance Max style campaigns. The audit judges the account as found. It does not change budgets, pause campaigns, or edit tracking. Fixes are recommendations with owners, not actions taken during the audit.

## Workflow

### 1. Set the audit frame

Collect before looking at any numbers:

- Audit window, default the last 30 full days, plus the prior 30 days for trend where the export allows it.
- The one primary conversion per platform and what it is worth. A purchase, a qualified lead, a booked call. Write the value down. If the requester cannot name it, that is finding zero and the audit still runs, with every performance judgement marked provisional.
- A target cost per conversion or target return per platform or objective. Targets differ by objective. One blended target across a shoe sale and a B2B lead produces false findings, as the worked example in `references/worked-audit.md` shows.
- Backend system of record for reconciliation: shop orders, CRM, booking system.

State the frame at the top of the report. An audit with no stated window, conversion, and target cannot be checked by anyone after you.

### 2. Pull the exports

Ask for, per platform, a campaign level export for the window with spend, impressions, clicks, conversions, and conversion value or revenue. Add frequency and period budget where the platform exposes them. Then pull the deeper exports the check sheets need: search terms for search platforms, ad or asset level rows for creative checks, and placement rows where they exist.

Normalise campaign rows to the header the tool expects:

```
platform,campaign,spend,impressions,clicks,conversions,revenue,frequency,budget
```

Blank is allowed for frequency and budget. Blank is never treated as zero. Settings that do not export (conversion definitions, deduplication status, attribution windows) get checked on screen or by screenshot, and the report says which method was used for each one.

### 3. Run the numbers

Run:

```
python3 bin/audit.py campaigns <campaigns.csv> --target-cpa <target>
```

Run it once per objective when targets differ, filtering the export first, instead of forcing one target across everything. The tool prints per campaign ratios (CTR, CPC, cost per conversion, return on spend), zero-conversion spend and its share of total spend, spend concentration in the top 3 campaigns, budget use flags, and frequency flags.

Treat every flag as a candidate, not a conclusion. Zero-conversion spend is a review list: check the buying cycle and the search terms behind it before calling any of it waste. A frequency flag means look at the trend, not refresh the creative today.

### 4. Check tracking health first

Score this pillar before trusting anything else in the report:

- Primary conversion matches a real business outcome, not a proxy click.
- Platform conversions reconcile with the backend count for the same window. Report the gap size and direction, and the likely cause separately.
- Browser and server events deduplicate. On Meta, that means the Pixel event and the Conversions API event share one event name and one event_id, checked in Events Manager along with Event Match Quality. On Google, check enhanced conversions is on where it applies, since it sends hashed first-party data with the conversion to improve measurement.
- Sample five conversions and verify value and currency against real transactions.
- Offline outcomes are imported when the sale closes offline. A lead account with no import is optimising toward form fills, whatever the dashboard calls them.

If reconciliation fails by a wide margin, say so in the first paragraph of the report and mark every return figure as a platform claim until it is fixed.

### 5. Work the check sheets

Open `references/check-sheets.md` and run the shared checks, then the sheet for each platform family in the account: search, social feed, short video, and retail or Performance Max style. Sheets carry the platform specific facts the audit relies on, with their sources: Google Quality Score components and how Google says to use them, impression share split into budget and rank losses, Meta learning volume of about 50 optimisation events in 7 days, TikTok Smart Creative fatigue handling, and the IAB and MRC viewability thresholds for display and video.

Judge creative fatigue on trend, always: cost per result, CTR, and frequency across weeks, plus any fatigue label the platform itself shows. No platform publishes a universal safe frequency, so set the audit threshold from the account's own history, write the number you used in the report, and never present it as a platform rule.

### 6. Score the account

Fill the check sheet in the format of `assets/example_checklist.csv` (pillar, item, status: pass, partial, fail, or na) and run:

```
python3 bin/audit.py score <checklist.csv>
```

Weights and grade bands live in `references/scoring-rubric.md`: Tracking 25, Waste 20, Structure 20, Creative 20, Budget and Auction 15. The rubric is this audit's own method, stated openly. It is not a platform standard and the report must not dress it up as one. Items that do not apply are marked na and leave the denominator.

### 7. Order the fix list

Order every fix by expected impact: spend at stake, times confidence in the evidence, divided by effort. Write the reasoning in words next to each fix. Tracking fixes go first when tracking is broken, even when a waste fix looks bigger, because the waste figure itself cannot be trusted until the count is right. Give each fix an owner and a check-back metric: the number that should move, and the window to judge it in.

### 8. Write the report

Use the Output Contract below. Keep platform conversion counts on their own terms: different attribution windows mean platforms overlap, so never add platform conversions into one grand total. Compare each platform against its own target, its own history, and the backend count. Those are the only comparisons that hold.

## Output Contract

One markdown audit report containing:

1. Audit frame: window, primary conversion and value per platform, target per objective, backend system used for reconciliation, and which checks were done from exports versus on screen.
2. Unified score: pillar scores, total, and grade from `bin/audit.py score`, with any unscored pillar stated plainly.
3. Tracking verdict: reconciliation gap, deduplication status, and whether return figures in the report are verified or platform claims.
4. Numbers appendix: the full `bin/audit.py campaigns` output, so every figure in the report can be reproduced from the export.
5. Findings by pillar: each finding tied to a row in the export, a check sheet item, or a named settings screen. No finding without evidence attached.
6. Fix list ordered by expected impact: fix, owner, spend at stake, confidence, effort, and the check-back metric with its window.

## Operating Rules

- Exports only. This audit never needs account credentials, an API key, or a live connection. If someone offers credentials to make the audit easier, decline and work from exports.
- Never invent a benchmark. Cross-platform benchmark tables mix denominators (per follower, per impression, per reach) and industries, and produce findings that look precise and mean nothing. The baselines are the account's own history, its own targets, and its backend count.
- Label every cutoff. Any frequency, CTR, or cost threshold used in a finding is either a platform published figure with its source named, or an audit default the auditor set. The report states which, every time.
- Zero conversions is not proof of waste. Long buying cycles, offline closing, and broken tracking all produce the same column of zeros. Rule those out in writing before the word waste is used.
- Quality Score is a diagnostic, per Google's own guidance. Score the components on high spend keywords. Never set raising the score itself as a fix goal.
- Do not add platform conversion counts together. Report each platform on its own attribution terms and reconcile each against the backend separately.
- An audit changes nothing in the account. No pauses, no budget moves, no negative keyword uploads during the audit. The fix list is the handover. Acting on it is a separate, approved job.
- If an export is missing a column a check needs, mark that item partial or na and say what was missing. A smaller honest audit beats a complete looking one built on guesses.
