# MGID Tracking Health Monitor

Gate skill — validates conversion data before budget/source/creative actions.

Tools: [../_shared/ads-mcp-tools.md](../_shared/ads-mcp-tools.md)  
Schemas: [../_shared/schemas.md](../_shared/schemas.md)

Called standalone or as Phase 0 of `mgid-auto-optimization-simulator`.

---

## Required inputs

| Input | Required | Default |
|---|---|---|
| Scope | Yes | all active campaigns |
| Date range | Yes | last 7 days (end = yesterday) |

---

## MCP tools

| Tool | Purpose |
|---|---|
| `get_account` | Wallet balance/credit |
| `list_conversion_targets` | Account has conversion targets defined |
| `list_campaigns` | Active campaign ids + **config** (status, type, conversionTracking, bidding) |
| `get_portfolio_statistics` | **One call** — spend, clicks and conversions for every campaign |
| `get_campaign` | Full config when list row insufficient |
| `get_campaign_statistics` | Only for a campaign already flagged — daily rows answer "when did conversions stop" |

There is no account-goals or inline stats in `list_campaigns`. Take the whole
portfolio's numbers from `get_portfolio_statistics`; do **not** loop
`get_campaign_statistics` over the account.

Campaign types `search_feed` and `newsletter` have no teaser-level conversion
model — report them as out of scope rather than failing them.

---

## Workflow

For each active campaign in scope:

### 1. Tracking configured

From `get_campaign` / `list_campaigns` → `conversionTracking`:

- Sensors, postback stage, or URL target present → pass
- Missing → **critical**

Cross-check `list_conversion_targets` is non-empty for account-level setup.

### 2. Spend with zero conversions

From `get_campaign_statistics` → `totals`:

- **ASSUMPTION:** spent ≥ $50 AND conversionsBuy = 0 → **critical**
- **ASSUMPTION:** spent ≥ $20 AND clicks ≥ 200 AND conversionsBuy = 0 → **high**

### 3. Implausible CVR

- **ASSUMPTION:** clicks ≥ 500 AND conversionsBuy = 0 → **high**
- **ASSUMPTION:** CVR > 50% with clicks ≥ 100 → **medium**

### 4. CPA campaign without tracking

`bidding.strategy` is `cpa` and check #1 fails → **critical**

### 5. Warming up

Campaign created &lt; 3 days ago (if known) → `warming_up: true`, downgrade severity

---

## Gate rule

`gate_result = pass` only if no campaign has **critical** or **high** on checks #1 or #2.

---

## Output

**Chat:** human summary only (pass/warn/fail + bullet list).

**Optional file:** `TrackingHealthReport` JSON if user or simulator requests persistence.

Emit `fix_tracking` recommendations (no MCP write) when failed. Use readable ids
e.g. `fix-campaign-12061865-tracking`.

---

## Integration

On fail: simulator sets `gates.tracking_health = fail`, suppresses spend actions
with `blocked_by: ["tracking_unhealthy"]`.

No "test conversion recorded via API" check — no read tool supports it; ask user
to confirm test conversion manually if needed.
