Agent skill
meta-ad-launch-playbook
This skill should be used when the user wants to launch a Meta campaign end to end, create a batch of Meta ads, turn a folder of creatives into ads, go \"from creatives to live ads\", \"set up a campaign, ad set and ads\", or \"make ads with a different ratio per placement\".
Filed under Positioning and messaging and Team and enablement.
From Ad-Superpowers/ad-superpowers-plugin · 120 skills · 5 · pushed 2026-09-10
What it does when it runs
This skill should be used when the user wants to launch a Meta campaign end to end, create a batch of Meta ads, turn a folder of creatives into ads, go \"from creatives to live ads\", \"set up a campaign, ad set and ads\", or \"make ads with a different ratio per placement\". It is the single guided runbook from zero to live ads using the Ad Superpowers MCP write tools (meta_create, meta_create_ad), and it routes to the specialist skills for depth. Do NOT use for: getting a file into Meta / image_hash / hosting (use media-upload-guide), choosing a bid strategy in depth (use bid-strategy-selector), CBO vs ABO theory (use campaign-structure-advisor), writing the copy (use ad-copy-generator), creative testing matrices (use creative-diversification-generator), catalog / DPA strategy (use catalog-optimizer).
Read from the skill and the 0 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- None found.
- Hosts it reaches
- No third-party host appears in the skill or its bundled files.
- Tool permissions it declares
- No
allowed-toolsin the frontmatter. It only issues instructions, so there is nothing to bound. - Actions present in the files
- None. Instructions only.
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/Ad-Superpowers/ad-superpowers-plugin.git /tmp/ad-superpowers-plugin git -C /tmp/ad-superpowers-plugin sparse-checkout set "plugin/skills/meta-ad-launch-playbook" mkdir -p ~/.claude/skills/meta-ad-launch-playbook cp -R "/tmp/ad-superpowers-plugin/plugin/skills/meta-ad-launch-playbook/." ~/.claude/skills/meta-ad-launch-playbook/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
Or take the whole library
This repo ships a .claude-plugin manifest, so Claude Code can install all 120 skills at once. Plugin skills are invoked as /<plugin>:<skill>, so they never collide with your own.
/plugin marketplace add Ad-Superpowers/ad-superpowers-plugin /plugin
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
The skill
Source on GitHub ↗Reproduced in full from Ad-Superpowers/ad-superpowers-plugin/blob/9b6385d2d2d228e4dac096a1d6bc5715c04fa736/plugin/skills/meta-ad-launch-playbook/SKILL.md, which is licensed MIT (repository). 1,586 words, 13 headings.
Meta Ad Launch Playbook
The end-to-end runbook for going from "I have some creatives" to live (paused) ads with the Ad Superpowers MCP tools. It owns the orchestration — the order of operations and the decisions that trip people up — and hands the deep mechanics to the specialist skills. Follow it top to bottom.
The journey at a glance
[0] Page & Instagram → confirm the client profile resolves a Page (+ IG)
│
[1] Campaign → meta_create(entity_type="campaign") (budget → CBO)
│
[2] Ad set → meta_create(entity_type="adset") (+ creative-mode decision)
│
[3] Creatives → ads → meta_create_ad(...) per ad (sequential batch)
│
[4] Verify → meta_query / meta_get_creatives
Everything is created PAUSED by default. Nothing spends until you flip it to ACTIVE in review.
§0 Before you start: Page & Instagram
Every ad needs a Facebook Page, and Instagram placements need an Instagram account. You usually do not pass these by hand — meta_create_ad resolves them from the client profile:
- Auto-resolution. If the client has a
facebook_page_id(and optionallyinstagram_user_id) stored,meta_create_aduses them. You only passpage_id/instagram_user_idto override. - Set them once with
clients_updateif they are missing, so every future ad just works. - Facebook-only ads. Pass
facebook_only=trueto deliberately skip Instagram (page-only creative). Do not also pass an Instagram id — that conflicts. - Error
1815199("ad account has no access to this Instagram account") means the stored IG account is not linked to this ad account. Fix the link in Business settings or correctinstagram_user_id; this is surfaced as a real error now rather than a silent page-only fallback.
Discover what is available:
meta_query(account_id="act_...", entity_type="promotepages") # Pages this account can advertise
§1 Create the campaign
meta_create(
account_id="act_...",
entity_type="campaign",
name="Spring Launch",
objective="OUTCOME_TRAFFIC", # or OUTCOME_SALES / _LEADS / _ENGAGEMENT / _AWARENESS / _APP_PROMOTION
daily_budget=2000, # cents (€20.00/day). A budget is REQUIRED — pass daily_budget OR lifetime_budget.
status="PAUSED",
)
Two things to internalize:
- A campaign budget is required, which means every campaign is CBO (Campaign Budget Optimization). The budget lives on the campaign and the ad sets share it. (ABO / per-ad-set budgets are not creatable through the tool yet.)
bid_strategydefaults toLOWEST_COST_WITHOUT_CAP. You normally omit it. This is also why your ad sets do not need abid_amount(see §2). Only set a different strategy if you have a real reason:LOWEST_COST_WITH_BID_CAPorCOST_CAP→ require abid_amount(set on the ad set).LOWEST_COST_WITH_MIN_ROAS→ needs a minimum-ROAS target thatmeta_createcannot set today, so this strategy is not configurable through the tool yet (set it in Ads Manager).- For the "which strategy and what number" decision,
use bid-strategy-selector. For CBO vs ABO and budget-split theory,use campaign-structure-advisor.
§2 Create the ad set
meta_create(
account_id="act_...",
entity_type="adset",
campaign_id="<from step 1>",
name="NL · 25-45 · interests",
targeting={"geo_locations": {"countries": ["NL"]}, "age_min": 25, "age_max": 45},
optimization_goal="LINK_CLICKS", # must fit the campaign objective
status="PAUSED",
)
- No budget here. Under CBO the ad set inherits the campaign budget; passing one is rejected.
- No
bid_amountneeded with the defaultLOWEST_COST_WITHOUT_CAP. Only supplybid_amountif you deliberately chose a cap strategy in §1. advantage_audiencedefaults sensibly; some objectives require it (the tool tells you if so).
The creative-mode decision (do this before §3)
This is the choice that quietly breaks launches. Pick one:
| You want… | Ad set setup | How you build the ad in §3 |
|---|---|---|
| One creative concept, the right ratio per placement (the common case) | Standard ad set (leave is_dynamic_creative off) | placement_assets on meta_create_ad |
| Meta to auto-optimize across multiple text/creative variants | Dynamic Creative ad set: meta_create(entity_type="adset", ..., is_dynamic_creative=true) | body_variants (and/or asset combos) on meta_create_ad |
Two things people get wrong:
placement_assetsis NOT Dynamic Creative. It builds anasset_feed_specwith placementasset_customization_rules, but that is just placement customization and runs on a standard ad set. Usingplacement_assetsdoes not require — and should not be confused with — Dynamic Creative.body_variantsrequires a Dynamic Creative ad set. Today, if you passbody_variantsto an ad on a standard ad set,meta_create_adreturns success — and even appends a note like "Meta will A/B test these variants" — but Meta drops the extra variants. Do not trust that note unless the ad set was created withis_dynamic_creative=true. So decide here: if you want multiple text variants, create the ad set withis_dynamic_creative=true; if you just want one message shown well across placements, stay standard and useplacement_assets.
§3 Creatives → ads
This is where the playbook earns its keep: orchestration. The file-handling mechanics (how to upload, URL vs hash, filename→ratio matching, the full placement list) live in media-upload-guide — use media-upload-guide for those and do not re-derive them here.
Group, then build
1. Group your creatives by CONCEPT (a concept = one message/offer, in its various ratios).
2. One ad per concept.
3. Within a concept, bundle the aspect ratios via placement_assets (one ad serves the
right ratio per placement, and keeps a single engagement post across placements).
4. Split into separate ads when:
- the copy differs per ratio (placement_assets shares one body/headline), or
- you are mixing image and video (Meta rejects mixed media in one ad), or
- it is a genuinely different creative concept (that is a new ad).
A single concept with multiple ratios → one ad:
meta_create_ad(
account_id="act_...",
adset_id="<from step 2>",
headline="Spring launch",
body="One message, shown well everywhere.",
link_url="https://example.com",
image_hash="<1x1 hash>", # primary / catch-all fallback (1:1 is safe anywhere)
placement_assets=[
{"image_hash": "<9x16 hash>",
"placements": ["instagram_stories", "facebook_stories", "instagram_reels"]},
{"image_hash": "<4x5 hash>",
"placements": ["instagram_feed", "facebook_feed"]},
],
status="PAUSED",
)
Other creative types, same meta_create_ad call:
- Single image / single video — pass one of
image_url/image_hash/video_url/video_id(exactly one). - Carousel — pass
slides=[{image_hash, name, link}, ...](2–10 cards). - Per-placement carousel variants —
placement_assetsentries of the shape{slides, placements}.
For local Meta JPEG/PNG up to 20 MB (20,000,000 bytes), follow media-upload-guide:
assets_stage → client HTTP PUT → meta_upload_image(stage_id=...) →
image_hash → the existing meta_create_ad(image_hash=...). The preview must
be available and the client must have file/HTTP access. Reuse an existing
account-library hash when possible. Do not add media arguments to campaigns.
A new staged image normally costs two successful calls; 50 cost 100 before
ad creation and checks. On unknown upload outcomes stop and inspect, not restage.
Batch writes and pacing
There is no bulk-create tool — a batch is several meta_create_ad calls. You do not need to pace them yourself:
- The server mirrors Meta's documented rate model (writes are score-weighted, and uploads count as writes) and has an error-613 circuit breaker plus backoff on Meta's own usage headers. Follow provider backoff, staging capacity hints and ordinary workspace plan limits. The removal of a historical hourly cap does not mean unlimited calls or uploads.
- Run the calls sequentially rather than as an unbounded parallel fan-out: sequential calls give clean per-ad results and let the server react to Meta's signals between calls.
- If a write is throttled, the error says so — back off, then resume where you left off; wait guidance is included where Meta provides it.
- If one ad in a batch hits a Meta API error, the others still succeed — that call returns a structured error result rather than aborting the run, so you can retry just the failures. Bad inputs are different: invalid media combinations, missing placements, a malformed carousel, or a
facebook_only+ Instagram conflict raise a validation error before the API call, so check each call's inputs before firing the batch.
§4 Verify + honest limits
Read back what you created:
meta_query(account_id="act_...", entity_type="ads", fields=["id","name","status","adset_id"])
# inspect the creative copy + placements (creative_id comes from the meta_create_ad response)
meta_get_creatives(account_id="act_...", scope="single", creative_id="<creative_id>")
Common stumbles and the fix:
- "Bid amount required" on the ad set → you (or an inherited strategy) chose a cap strategy without a
bid_amount. With the defaultLOWEST_COST_WITHOUT_CAPthis should not happen; if it does, omit the strategy or supplybid_amount. - Instagram error
1815199→ see §0. body_variants"did nothing" → the ad set was standard, not Dynamic Creative (see §2).- Mixed image + video rejected → split into separate ads.
Honest limits (today):
- Catalog / Advantage+ catalog ads cannot be created through MCP: this release ships no catalog tool, so catalog data is not reachable either. Build catalog ads in Ads Manager;
use catalog-optimizerfor the strategy. - No bulk-create tool — batch = sequential
meta_create_adcalls (see §3).
Complementary skills
use media-upload-guide— get files into Meta (URL vs hash, hosting, filename→ratio, the full placement list).use bid-strategy-selector— pick the bid strategy and the number when you override the default.use campaign-structure-advisor— CBO vs ABO, budget splits, account structure.use ad-copy-generator/use video-script-writer— produce the copy/script before you build.use creative-diversification-generator— plan the creative matrix (concepts × angles) feeding §3.use catalog-optimizer— catalog / DPA strategy (creation is Ads-Manager-only for now).
Account integrity reminder
Every meta_create_ad and every upload is a write. The server backs off on Meta's throttle signals. Follow explicit retry hints and the upload guide's bounded window; workspace quotas still apply. If a write is throttled, the error says so; back off and resume. Everything ships PAUSED so you can review before any spend.
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- feature-launch-playbook by edupegoretti · 0
- launch by coreyhaines31 · 50,138
- sales-playbook by ericosiu · 3,528
- playbook-ad-library by growthenginenowoslawski · 705
- playbook-ai-specificity by growthenginenowoslawski · 705
- playbook-case-study-page by growthenginenowoslawski · 705
- playbook-company-name-cleaning by growthenginenowoslawski · 705
- playbook-creative-ideas by growthenginenowoslawski · 705
Need help setting it up?
This page tells you what meta-ad-launch-playbook does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.