--- name: meta-ads-write-operations context: fork description: "Safely executing Meta Ads write operations through the Pipeboard MCP server. Covers campaign creation, ad set setup, ad creation, audience management, creative uploads, budget changes, and entity status changes. Every mutation follows the CEP Protocol (Confirm > Execute > Post Check) and requires Michael's explicit approval before execution." argument-hint: "[client-name] [ad-account-id] [operation]" allowed-tools: - mcp__meta-ads__create_campaign - mcp__meta-ads__update_campaign - mcp__meta-ads__create_adset - mcp__meta-ads__update_adset - mcp__meta-ads__create_ad - mcp__meta-ads__update_ad - mcp__meta-ads__create_ad_creative - mcp__meta-ads__create_carousel_ad_creative - mcp__meta-ads__update_ad_creative - mcp__meta-ads__duplicate_campaign - mcp__meta-ads__duplicate_adset - mcp__meta-ads__duplicate_ad - mcp__meta-ads__duplicate_creative - mcp__meta-ads__upload_ad_image - mcp__meta-ads__upload_ad_video - mcp__meta-ads__bulk_update_campaigns - mcp__meta-ads__bulk_update_adsets - mcp__meta-ads__bulk_update_ads - mcp__meta-ads__bulk_upload_ad_images - mcp__meta-ads__bulk_upload_ad_videos - mcp__meta-ads__create_lead_gen_form - mcp__meta-ads__estimate_audience_size - mcp__meta-ads__get_campaigns - mcp__meta-ads__get_campaign_details - mcp__meta-ads__get_adsets - mcp__meta-ads__get_adset_details - mcp__meta-ads__get_ads - mcp__meta-ads__get_ad_details - mcp__meta-ads__get_ad_creatives - mcp__meta-ads__get_creative_details - mcp__meta-ads__get_insights - mcp__meta-ads__get_custom_audiences - mcp__meta-ads__get_pixels - mcp__meta-ads__get_account_info - mcp__meta-ads__get_account_pages - mcp__meta-ads__get_instagram_accounts - mcp__meta-ads__compare_performance triggers: - "create meta campaign" - "create facebook campaign" - "create meta ad" - "create facebook ad" - "meta ad set" - "meta budget" - "duplicate meta" - "duplicate campaign" - "pause meta" - "enable meta" - "meta creative" - "upload meta image" - "upload meta video" - "meta lead form" - "carousel ad" - "meta write" - "update meta" --- ## Campaign Creation Strategy Prerequisites Before creating any campaign, the agent must have one of: a. An approved Architecture Output from the Meta Ads Analysis Framework Phase 5 b. An approved greenfield build plan for a GREENFIELD lifecycle stage account c. Explicit instructions from Michael specifying exactly what to create The agent never creates campaigns based solely on its own judgment. When creating from an Architecture Output, follow specs exactly: campaign type, objective, bid strategy, budget, naming per `.claude/rules/campaign-naming-convention.md`, targeting, creative requirements. After creation, generate monitoring rules from `.claude/rules/post-creation-monitoring.md`. For Chrome based UI interactions, load `.claude/frameworks/platform-ui-guide.md`. # Meta Ads Write Operations (Pipeboard MCP) This skill covers all Meta Ads write operations executed through the Pipeboard MCP server (mcp__meta-ads__*). Every mutation follows the CEP Protocol and requires Michael's explicit conversational approval before execution. ## CEP Protocol (Confirm > Execute > Post Check) Every single write operation follows this protocol. No exceptions. ### Step 1: Confirm (Draft and Preview) Before calling any write tool, present the full details of what will happen to Michael in a clear summary: - What entity will be created or modified - Which ad account it affects (act_XXXXXXXXX) - All settings, values, targeting, and creative parameters - Budget and bidding implications - Special Ad Category detection (HOUSING, EMPLOYMENT, CREDIT, ISSUES_ELECTIONS_POLITICS) - Current state (for modifications) - Learning phase impact assessment Then STOP and wait for Michael's explicit approval. Do not proceed. Do not assume. If Michael says "go ahead" or "approved" or "do it," that counts. Anything ambiguous does not. ### Step 2: Execute (Create or Update) Only after receiving explicit approval, call the write tool. Unlike adloop which has a staging workflow, Pipeboard Meta Ads tools execute immediately on call. There is no dry_run option. This makes the Confirm step even more critical. **Key safety measure:** All campaigns MUST be created with `status: PAUSED`. Michael decides when to enable. ### Step 3: Post Check (Verify the Change) After execution, verify the change took effect using read tools: - `mcp__meta-ads__get_campaign_details` for campaign verification - `mcp__meta-ads__get_adset_details` for ad set verification - `mcp__meta-ads__get_ad_details` for ad verification - `mcp__meta-ads__get_creative_details` for creative verification Confirm: - The entity exists with the correct settings - Status is PAUSED (for new entities) or as intended (for updates) - Budget, targeting, creative, and other parameters match what was approved - No policy violations or issues flagged (check effective_status and issues_info) Log the verification result. If something does not match, flag it immediately to Michael. ## Safety Rules (Non Negotiable) These rules cannot be overridden under any circumstances. Also see `.claude/rules/meta-write-operation-safety.md` for the complete safety rule set. 1. **NEVER execute without Michael's explicit approval.** The CEP Confirm step in conversation is the safety gate. No write operation proceeds without Michael saying yes. 2. **New campaigns always PAUSED.** When calling `create_campaign`, always set status to PAUSED. Michael decides when to enable. No exceptions. 3. **Budget increases capped at 20% per operation.** If the current daily budget is $100, the maximum new budget in a single operation is $120. Larger increases require multiple steps with approval at each step. This also protects the learning phase from resetting (resets trigger on >20% budget changes). 4. **Detect Special Ad Categories before campaign creation.** If the client operates in legal, financial, housing, employment, credit, insurance, banking, investments, or payments, the campaign MUST have the correct special_ad_categories set. Missing this designation risks account suspension. 5. **Learning phase protection.** Do NOT edit ad sets that are in active Learning phase unless Michael explicitly directs it. Changes to budget (>20%), targeting, creative, bid strategy, or optimization event will reset learning. Check effective_status before any ad set modification. 6. **No immediate write tools exist.** Unlike adloop, there is no dry_run mode. Pipeboard write tools execute on call. This makes the Confirm step the only safety gate before execution. 7. **Removals via status change, not deletion.** Meta does not truly delete campaigns, ad sets, or ads. Use `update_campaign` with `status: ARCHIVED` or `status: PAUSED`. Do not use any delete endpoint. Archiving is the Meta equivalent of removal. 8. **Verify account ID before every write.** Before any write operation, confirm you are targeting the correct ad account ID. Use `mcp__meta-ads__get_account_info` to verify account name and configuration. 9. **All mutations logged.** Every write operation must be recorded in the client's history.md and as an Asana subtask. ## Tool Reference ### Campaign Operations | Tool | What It Does | Key Parameters | |---|---|---| | `create_campaign` | Creates new campaign | name, objective, status (PAUSED), special_ad_categories, buying_type, bid_strategy | | `update_campaign` | Modifies campaign settings | campaign_id, name, status, bid_strategy, daily_budget, lifetime_budget | | `duplicate_campaign` | Copies campaign with all ad sets and ads | campaign_id, rename options | ### Ad Set Operations | Tool | What It Does | Key Parameters | |---|---|---| | `create_adset` | Creates ad set within campaign | campaign_id, name, targeting, placements, budget, optimization_goal, billing_event, bid_amount, status | | `update_adset` | Modifies ad set settings | adset_id, targeting, budget, bid_amount, status, optimization_goal | | `duplicate_adset` | Copies ad set with ads | adset_id, campaign_id (target), rename options | ### Ad and Creative Operations | Tool | What It Does | Key Parameters | |---|---|---| | `create_ad` | Creates ad linking creative to ad set | adset_id, creative_id, name, status | | `update_ad` | Modifies ad settings | ad_id, name, status, creative_id | | `create_ad_creative` | Creates single image/video creative | name, object_story_spec (page_id, link_data or video_data), degrees_of_freedom_spec | | `create_carousel_ad_creative` | Creates carousel creative | name, object_story_spec with child_attachments array | | `update_ad_creative` | Modifies creative | creative_id, updated fields | | `duplicate_ad` | Copies ad | ad_id, adset_id (target) | | `duplicate_creative` | Copies creative | creative_id | ### Media Upload | Tool | What It Does | Key Parameters | |---|---|---| | `upload_ad_image` | Uploads image to ad account | image file or URL, account_id | | `upload_ad_video` | Uploads video to ad account | video file or URL, account_id | | `bulk_upload_ad_images` | Batch image upload | Multiple images | | `bulk_upload_ad_videos` | Batch video upload | Multiple videos | ### Lead Gen | Tool | What It Does | Key Parameters | |---|---|---| | `create_lead_gen_form` | Creates instant form | page_id, name, questions, privacy_policy, follow_up_action_url | ### Bulk Operations | Tool | What It Does | Key Parameters | |---|---|---| | `bulk_update_campaigns` | Updates multiple campaigns | Array of campaign updates | | `bulk_update_adsets` | Updates multiple ad sets | Array of ad set updates | | `bulk_update_ads` | Updates multiple ads | Array of ad updates | ### Planning (Read Only) | Tool | What It Does | Key Parameters | |---|---|---| | `estimate_audience_size` | Estimates audience reach | targeting_spec, optimization_goal | | `get_account_pages` | Lists available Facebook Pages | account_id | | `get_instagram_accounts` | Lists connected Instagram accounts | account_id | ## Common Workflows ### Workflow 1: Creating a New Conversion Campaign Prerequisites: client name, ad account ID, Facebook Page ID, target URL, creative assets, targeting strategy. 1. **Load client context.** Read `clients/{client-name}/` for profile, history, and open items. Verify the ad account ID via `mcp__meta-ads__get_account_info`. 2. **Check Special Ad Categories.** If the client is in legal, financial, housing, employment, or credit, the campaign MUST include the appropriate special_ad_categories. Flag this to Michael before proceeding. 3. **Estimate audience size.** Use `mcp__meta-ads__estimate_audience_size` with the proposed targeting to verify the audience is large enough (minimum 1,000 for custom audiences, recommended 100K+ for prospecting). 4. **Present campaign plan to Michael:** - Campaign name, objective (CONVERSIONS or OUTCOME_SALES), status: PAUSED - Budget type (CBO or ad set level), daily budget amount - Bid strategy (LOWEST_COST_WITHOUT_CAP, COST_CAP, BID_CAP, or MINIMUM_ROAS) - Ad set targeting (location, age, gender, interests, custom audiences, exclusions) - Placement selection (Automatic or manual) - Optimization event (Purchase, Lead, AddToCart, etc.) - Attribution window (7d_click, 1d_view default) - Creative format and copy 5. **Wait for approval.** Do not proceed without explicit confirmation. 6. **Execute in order:** a. Upload creative assets (`upload_ad_image` or `upload_ad_video`) b. Create campaign (`create_campaign` with status: PAUSED) c. Create ad set (`create_adset` with targeting and budget) d. Create ad creative (`create_ad_creative` with uploaded assets) e. Create ad (`create_ad` linking creative to ad set) 7. **Post check.** Verify each entity via read tools. Check effective_status and issues_info for any problems. 8. **Log everything.** Update client history.md and create Asana subtask. ### Workflow 2: Duplicating a Campaign for Testing 1. **Identify source campaign.** Pull campaign details via `mcp__meta-ads__get_campaign_details`. 2. **Present duplication plan.** Show: source campaign name and performance, what will change in the duplicate (targeting, creative, bid strategy, or budget), and test hypothesis. 3. **Wait for approval.** 4. **Execute.** Use `mcp__meta-ads__duplicate_campaign`. The duplicate will inherit all ad sets and ads from the source. Rename the duplicate to indicate it's a test variant. 5. **Modify the duplicate.** Update whatever test variable is being changed (targeting, budget, creative, bid strategy). 6. **Post check.** Verify the duplicate exists with correct settings and is PAUSED. ### Workflow 3: Budget Changes 1. **Pull current budget.** Use `mcp__meta-ads__get_campaign_details` or `get_adset_details` to see current daily or lifetime budget. 2. **Calculate the change.** Apply the 20% cap rule. If current budget is $100/day and the request is $150/day, flag that this is a 50% increase and must be staged: - Step 1: $100 > $120 (20% increase) - Step 2: $120 > $144 (20% increase, after 2 to 3 days stabilization) - Step 3: $144 > $150 (4% increase) 3. **Check learning phase.** Use `get_adset_details` to check effective_status. If the ad set is in LEARNING_PHASE, warn Michael that a budget change >20% will reset learning. 4. **Present to Michael.** Show: current budget, proposed budget, percentage change, learning phase impact, and staging plan if over 20%. 5. **Wait for approval, execute, post check.** 6. **Reminder:** Meta enforces 4 budget changes per hour per ad set and 10 account spending limit changes per day. Do not exceed these. ### Workflow 4: Creating Carousel Ads 1. **Upload all carousel card images.** Use `upload_ad_image` for each card (minimum 2, maximum 10 cards). 2. **Build the carousel creative.** Use `create_carousel_ad_creative` with: - child_attachments array (each with link, image_hash, name, description, call_to_action) - Page ID and Instagram account ID - Multi share optimized setting (let Meta optimize card order) 3. **Present full carousel to Michael.** Show each card: image description, headline, link URL, and CTA. 4. **Wait for approval, execute, post check.** ### Workflow 5: Pausing/Enabling Entities 1. **Identify the entity.** Pull current status via read tools. 2. **For pausing:** Use `update_campaign`, `update_adset`, or `update_ad` with status: PAUSED. Pausing is lower risk but still requires Michael's approval through the CEP flow. 3. **For enabling:** Use `update_campaign`, `update_adset`, or `update_ad` with status: ACTIVE. Enabling a paused campaign or ad set may trigger a new learning phase. Flag this to Michael. 4. **Post check.** Verify the status change via `get_campaign_details`, `get_adset_details`, or `get_ad_details`. ### Workflow 6: Creating Lead Gen Forms 1. **Gather form requirements.** Question types, privacy policy URL, completion CTA, follow up URL. 2. **Present form design to Michael.** Show: all questions with types, form type (MORE_VOLUME or HIGHER_INTENT), privacy policy link, follow up action. 3. **Important:** Lead gen forms CANNOT be edited after publishing. The form must be correct before creation. Double check everything. 4. **Wait for approval.** Execute `create_lead_gen_form`. 5. **Post check.** Verify the form was created and is ready to attach to ads. ### Workflow 7: Uploading Creative Assets 1. **Prepare assets.** Verify image specs: recommended 1080x1080 (1:1) for Feed, 1080x1920 (9:16) for Stories/Reels. Video: MP4 or MOV, under 4GB, recommended under 15 seconds for most placements. 2. **Upload.** Use `upload_ad_image` or `upload_ad_video`. For bulk uploads, use `bulk_upload_ad_images` or `bulk_upload_ad_videos`. 3. **Capture asset IDs.** The upload returns image_hash (for images) or video_id (for videos). Store these for use in creative creation. 4. **Note:** Uploading assets does NOT create ads. Assets must be assembled into creatives and then linked to ads in separate steps. ### Workflow 8: Advantage+ Creative Controls When creating or updating creatives, configure degrees_of_freedom_spec to control which AI enhancements Meta applies: | Feature | What It Does | Recommended Default | |---|---|---| | text_generation | AI variations of primary text | OPT_IN for most clients | | text_optimizations | Swaps text across positions | OPT_IN | | image_uncrop | AI expands images for different ratios | OPT_IN (test and verify) | | image_background_gen | AI generated backgrounds (catalog only) | OPT_IN for ecommerce | | image_touchups | Auto crop and adjust | OPT_IN | | creative_stickers | AI CTA stickers | OPT_OUT (often looks cheap) | | inline_comment | Shows most relevant comment | OPT_IN | | video_auto_crop | Auto crops video | OPT_IN for horizontal video | | adapt_to_placement | Auto fits to placement dimensions | OPT_IN | Present the full degrees_of_freedom_spec to Michael before applying. Each feature can be toggled individually. ## Meta API Rate Limits for Write Operations | Limit | Value | Consequence | |---|---|---| | Ad set budget changes | 4 per hour per ad set | Hard block. Wait for next hour window. | | Account spending limit changes | 10 per day | Hard block. Wait for next day. | | Account level API scoring | Read: 1 point, Write: 3 points, Max: 9,000 | 60 second cooldown if exceeded. | | Bulk operations | Subject to same scoring | Each entity in a bulk call counts separately. | ## Error Handling ### Common Meta API Errors | Error | Cause | Resolution | |---|---|---| | (#100) Invalid parameter | Wrong field name, value, or format | Check field names and value types. Common: budget in wrong units (Meta uses cents for some endpoints, dollars for others). | | (#2635) Special Ad Category required | Campaign targets housing/employment/credit without SAC designation | Add special_ad_categories to campaign creation. Cannot be added after creation for some objectives. | | (#1487851) Ad set budget too low | Budget below minimum for the optimization goal and audience | Increase budget. Minimum varies by country and optimization event. | | (#100.33) Invalid creative | Creative spec malformed or missing required fields | Check page_id, image_hash/video_id, link URL, and object_story_spec structure. | | (#17) Rate limit | Too many API calls | Wait 60 seconds. Check x-business-use-case-usage header for current utilization. | | (#190) Invalid OAuth token | Token expired or permissions revoked | Flag to Michael. Token needs refresh via Pipeboard. | | Policy violation | Creative, landing page, or targeting violates Meta policies | Review the policy feedback in the error message. Fix and resubmit. | | Learning phase reset | Budget/targeting/creative change on active ad set | This is expected for significant changes. Document it and set expectations (7 day learning period). | ### When Meta MCP Is Unavailable 1. Flag the issue to Michael immediately. 2. Do NOT attempt to make changes through Chrome Ads Manager as a workaround without approval. 3. Document what was planned so it can be executed once the MCP is restored. 4. Switch to read only analysis while the write path is down. ## Audit Trail Requirements Every write operation must be logged in the client `history.md` with this format: ``` ### [Date] Meta Ads Write Operation **Account:** [act_XXXXXXXXX] **Operation:** [What was done] **Tool:** [mcp__meta-ads__ tool name] **Entities affected:** [Campaign/Ad Set/Ad names and IDs] **Approved by:** Michael (timestamp or reference to approval) **Post check result:** [Verified/Issue found] **Learning phase impact:** [None/Reset triggered/Already in learning] **Notes:** [Any relevant context] ``` Also create an Asana subtask under the client parent task documenting the write operation and its verification status. ## Dependencies - Requires Pipeboard Meta Ads MCP server connected and authenticated - Requires Michael's explicit CEP approval for all write operations - Requires client context in `clients/{client-name}/` (profile, history, open items) - References `.claude/rules/meta-write-operation-safety.md` for complete safety rules - References `.claude/skills/meta-ads-deep-audit/references/insights-query-library.md` for post check queries - Uses read tools for verification after every write - Asana integration for audit trail and task tracking