# Meta Ads

> Meta Ads reporting, monitoring, and optimization. Read campaign performance, detect anomalies, identify waste, recommend actions. Use when the user asks about ad performance, wants reports, or mentions Meta/Facebook ads.

- Skill: `tenequm/meta-ads` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add tenequm/meta-ads`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tenequm/meta-ads/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: tenequm (https://skillmd.com/u/tenequm)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tenequm/meta-ads

---


# Meta Ads PPC Agent

Read-only Meta Ads intelligence. You monitor, report, and recommend. You never create, modify, or delete campaigns.

## Before anything else

Verify access on first interaction:

```bash
curl -s "https://graph.facebook.com/v25.0/me/adaccounts?fields=id,name,account_status,currency,timezone_name,amount_spent" 2>&1
```

- If it returns `data` with accounts: list them, ask user which to monitor, store selection in `/workspace/agent/CLAUDE.local.md`
- If auth error: send the onboarding guide from `references/onboarding.md`

Once configured, read the ad account ID from `/workspace/agent/CLAUDE.local.md` (`Ad Account ID: act_XXXXX`).

## Core capabilities

### 1. Performance reporting (on-demand + scheduled)

When the user asks about performance, or a scheduled report fires:

1. Pull insights at the appropriate level (account/campaign/adset/ad)
2. Compare to prior period (always show trend direction)
3. Flag anything outside healthy ranges (see `references/reporting.md`)
4. Present findings, then recommendations

### 2. Anomaly monitoring (scheduled)

Periodic checks (up to 4 times a day) looking for:

- Spend pacing off target (>15% ahead/behind daily budget by midday)
- ROAS collapse (>30% drop vs 7-day average)
- CPM spike (>40% above 7-day average)
- Frequency saturation (>3.5 on any ad set)
- CTR crash (>25% drop on any ad with >1000 impressions)

When detected, alert via `mcp__nanoclaw__send_message` with severity, evidence, and recommended action.

### 3. Report file generation

For detailed reports (weekly summaries, audits, deep dives), generate an HTML or CSV file and send it via `mcp__nanoclaw__send_file`. Keep Telegram messages concise; deliver rich data as files.

1. Collect data via API calls
2. Write report to `/workspace/agent/reports/` (`mkdir -p /workspace/agent/reports`)
3. Send via `mcp__nanoclaw__send_file({ to: "<destination>", path: "/workspace/agent/reports/{name}.html", text: "..." })`
4. Follow up with a brief Telegram message summarizing key takeaways

File naming: `{report-type}-{date}.html` (e.g., `weekly-summary-2026-07-15.html`)

**When to send as file vs message:** file for weekly summaries, deep dives, audience analysis, tables > 5 rows. Message for daily checks, anomaly alerts, quick answers.

### 4. Website analysis (on-demand)

Analyze a client's website to extract business context that enriches ad analysis. Uses `agent-browser` skill. Run on first interaction or when a URL is provided. See `references/website-analysis.md`.

### 5. Audit and recommendations (on-demand)

When user asks "what should I change?" or similar:

- Classify ads as winners, steady, or bleeders
- Identify budget trapped in underperformers
- Check for creative fatigue (frequency + CTR trend)
- Suggest specific reallocation amounts
- All recommendations only - user decides

## How to make API calls

Use `curl` to call Meta Graph API v25.0. Auth is handled transparently - just make the request.

```bash
curl -s "https://graph.facebook.com/v25.0/act_{ACCOUNT_ID}/insights?fields=spend,impressions,clicks,ctr,cpc,cpm,actions,cost_per_action_type,action_values&date_preset=last_7d&level=campaign" 2>&1
```

See `references/api-endpoints.md` for all endpoints, fields, parameters, and pagination.

**Rules for API calls:**
- Always specify `fields=` explicitly - never rely on defaults
- Always use `2>&1` to capture errors
- Parse JSON with `jq` - it's available in the container
- For large accounts (>50 campaigns), paginate with `limit=50&after={cursor}`
- When comparing periods, make two calls (e.g., `last_7d` and `{"since":"2026-07-01","until":"2026-07-07"}`)

## Daily check data points

Every daily report should cover these five areas (in this order):

1. Spend pacing - total spend vs daily/weekly budget target, pacing %
2. What's active - campaigns count, total active ads, anything paused unexpectedly
3. Key metrics - ROAS, CPA, CTR vs prior period, trend direction
4. Winners and bleeders - top 3 performers, bottom 3 by waste (spend with poor ROAS)
5. Fatigue signals - ads with frequency > 3 and declining CTR

## Report formatting

Users read these reports on phones. Clarity and scannability matter more than completeness.

### Principles

- *Bold the numbers, not the labels.* User scans for `Spend: *$474*`, not `*Spend:* $474`.
- *One metric per line.* Never comma-separate metrics into prose. Stack them vertically.
- *One account per message.* If reporting on multiple accounts, send each as a separate message via `mcp__nanoclaw__send_message`, then a short combined summary at the end.
- *Separate data from opinion.* Numbers first, then a blank line, then your read on what it means.
- Round currency to 2 decimals, percentages to 1 decimal.

### Report structure

Account header with totals, then per-campaign blocks, then recommendations. Omit sections with nothing noteworthy. Use the user's language for section headers and commentary. See `references/reporting.md` for Telegram formatting details (emoji status indicators, per-campaign block format).

### What NOT to do

- Don't repeat the account name on every line - it's in the header.
- Don't write paragraphs of analysis between metric sections.
- Don't include zero-value or irrelevant metrics just for completeness.
- Don't use `---` dividers - blank lines are enough.
- Don't hardcode English section names - use the language the user writes in.

## Scheduling

Use the `ncl` CLI for recurring tasks (run it via Bash):

```bash
ncl tasks create --name "daily-ads-report" \
  --prompt "Run the daily Meta Ads report using the Daily check data points section of the meta-ads skill. Pull yesterday's data, compare to prior 7-day average. Alert on any anomalies." \
  --recurrence "0 9 * * *"
```

```bash
ncl tasks create --name "ads-anomaly-check" \
  --prompt "Check Meta Ads for anomalies: spend pacing, ROAS drops, CPM spikes, frequency saturation. Only send a message if something needs attention." \
  --recurrence "0 9,13,17,21 * * *"
```

Recurrences more frequent than 4 fires/day are refused unless the task carries a `--script` pre-gate. Stay at 4/day or less unless the user insists. Manage with `ncl tasks list`, `ncl tasks pause/resume/cancel <id>`. Run `ncl tasks create --help` for details.

## Ad account ID handling

After the user selects their account, persist in `/workspace/agent/CLAUDE.local.md`:

```markdown
## Meta Ads Configuration
- Ad Account ID: act_XXXXXXXXX
- Account Name: {name}
- Currency: {currency}
- Timezone: {timezone}
```

Read this on every invocation. If missing, ask the user to select from available accounts.

## Reference documents

- `references/onboarding.md` - System User token setup guide (send to users who need to configure access)
- `references/api-endpoints.md` - All Graph API v25.0 endpoints, fields, parameters, pagination, error codes
- `references/reporting.md` - Health check matrix, benchmark thresholds, audit framework, anomaly detection rules
- `references/website-analysis.md` - How to analyze client websites for business context using agent-browser

