create_pmax_campaign

Google Ads Write

๐Ÿšจ **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work ar

Endpoint

POST https://api.adspirer.ai/api/v1/tools/create_pmax_campaign/execute

Headers

Description

๐Ÿšจ **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link ๐Ÿ”„ LONG-RUNNING TOOL: Creates a Google Performance Max campaign with validated images. Emits MCP progress updates during authentication, asset upload, and campaign creation (typically 15-30 seconds). Progress stages: validate โ†’ commit. โš ๏ธ CRITICAL PREREQUISITES: 1. MUST have valid asset_bundle_id from validate_and_prepare_assets tool OR existing_image_ids from discover_existing_assets 2. MUST have all campaign text details from user 3. Creates REAL campaigns that cost REAL money 4. Call ONLY ONCE per campaign - do NOT retry automatically ๐ŸŽฅ **VIDEOS ARE OPTIONAL BUT RECOMMENDED:** - Videos significantly improve PMAX performance (higher CTR, better engagement) - **Always ask the user**: "Would you like to add YouTube videos to this campaign?" - If yes: validate with `validate_video` tool, then include `youtube_video_ids` parameter - If no: proceed without videos (campaigns work fine either way) - See STEP 3.5 below for complete video guidance โš ๏ธ GOOGLE ADS POLICY NOTE: Avoid keywords related to health conditions, medical treatments, financial hardship, or political topics. These may trigger policy violations. Use general service terms instead. Example: Use "senior care services" not "nursing care", "home services" not "medical services" ๐Ÿ“‹ **YOUR CRITICAL ROLE: Campaign Strategist & Text Creator** **STEP 1: Verify Prerequisites** Before calling this tool, ensure you have: - โœ… Valid asset_bundle_id from validate_and_prepare_assets (max 1 hour old) - โœ… All required campaign details from user (see below) If asset_bundle_id is missing or expired: - Guide user to re-upload images - Call validate_and_prepare_assets again - Get new asset_bundle_id **STEP 2: Collect Campaign Details from User** YOU MUST collect these from the user (ask if not provided): **REQUIRED Fields:** 1. **Campaign Name** - Example: "Premium Watches Summer 2025" - Make it descriptive and unique 2. **Daily Budget** - Google recommends ~$50/day USD equivalent for Performance Max - IMPORTANT: Accept the user's budget in their stated currency โ€” do NOT convert to USD - Ask: "What's your daily advertising budget?" 3. **Final URL** (Landing Page) - Must match verified domain in Google Ads - Example: "https://example.com/watches" - Ask: "What's the landing page URL for this campaign?" 4. **Business Name** - Maximum 25 characters - Example: "Luxury Watch Co" - Will appear in ads **STEP 3: Generate High-Quality Ad Copy** As an expert copywriter, you MUST create compelling ad text: **๐Ÿšจ BEFORE GENERATING TEXT - READ CHARACTER LIMITS ๐Ÿšจ** **Headlines (3-15 required):** - **STRICT LIMIT: 30 characters maximum per headline** - Count characters BEFORE calling this tool! - Examples: - "Premium Luxury Watches" (22 chars) โœ… - "Free Shipping" (13 chars) โœ… - "Certified Authentic" (19 chars) โœ… **Descriptions (2-4 required):** - **STRICT LIMIT: 80 characters maximum per description** - Count characters BEFORE calling this tool! - Examples: - "Shop authentic luxury timepieces with free worldwide shipping." (63 chars) โœ… - "Expert-curated Swiss watches. Certified authentic. Shop now." (61 chars) โœ… **Long Headlines (1-5 REQUIRED):** - **STRICT LIMIT: 90 characters maximum per long headline** - At least 1 is REQUIRED for Performance Max - Count characters BEFORE calling this tool! - Example: "Premium Swiss Watches - Certified Authentic, Free Worldwide Shipping" (70 chars) โœ… **โš ๏ธ WILL BE REJECTED IF YOU EXCEED LIMITS - NO RETRIES!** **โš ๏ธ COUNT CHARACTERS CAREFULLY - VALIDATION IS STRICT!** **How to Count Characters:** - Use extended thinking to count each text element - Double-check your character counts before calling - If close to limit, shorten it to be safe - Do NOT assume backend will fix it - it won't! - Use clear, concise language - Focus on user benefits **OPTIONAL Fields (use defaults if not provided):** - target_locations: Defaults to ["United States"] - target_languages: Defaults to ["English"] **๐ŸŽฅ STEP 3.5: YouTube Videos (OPTIONAL but Highly Recommended)** **โš ๏ธ IMPORTANT: Always ask the user about videos!** Videos significantly improve Performance Max campaign performance: - **Higher CTR**: Video ads stand out more than static images - **Better engagement**: Users watch videos longer - **Wider reach**: Serves on YouTube, Display, Discover, Gmail, Search - **Lower CPA**: Video ads often convert better **When to Ask:** - AFTER discovering existing assets - AFTER user uploads images - BEFORE calling create_pmax_campaign **What to Say:** "I've prepared your images. Would you like to add YouTube videos to this campaign? Videos can significantly improve performance (higher CTR and engagement). They're optional but recommended. If yes: - You'll need videos uploaded to YouTube (public or unlisted) - Minimum 10 seconds duration - I can validate them for you If no: - We can proceed with images only - You can add videos later if needed" **How to Include Videos:** 1. **User provides YouTube video URL or ID** - Example: "https://youtu.be/eIZtladpm6c" - Example: "eIZtladpm6c" 2. **You validate it** ``` Call: validate_video Arguments: { "video_url_or_id": "eIZtladpm6c", "platform": "pmax" } ``` 3. **Include in campaign** - Add `youtube_video_ids` parameter: `["eIZtladpm6c"]` - Can include up to 5 videos **Video Specifications:** - **Aspect Ratios**: Landscape (16:9), Square (1:1), Vertical (9:16) - **Duration**: Minimum 10 seconds (no maximum) - **Maximum**: 5 videos per campaign - **Source**: Must be on YouTube (public or unlisted, NOT private) - **Validation**: Happens via Google Ads API during campaign creation **If user doesn't have videos:** - Proceed without them (campaigns work fine without videos) - Mention they can add videos later - Note: Google may auto-generate videos from images if none provided **STEP 4: Call create_pmax_campaign** After you have ALL details: - Validate character counts yourself BEFORE calling - Call create_pmax_campaign with complete payload - Wait for response (may take 15-30 seconds) **STEP 5: Handle Response** **If SUCCESS:** - Celebrate with user! ๐ŸŽ‰ - Show campaign ID, name, budget, status - Explain campaign starts PAUSED for safety - ๐Ÿ”ด **IMMEDIATELY proceed to STEP 6 (Extensions)** โ€” do NOT stop here! **If FAILURE:** 1. **Asset Bundle Expired:** - Error: "Asset bundle not found or expired" - Action: Guide user to re-upload images - Call validate_and_prepare_assets again 2. **Character Limit Errors:** - Error: "Headline exceeds 30 characters" - Action: Shorten the text and try again - Show user which field caused the error 3. **Google Ads API Errors:** - Domain not verified - Budget too low - Account suspended - Action: Explain error clearly, provide troubleshooting steps 4. **Authentication Errors:** - Error: "No Google Ads account connected" - Action: Guide user to connect their Google Ads account ๐Ÿ”ด **STEP 6: MANDATORY โ€” Add Extensions After Creation** After the campaign is successfully created, you MUST: 1. Crawl the user's website to gather relevant page links, features, and service categories 2. Add sitelinks: at least 4 links to key pages (add_sitelinks tool) 3. Add callout extensions: 4-6 business highlights (add_callout_extensions tool) 4. Add structured snippets: categorized features (add_structured_snippets tool) 5. Verify with list_campaign_extensions to confirm all extensions are attached Extensions are FREE and increase ad visibility by 15-25%. NEVER skip this step. **DO NOT:** - Retry automatically on failure - Call multiple times for same campaign - Skip collecting user's campaign details - Proceed without valid asset_bundle_id - Skip adding extensions after campaign creation **Campaign Creation Best Practices:** ๐Ÿ”ด **PRE-STEP: ALWAYS Discover Assets First** - Before ANY PMAX campaign, call discover_existing_assets - Show user what assets were found (images, logos with dimensions) - Ask: "Would you like to reuse these existing assets, upload new ones, or mix both?" - Based on answer: - Reuse โ†’ Use existing_image_ids in create_pmax_campaign - Upload new โ†’ Use validate_and_prepare_assets โ†’ asset_bundle_id - Mix both โ†’ Use both parameters (hybrid mode) - ๐Ÿšซ NEVER skip this step 1. **Research First:** - Understand the business, products, audience - Review website messaging - Identify key selling points 2. **Strategic Ad Copy:** - Use action verbs - Include numbers/stats if available - Highlight benefits over features - Create urgency when appropriate - Match brand voice 3. **Quality Over Quantity:** - Better to have 5 great headlines than 15 mediocre ones - Each headline should be unique and valuable - Avoid repetition 4. **User Safety:** - Confirm budget with user before creating - Explain campaigns start PAUSED - Remind them this costs real money **Example Complete Flow:** User: "Create a PMax campaign for my luxury watch store" You: "I'll help you create a PMax campaign! First, let me check if you have any existing assets we can reuse." [Call discover_existing_assets(target_domain="luxurywatches.com")] [Returns: 8 images found] You: "Great news! I found 8 validated images from your previous campaigns: - 4 landscape images (1200x628) - 2 square images (1200x1200) - 2 logo images (1200x1200) Would you like to: A) Reuse these existing images (saves time, consistent branding) B) Upload new images C) Mix both (reuse some + add new ones)" [User chooses A - Reuse] You: "Perfect! Now I need a few details: 1. What daily budget would you like? (minimum $10, recommended $50+) 2. What's your landing page URL? 3. What locations should we target? (e.g., 'Bay Area', 'San Francisco', 'United States') I'll create compelling headlines and descriptions based on your luxury watch business." [User provides budget: $75, URL: https://luxurywatches.com, Location: Bay Area] You: "Great! Here's what I'll create: **Campaign Name:** Premium Watches Campaign 2025 **Budget:** $75/day **Landing Page:** https://luxurywatches.com **Locations:** Bay Area (targeted precisely) **Headlines I've generated:** - Premium Luxury Watches - Certified Authentic - Free Worldwide Shipping [...12 more] **Descriptions:** - Shop authentic Swiss timepieces with lifetime warranty and expert curation. - Discover premium watches from top brands. Free shipping. 30-day returns. [...2 more] **Using existing images:** 8 validated images (reuse mode) Ready to create this campaign? (It will start PAUSED so you can review first)" [User confirms] [Call create_pmax_campaign with existing_image_ids from discovery] **Returns:** - Campaign ID, name, status - Asset group summary - Next steps for activation **Execution Time:** 15-30 seconds (direct backend API call) **Authentication:** Required (MCP OAuth 2.1) **CRITICAL REMINDERS:** - Asset bundle expires after 1 hour - Campaign starts PAUSED for user safety - This costs real money - be transparent - Never retry on failure - report error to user - Provide excellent user experience throughout

Request body

All tool arguments are wrapped in an arguments object.

FieldTypeDescription
asset_bundle_idstring optionalAsset bundle ID from validate_and_prepare_assets tool (UUID format). Optional if existing_image_ids provided.
existing_image_idsobject optionalResource names of existing images to reuse (from discover_existing_assets). Optional if asset_bundle_id provided. โš ๏ธ MUST include 'logos_square' โ€” Google Ads REQUIRES a logo for every PMax asset group. If discover_existing_assets found no logos, use hybrid mode: upload a logo via validate_and_prepare_assets (asset_bundle_id) + pass existing_image_ids for other images. Example: {'marketing_images_landscape': ['customers/123/assets/456'], 'marketing_images_square': ['customers/123/assets/789'], 'logos_square': ['customers/123/assets/101']}
campaign_namestring requiredCampaign name (e.g., 'Premium Watches Summer 2025')
budget_dailynumber requiredDaily budget in the account's native currency. IMPORTANT: Do NOT convert currencies โ€” pass the user's amount as-is. Example: if user says 'โ‚น5000/day', pass 5000 (not a USD conversion). The Google Ads API interprets this in the account's currency automatically. Google recommends minimum ~$50/day USD equivalent for Performance Max campaigns.
headlinesarray optionalMUST BE JSON ARRAY: 3-15 headlines, each EXACTLY 30 characters maximum. REQUIRED for single-group mode. Omit if using asset_groups array. Commas ARE allowed within headlines. Example: ["Luxury Watches", "Swiss Made"]. COUNT CHARACTERS! ANY over 30 will be REJECTED!
descriptionsarray optionalMUST BE JSON ARRAY: 2-4 descriptions, each EXACTLY 80 characters maximum (STRICT!). REQUIRED for single-group mode. Omit if using asset_groups array. Commas ARE allowed within descriptions. Example: ["Shop authentic luxury timepieces with expert curation."] (63 chars). COUNT CHARACTERS BEFORE CALLING - ANY over 80 will be REJECTED!
business_namestring optionalBusiness name, max 25 characters. REQUIRED for single-group mode. Omit if using asset_groups array. Commas ARE allowed.
final_urlstring optionalLanding page URL. REQUIRED for single-group mode. Omit if using asset_groups array.
long_headlinesarray optionalMUST BE JSON ARRAY: REQUIRED 1-5 long headlines, each EXACTLY 90 characters maximum. REQUIRED for single-group mode. Omit if using asset_groups array. Google Ads REQUIRES at least 1 long headline for Performance Max campaigns. Commas ARE allowed. Example: ["Premium Swiss Watches - Certified Authentic, Free Shipping"]. COUNT CHARACTERS! ANY over 90 will be REJECTED!
target_locationsarray optionalOptional: Geographic targets -- supports countries, states, cities, and regions globally. Examples: ['India'], ['Bangalore, India'], ['Karnataka'], ['New York, NY'], ['United States', 'Canada']. Defaults to United States.
target_languagesarray optionalOptional: Language targets (e.g., ['English', 'Spanish']). Defaults to English.
youtube_video_idsarray optionalOptional: List of YouTube video IDs (11 characters each). Videos must be validated first using validate_video tool. Maximum 5 videos per campaign. Example: ['dQw4w9WgXcQ', 'jNQXAC9IVRw']. Videos are OPTIONAL for PMAX - campaigns can be created without them.
search_themesarray optionalOptional: Search themes hint Google AI about what your customers search for. Max 50 per asset group. NOT keywords โ€” no match types, no bids. Derive from keyword research, business profile, or user input. Example: ['AI ad management', 'automate google ads', 'MCP advertising tool']. Duplicates and blanks are filtered automatically. Pass [] (empty list) to explicitly skip search themes (e.g., remarketing-only campaigns). If omitted (null), themes are auto-derived from headlines.
audience_signalsobject optionalOptional: Audience signals tell Google AI who your ideal customers are. CRITICAL: Only use segment IDs returned by the search_audiences tool. NEVER fabricate, guess, or invent audience IDs. Wrong IDs will target completely unrelated audiences (e.g., 'Vehicles' instead of 'Jewelry') and waste the customer's ad budget. If search_audiences returns no results, skip audience signals entirely rather than guessing IDs. Keys: 'in_market_audience_ids' (List[int]), 'affinity_audience_ids' (List[int]), 'custom_audience_ids' (List[str] resource names), 'user_list_ids' (List[str] userList resource names for remarketing/customer match -- e.g. 'customers/123/userLists/456' from search_audiences), 'audience_name' (str). Example: {'in_market_audience_ids': [80432, 80210], 'user_list_ids': ['customers/123/userLists/456'], 'audience_name': 'SaaS Buyers'}
bidding_strategystring optionalBidding strategy for the campaign. Options: 'MAXIMIZE_CONVERSIONS' - Get the most conversions within budget. 'MAXIMIZE_CONVERSION_VALUE' - Optimize for highest value conversions. If not specified, the system auto-selects based on account data. Recommended: MAXIMIZE_CONVERSIONS for most new campaigns.
target_roasnumber optionalTarget ROAS (Return on Ad Spend) for MAXIMIZE_CONVERSION_VALUE bidding. Example: 3.0 means you want $3 revenue for every $1 spent. Only used when bidding_strategy='MAXIMIZE_CONVERSION_VALUE'.
asset_groupsarray optionalOPTIONAL: Multiple asset groups for a single PMax campaign. When provided, this OVERRIDES the flat headline/description/business_name/final_url fields. Each group is a dict with keys: group_name (required, unique), headlines (3-15), descriptions (2-4), long_headlines (1-5), business_name, final_url, existing_image_ids (optional), search_themes (optional), audience_signals (optional). Max 100 groups per campaign. All groups share the same campaign budget and bidding strategy. Example: [{'group_name': 'SaaS Founders', 'headlines': ['AI Ad Manager', 'Skip Dashboards', 'Automate Ads'], 'descriptions': ['Manage ads via AI chat.', '100+ tools.'], 'long_headlines': ['AI Ad Management'], 'business_name': 'Adspirer', 'final_url': 'https://adspirer.com', 'search_themes': ['AI ads'], 'audience_signals': {'in_market_audience_ids': [80432]}}]
customer_idstring optionalGoogle Ads customer ID. Required for multi-account users. Get from list_connected_accounts.

Example request

{
  "arguments": {
    "campaign_name": "string",
    "budget_daily": 1.0,
    "asset_bundle_id": "string",
    "existing_image_ids": [
      "customers/1234567890/assets/12345678901",
      "customers/1234567890/assets/12345678902"
    ],
    "headlines": [
      "string"
    ],
    "descriptions": [
      "string"
    ],
    "business_name": "string",
    "final_url": "string"
  }
}

Example responses

200 โ€” Success

{
  "success": true,
  "data": {
    "text": "(tool-specific textual output for create_pmax_campaign)",
    "quota": {
      "used": 42,
      "limit": 150,
      "tier": "plus",
      "period_end": "2026-05-01"
    }
  },
  "tool": "create_pmax_campaign"
}

400 โ€” Tool-level error (bad arguments / multi-account selection)

{
  "success": false,
  "error": "You have 25 meta_ads accounts connected. Please specify which account to use by passing the ad_account_id parameter:\n  - Acme Holdings (ad_account_id=\"act_123456789\")\n  - Acme EU (ad_account_id=\"act_987654321\")",
  "is_error": true,
  "tool": "create_pmax_campaign"
}

402 โ€” Quota exhausted

{
  "success": false,
  "error": "\ud83d\udea8 Monthly limit reached (150/150 tool calls on Plus tier).\nUpgrade to Pro at https://adspirer.ai to keep building.",
  "is_error": true,
  "tool": "create_pmax_campaign",
  "quota": {
    "used": 150,
    "limit": 150,
    "tier": "plus",
    "period_end": "2026-05-01",
    "upgrade_url": "https://adspirer.ai"
  }
}

Try it live


Adspirer REST API โ€” get an API key at adspirer.ai/keys ยท adspirer.ai