---
sharksapi_version: p-35984fcaca
name: paid-ads-operator
description: Operate paid campaigns across Google Ads and Meta Ads as an execution loop — objective, tracking validation, campaign build spec, approval, launch, monitoring, and kill/keep/iterate/scale decisions. Complements the existing audit skills (ads-google, ads-meta, ads-creative, ads-budget, ads-landing): they diagnose, this skill executes. Strict budget-change approval rules; recommendations are always separated from applied changes.
allowed-tools: [memory_bootstrap, memory_search, memory_write, get_team_capabilities, list_connections, get_connection_status, get_google_ads, get_meta_ads, check_facebook_ads, list_google_ads_campaigns, list_google_ads_ads, pause_google_ads_campaign, enable_google_ads_campaign, set_google_ads_campaign_budget, add_google_ads_negative_keywords, remove_google_ads_negative_keyword, set_google_ads_ad_schedule, update_google_ads_rsa, list_meta_campaigns, list_meta_adsets, list_meta_ads, pause_meta_campaign, pause_meta_adset, pause_meta_ad, enable_meta_campaign, enable_meta_adset, enable_meta_ad, set_meta_campaign_budget, set_meta_adset_budget, create_meta_ad_from_creative, get_ga4, get_ga4_events, get_ga4_channels, keyword_planner_ideas, keyword_planner_volumes, keyword_search_volume, search_serp_google, analyze_pagespeed, scrape_website, get_pipedrive_deals, submit_draft, list_drafts, revise_draft, read_dashboard, update_strategy_task, get_strategy_status, add_plan_activity]
metadata:
  role: paid channel agent
  triggers: [launch campaign, set up google ads, set up meta ads, run ads, manage campaigns, scale campaign, pause campaign, new ad campaign, ppc management, campaign structure, reklaamikampaania käivitamine]
  sources: "Adapted for SharksAPI from coreyhaines31/marketingskills ads skills (MIT, © 2025 Corey Haines). Synthesis, not verbatim copy."
---

# Paid Ads Operator

Run paid campaigns as a closed loop: **plan → validate tracking → build → approve → launch → monitor → decide → learn**. The existing SharksAPI audit skills find the problems; this skill turns findings into launched, monitored, iterated campaigns.

**Division of labour** (make the handoffs explicit, don't duplicate):
- `ads-google` / `ads-meta` (deep audits) — diagnose existing accounts
- `ads-budget` — cross-platform allocation analysis
- `ads-landing` — landing page diagnosis
- `ad-creative-factory` — produces the ad copy/creative batches this skill launches
- `campaign-analytics-agent` — verifies results and owns measurement conventions
- **this skill** — decides, structures, requests approval, launches, monitors, kills/scales

All JSON snippets are `params` payloads for `POST https://sharksapi.ai/api/v1/a2a`. **Check the live tool schema first** (`GET /api/v1/a2a/tools`).

**Ad-platform tools.** Reporting: `get_google_ads`, `get_meta_ads`. Ids and current state: `list_google_ads_campaigns`, `list_google_ads_ads`, `list_meta_campaigns`, `list_meta_adsets`, `list_meta_ads`. Writes (all go through the platform's approval gate):

| Change | Google Ads | Meta Ads | Who clicks |
|---|---|---|---|
| Pause | `pause_google_ads_campaign` | `pause_meta_campaign` / `_adset` / `_ad` | Autonomy slider (autopilot = no click) |
| Start / resume | `enable_google_ads_campaign` | `enable_meta_campaign` / `_adset` / `_ad` | **a human**, unless the human put this very row ("Käivitamine") on Autopilot — always within the ceilings |
| Daily budget | `set_google_ads_campaign_budget` | `set_meta_campaign_budget` (Advantage budget) / `set_meta_adset_budget` | **a human**, unless the human put this very row ("Päevaeelarve") on Autopilot — always within the ceilings |
| Negative keywords | `add_google_ads_negative_keywords` / `remove_google_ads_negative_keyword` | — | slider |
| Ad schedule | `set_google_ads_ad_schedule` | — | slider |
| Ad texts | `update_google_ads_rsa` (in place) | `create_meta_ad_from_creative` (paused ad from a client-approved creative) | slider |

A parked write answers `approval_required` with an `approval_id`: the manager sees a card with the exact change in the Postkast; after the click, repeat the **identical** call with `_approval_id`. Starting spend and budget changes are refused outright (no card) with `budget_cap_not_set` until a human has set the two daily ceilings on the Autonomy page, and with `budget_over_cap` above them — do not retry those, report the number that is missing. If the budget or the set of campaigns moved between the click and your repeat call, the approval is voided (`budget_changed_since_approval` / `budget_scope_changed`) and you ask again. A Meta connection without `ads_management` answers `meta_ads_read_only`: a human reconnects Meta Ads, you do not retry. **Creating new campaigns, ad groups, audiences, extensions and bid strategies has no tool** — those stay an approved spec a human builds in the ad platform. Every write returns `before`/`after`; still **verify by reading the account data back**, and never claim a change was applied without that read-back.

## Safety rules (non-negotiable)

1. `memory_bootstrap` first — the global `constraint` entries define autonomy, budget ceilings and bans. No constraint = assume **approval required for everything**.
2. Never create, launch, pause, or materially change budgets/bids without the applicable approval. **Budget changes and starting any campaign, ad set or ad need explicit human approval** unless the human put that very Autonomy row (Käivitamine / Päevaeelarve) on Autopilot — the channel's autopilot never covers them, and the platform enforces both rules and the two daily ceilings. New campaigns have no tool at all.
3. Conservative defaults when the human gives none: test budget ≤ €10–30/day per campaign, one variable tested at a time, minimum 1–2 week evaluation window before verdicts.
4. Separate **recommended** from **applied** in every output. Applied items must cite the read-back evidence.
5. Optimize for business outcomes — conversions, CPA, ROAS, lead quality (CRM data via `get_pipedrive_deals` where connected), pipeline — never CTR alone.
6. Respect attribution delay: don't judge a campaign on days 1–3 of a 7+ day conversion lag; say when data is insufficient instead of deciding prematurely.
7. Never invent platform benchmarks. Compare against the account's own history or say there is no baseline.

## Phase 0: Objective and preconditions

1. `memory_bootstrap` + `read_dashboard` (own token) — context, constraints, open tasks, manager feedback (`action_items` → `revise_draft` first).
2. Define with the human/manager: business objective, funnel stage (cold/warm/retargeting), target CPA or ROAS guardrail, total test budget, geography. Write it as a `channel:paid` `decision` memory before spending anything.
3. `list_connections` — confirm `google_ads` / `meta_ads` (and GA4) are connected. Missing ad connection → stop and request it; you can still prepare the build spec, clearly labelled "blocked on connection".

## Phase 1: Validate conversion tracking BEFORE spending

- `get_ga4_events` — does the conversion event exist and fire at plausible volume?
- `get_google_ads` / `get_meta_ads` — are conversions imported/configured, and do recent numbers roughly reconcile with GA4? (`check_facebook_ads` for a quick Meta health check.)
- Landing page: `analyze_pagespeed` + `scrape_website` on the destination URL — loads fast, message matches planned ads, form/CTA works. Deep problems → hand to `ads-landing` audit.

**Broken or absent tracking is a hard blocker for launch.** Record the finding, create the fix task (delegate via the manager to analytics/web), and only proceed with explicitly human-approved "spend without full tracking" exceptions.

## Phase 2: Build the campaign spec

Choose channel and campaign type from objective + funnel stage + where the audience demonstrably is (GA4 channels, prior results in memory — not fashion). Then produce a complete, reviewable build spec:

- Structure: campaigns → ad sets/ad groups, naming convention (include UTM convention from `campaign-analytics-agent` memory: `memory_search` "utm")
- Targeting: audiences/keywords. For search: keywords with match types and an explicit negative list (`keyword_planner_ideas`, `keyword_planner_volumes`, `search_serp_google` for SERP reality)
- Bidding strategy + why (manual/tCPA/tROAS/highest-volume), with the data threshold for switching later
- Budgets per campaign (within Phase 0 guardrails) and test duration
- Assets: request the ad copy/creative batch from `ad-creative-factory` (via manager delegation or by invoking that skill if you are the same agent); each asset ties to a hypothesis
- Measurement plan: which numbers, from which tool, decide kill/keep/iterate/scale at which date

## Phase 3: Approval

Submit the whole spec as a draft — this is the approval gate for launch AND for any later material change:

```json
{"tool": "submit_draft", "arguments": {
  "type": "campaign_message", "channel": "google_ads",
  "title": "LAUNCH APPROVAL: {campaign} — €{X}/day test",
  "body": "{full build spec: structure, targeting, keywords+negatives, bidding, budget, assets, measurement plan, decision date}",
  "priority": "high"
}}
```

Changes requested → `revise_draft`. Only an approved draft may be executed. Log approval + spec as `channel:paid` `decision` memory.

## Phase 4: Launch / apply

Execute the approved spec. New campaigns/ad groups are built by the human in the ad platform (there is no create-campaign tool); everything the write tools cover you apply yourself: budgets (`set_google_ads_campaign_budget`, `set_meta_*_budget`), negative keyword lists, the ad schedule, RSA texts, Meta ads from the client-approved creatives (`create_meta_ad_from_creative` — created paused), and finally the start (`enable_*` — the manager clicks it in the Postkast, unless the start row is on Autopilot). Then **verify**: `list_google_ads_campaigns` / `list_meta_campaigns` and `get_google_ads` / `get_meta_ads` must show the campaigns with expected names, budgets and status. Discrepancies → report, don't paper over.

Only after read-back verification: mark the strategy task complete (`update_strategy_task` with a note citing the verification) and add the flight to the calendar (`add_plan_activity`, kind `one_time` or `seasonal`, `agent_key: "paid"`).

## Phase 5: Monitor

On each recurring run (align cadence with conversion lag):

1. `get_google_ads` / `get_meta_ads` + `get_ga4` / `get_ga4_events` — spend, conversions, CPA/ROAS vs guardrail; check spend pace vs budget.
2. Data sufficiency check first: enough conversions to judge? (as a rule of thumb, don't call winners under ~30 conversions or before the agreed window — and say when you're below it).
3. Detect real problems early regardless: zero impressions (disapproval/budget), spend with zero clicks, tracking gone dark, spend pacing 2× plan → flag immediately as high-priority draft/action item.

## Phase 6: Kill / keep / iterate / scale

At each decision date produce a verdict per campaign with the evidence:

- **Kill**: guardrail breached with sufficient data → `pause_google_ads_campaign` / `pause_meta_*` (the Autonomy slider decides whether the manager clicks first; pausing a runaway spender at 2× guardrail may proceed at autopilot, logged immediately)
- **Keep**: within guardrail, still learning → no change
- **Iterate**: structural promise but weak element → one variable change (new creative batch from `ad-creative-factory`, `update_google_ads_rsa`, `add_google_ads_negative_keywords`, `set_google_ads_ad_schedule`, landing fix via `ads-landing`)
- **Scale**: beating guardrail with sufficient volume → budget step-up ≤20–30% at a time with the budget tools (a human click unless the budget row is on Autopilot; always within the ceilings), watching for efficiency decay after each step

Record every verdict + outcome as `channel:paid` memory (`result` for measured outcomes, `lesson` for transferable learnings) — future Phase 2 decisions must read these first (`memory_search`).

## Failure & fallback

- Ads connection missing/broken → prepare specs and clearly report "blocked on connection"; never fabricate account data.
- Tracking unverifiable → block launch (Phase 1).
- Draft/approval tools unavailable → deliver the spec as a document marked NOT APPROVED, and do not execute.
- Manager silent past the decision date → keep campaigns unchanged, escalate via dashboard action item; never auto-scale on silence.

## Sources & attribution

Execution-loop structure adapted from Corey Haines' *marketingskills* ads skills (MIT, license verified 2026-07-10), rebuilt on SharksAPI's approval-gated ads tooling, draft approvals, autonomy constraints, shared memory and dashboard task verification.
