zuckerbot_create_campaign_from_spec
Build a complete Meta ad campaign from a declarative JSON spec. Use dry-run to preview resolved payloads, then create everything paused and ready for deliberate launch.
Instructions
Build a complete Meta campaign VERBATIM from a declarative JSON spec — no strategy generation, no copy authoring. Everything is created PAUSED, always; launching remains a separate deliberate call. Recommended flow: send with dry_run=true first to get the fully resolved Graph API payloads without creating anything, review them, then re-send without dry_run to build. Validation failures return an errors array of per-field {path, message, kind: schema|semantic} entries — fix each path and retry. Spec shape: campaign {name, objective OUTCOME_LEADS|OUTCOME_SALES, budget {type CBO_DAILY, amount, bid_strategy HIGHEST_VOLUME|LOWEST_COST_WITHOUT_CAP|COST_CAP}, special_ad_categories}, ad_sets [{name, conversion_location WEBSITE|INSTANT_FORM, attribution {click_days 1|7, view_days 0|1}, targeting {geo — ARRAY of 2-letter country codes e.g. ["AU"], age_min, advantage_audience, excluded_custom_audiences}, placements {mode MANUAL|ADVANTAGE_PLUS, exclude}; WEBSITE additionally: pixel_id, optimisation_event {type CUSTOM_CONVERSION, id}|{type STANDARD, event e.g. Lead}, performance_goal MAXIMISE_CONVERSIONS (the Ads Manager label, not the Graph enum); INSTANT_FORM instead: lead_form_id — the Meta instant form on the connected Page (no pixel_id, no optimisation_event, and its ads take NO final_url — the form is the destination; the creative's required display link is set automatically to the business's stored website, else its Facebook Page URL; single-image creative, no multi-ratio placement customisation)}], ads [{name, asset {type IMAGE_SET, refs {1x1,4x5,9x16 — https URLs or uploaded image hashes}}|{type VIDEO, ref — pre-uploaded Meta video id (upload one with zuckerbot_upload_ad_asset)}|{type EXISTING_AD, ad_id — clones that ad's image/video asset from the SAME ad account; copy, CTA and destination come from THIS spec}|{type EXISTING_POST, ad_id — reuses the SAME page post as that ad (object_story_id), keeping the post's social proof and engagement; or object_story_id "_" directly; the post must belong to the connected Page and the source ad to the connected ad account; the post carries ALL copy/CTA/destination, so OMIT primary_text, headline, description, cta and final_url on EXISTING_POST ads — declaring any is rejected as existing_post_copy_conflict}, primary_text, headline, description, cta, final_url (WEBSITE ad sets only; all five omitted for EXISTING_POST), ad_set_name?}]. EXISTING_AD and EXISTING_POST (ad_id form) specs need Meta credentials even for dry_run (the source ad is read from Meta). Use zuckerbot_list_custom_conversions to find custom conversion ids.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes | The declarative campaign spec (see tool description for the shape) | |
| dry_run | No | true = return the resolved Graph payloads without creating anything. Strongly recommended before a real build | |
| business_id | No | Optional business ID override for the authenticated API key |