API Reference โบ Google Ads โบ create_pmax_campaign
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
Authorization: Bearer sk_live_... โ your Adspirer API key (required)
Content-Type: application/json (required)
Idempotency-Key: <uuid> โ recommended for write operations to make retries safe
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.
| Field | Type | Description |
asset_bundle_id | string optional | Asset bundle ID from validate_and_prepare_assets tool (UUID format). Optional if existing_image_ids provided. |
existing_image_ids | object optional | Resource 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_name | string required | Campaign name (e.g., 'Premium Watches Summer 2025') |
budget_daily | number required | Daily 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. |
headlines | array optional | MUST 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! |
descriptions | array optional | MUST 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_name | string optional | Business name, max 25 characters. REQUIRED for single-group mode. Omit if using asset_groups array. Commas ARE allowed. |
final_url | string optional | Landing page URL. REQUIRED for single-group mode. Omit if using asset_groups array. |
long_headlines | array optional | MUST 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_locations | array optional | Optional: 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_languages | array optional | Optional: Language targets (e.g., ['English', 'Spanish']). Defaults to English. |
youtube_video_ids | array optional | Optional: 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_themes | array optional | Optional: 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_signals | object optional | Optional: 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_strategy | string optional | Bidding 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_roas | number optional | Target 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_groups | array optional | OPTIONAL: 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_id | string optional | Google 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