add_asset_group_listing_filter
ChatGPTSubdivide a retail Performance Max asset group's products — include or exclude a partition. Splits products by dimension_type=value (e.g. product_brand=Nike, product_type=Shoes). exclude=true makes the partition UNIT_EXCLUDED (those products won't serve from this asset group); otherwise it's UNIT_INCLUDED. Retail PMax has NO per-node bids (bidding is fully automated). The "everything else" sibling is created automatically. FIRST call on an unpartitioned asset group subdivides the root. To split an EXISTING partition further, pass parent_filter_id (from get_asset_group_listing_filters). Required: asset_group_id, dimension_type, value. Optional: level (type/category), index (custom_attribute), exclude, parent_filter_id.
add_campaign_label
ChatGPTAttach an existing label to a campaign. Get the label_id from list_labels (or create_label first). This tags the campaign for filtering and reporting; it does not change delivery. Required: campaign_id + label_id.
add_demandgen_ad
ChatGPTAdd a new Demand Gen ad (image or video) to an EXISTING Demand Gen ad group. Use this to add MORE ads to an ad group you already have — e.g. test a second creative, or add a video ad alongside an image ad. It does NOT create an ad group or change targeting; get the ad_group_id from get_campaign_structure (it must be a DEMAND_GEN ad group). Formats: - multi_asset (default) — image ad: marketing_images (landscape 1.91:1), square_marketing_images (1:1), portrait_marketing_images (4:5), logo. Google mixes them. - video_responsive — video ad: youtube_video_ids (1-5) + logo. long_headlines recommended. Creative bounds (Demand Gen): headlines 1-5 (max 40 chars), descriptions 1-5 (max 90 chars), business_name max 25, long_headlines max 90 chars. Assets: provide NEW images via marketing_images/etc. as [{"url": "...", "name": "..."}], OR reuse existing asset resource names via existing_images, OR a logo by logo_asset_id (from discover_existing_assets). Videos are referenced by youtube_video_ids. Parameters: - ad_group_id (REQUIRED) — existing DEMAND_GEN ad group - ad_format, final_url (REQUIRED), business_name (REQUIRED), headlines (REQUIRED), descriptions (REQUIRED) - long_headlines, call_to_action, image/video/logo sources (optional per format) The ad is created ENABLED; delivery is still gated by the ad group + campaign status. Execution time: 10-20 seconds (assets are uploaded then the ad is created in one atomic mutate).
add_demandgen_ad_group
ChatGPTAdd a new ad group with targeting and ads to an EXISTING Demand Gen campaign. Use this after create_demandgen_campaign to add additional ad groups. Each ad group can have: - Different location targeting (e.g., US cities vs India cities vs UAE cities) - Different audience targeting (e.g., marketing pros vs tech founders vs agency owners) - Same or different ad creative (headlines, descriptions, images, videos) Reuse Existing Audiences: To attach an existing audience (from Google Ads UI or a previous campaign), pass: - audience_segments.existing_audience_id: numeric audience ID - audience_segments.existing_audience_resource_name: full resource name Create New Audiences: To create a new audience from interest segments: - audience_segments.in_market_audience_ids: [80517, 80520] - audience_segments.affinity_audience_ids: [92948] Use search_audiences to find segment IDs. Parameters: - campaign_id: Demand Gen campaign ID (from create_demandgen_campaign or list_campaigns) - ad_group_name: Descriptive name - Same creative fields as create_demandgen_campaign (headlines, descriptions, images, etc.) - target_locations: Location targeting specific to this ad group - audience_segments: Audience targeting specific to this ad group Execution time: 10-20 seconds
add_display_ad
ChatGPTAdd another Responsive Display Ad (RDA) to an EXISTING Display ad group. When to use: - User wants to A/B test multiple creatives in the same ad group - User asks to "add another ad" to an existing Display ad group Required: - ad_group_id - headlines (1-5 @ 30ch), long_headline (1 @ 90ch), descriptions (1-5 @ 90ch), business_name (≤25ch), final_url - At least one landscape AND one square marketing image (new or via existing_images) Character limits (strict): - Headlines: MAX 30 chars each - Long headline: MAX 90 chars - Descriptions: MAX 90 chars each - Business name: MAX 25 chars Execution time: 4-8 seconds
add_display_ad_group
ChatGPTAdd a new DISPLAY_STANDARD ad group (with its own targeting + a Responsive Display Ad) to an EXISTING Display campaign. When to use: - User wants another ad group inside a Display campaign (different targeting + different creative) - User asks to "add an ad group to my Display campaign" Each ad group can have: - Its own audience_segments, topics, managed_placements, display_keywords, demographics - Its own responsive display ad (creative + assets) - Optional manual CPC/CPM bid (inherits campaign bidding otherwise) Required: - campaign_id (Display campaign from list_campaigns) - ad_group_name - Full RDA payload: headlines (1-5 @ 30ch), long_headline (1 @ 90ch), descriptions (1-5 @ 90ch), business_name (≤25ch), final_url - At least one landscape AND one square marketing image (new URL or reuse via existing_images) Execution time: 8-15 seconds
add_display_audiences
ChatGPTAdd audience targeting to a Display ad group. audience_segments keys: - user_interests — list of affinity/in-market category IDs (from search_audiences) - custom_audiences — list of resource names like "customers/123/customAudiences/456" - user_lists — list of remarketing list resource names like "customers/123/userLists/789" - combined_audiences — list of combined audience resource names CRITICAL: Only use IDs returned by search_audiences. NEVER fabricate — wrong IDs waste budget on unrelated audiences. Example: `` audience_segments: { "user_interests": ["80517", "80520"], "user_lists": ["customers/123/userLists/111"] } `` Execution time: 2-5 seconds.
add_display_keywords
ChatGPTAdd contextual display keywords to a Display ad group. Display keywords are ALWAYS BROAD-match (Google ignores match_type for Display). Each keyword tells Google what context to show ads in — NOT what users are searching. Example: `` display_keywords: [ {"text": "running shoes"}, {"text": "cheap knockoff", "negative": true} ] `` Execution time: 2-5 seconds.
add_display_placements
ChatGPTAdd managed placements (websites, mobile apps, YouTube channels, YouTube videos) to a Display ad group. Placement types: - website — value is a domain or URL (e.g., "nytimes.com") - mobile_app — value is an app ID in format "mobileapp::1-com.example.app" - youtube_channel — value is a channel ID (e.g., "UCxxxxx") - youtube_video — value is a video ID (e.g., "dQw4w9WgXcQ") Example: `` placements: [ {"type":"website","value":"nytimes.com"}, {"type":"youtube_video","value":"dQw4w9WgXcQ"} ] `` Execution time: 2-5 seconds.
add_display_topics
ChatGPTAdd topic targeting to a Display ad group. topics is a list of topic IDs or topicConstants/<id> resource names. Example: ["topicConstants/1017", "1020"] (the bare form gets auto-prefixed). Topic IDs are published by Google at https://developers.google.com/google-ads/api/data/codes-formats#verticals Execution time: 2-5 seconds.
add_meta_ad
ChatGPTUser wants to add another ad/creative variation to an EXISTING ad set. DO NOT USE to create a new campaign. For new campaigns: - Video campaign - create_meta_video_campaign - Image campaign - create_meta_image_campaign - Carousel campaign - create_meta_carousel_campaign Common scenarios: - A/B test ad copy: Different headlines, primary text, or CTAs for the same audience - A/B test creatives: Different images or videos for the same audience - Format testing within one audience: Image vs video ad in the same ad set - Dynamic Creative (DCO): Multiple images + text variations in one ad — Meta auto-optimizes KEY DISTINCTION — add_meta_ad vs add_meta_ad_set: - Same audience, different creative/copy - use THIS tool (add_meta_ad) - Different audience/targeting - use add_meta_ad_set instead (creates a new ad set) Ads in the same ad set SHARE: targeting, budget, schedule, pixel tracking. Each ad has its OWN: creative (image/video/carousel), headline, primary text, CTA, landing page. IMPORTANT: You need an ad_set_id from a previously created ad set. Use list_meta_ad_sets first if you don't have the ad_set_id. Supports all 3 ad types + Dynamic Creative: - image: Different image + copy variation - video: Different video + copy variation - carousel: Different card set + copy variation - Dynamic Creative (DCO): Pass image_urls (2-10 images), headlines (up to 5), primary_texts (up to 5), descriptions (up to 5). Meta tests ALL combinations and optimizes delivery automatically. Dynamic Creative Optimization (DCO) workflow: 1. Create ad set with is_dynamic_creative=true via add_meta_ad_set 2. Call this tool with image_urls (list of 2-10 image URLs), plus optional headlines, primary_texts, descriptions arrays 3. Meta will test all image × headline × text combinations and optimize 4. DCO ad sets support only 1 ad — if the ad set already has is_dynamic_creative enabled, this tool auto-detects it Note: Cannot mix image_urls (DCO) with image_url (single image) or placement-specific images. Standard workflow: 1. Get ad_set_id from prior campaign creation or list_meta_ad_sets 2. Write variant ad copy (different headline/primary_text/image) 3. Call this tool with ad_set_id + new creative + copy
add_meta_catalog_ad
ChatGPTUser wants to add ANOTHER catalog ad to an existing catalog ad set — e.g. to test multiple creatives (different copy, CTA, or product set on the creative) within one ad set. Adds the ad PAUSED.
add_meta_catalog_ad_set
ChatGPTUser wants to add ANOTHER ad set to an existing Advantage+ Catalog campaign — e.g. one campaign running multiple strategies in parallel: ad set A = prospecting, ad set B = viewed-not-purchased retargeting, ad set C = a different product set or budget. Each catalog ad set independently controls its product set, audience strategy, budget, targeting, and retention window. The catalog is inherited from the parent campaign. Use this AFTER create_meta_catalog_campaign to layer on more ad sets. Adds the ad set + its first catalog ad, PAUSED.
add_negative_keywords_to_list
ChatGPTAdd negative keywords to a SHARED negative keyword list. Adds negatives to a reusable list (SharedSet), so every campaign the list is attached to blocks those searches at once — no need to repeat per campaign. Parameters: - shared_set_id (required — from list_negative_keyword_lists) - keywords (required): each {text, match_type} — match_type EXACT, PHRASE, or BROAD (default BROAD) Use when: "add these negatives to my shared list", "block 'free', 'cheap' across all my campaigns via the list".
add_placement_exclusions
ChatGPTExclude placements — add negative placement criteria so your ads STOP serving on specific websites, YouTube channels/videos, or apps. This is the write side that closes the optimization loop after get_placement_performance finds wasted or off-target placements. What it does: adds NEGATIVE placement criteria at the campaign level (applies to all ad groups) OR a single ad-group level. It is non-destructive — it does NOT pause or delete any campaign, ad group, ad, or existing targeting; it only prevents future serving on the placements you list. (To undo, the negative criterion can be removed later.) Scope — provide exactly ONE: - campaign_id — exclude across the whole campaign (all ad groups) - ad_group_id — exclude only within that ad group Placements — a list of {type, value}: - WEBSITE → value = domain/url (e.g. msn.com) - YOUTUBE_CHANNEL → value = channel id - YOUTUBE_VIDEO → value = video id - MOBILE_APPLICATION → value = app id Typically you take the target_url / display_name of placements that get_placement_performance shows with spend but zero conversions, and pass them here. Returns: which placements were added (with their criterion resource names) and which were skipped (invalid type/empty value), plus counts. Invalid rows are reported, never silently dropped. Parameters: - customer_id: Optional (uses connected account if omitted) - campaign_id OR ad_group_id: exactly one (required) - placements: list of {type, value} (required) Use this tool when: - User wants to exclude wasteful placements found via get_placement_performance - User says "block ads on <site>", "exclude this channel/app", "stop showing on these placements" Tip: Pair with get_placement_performance (zero_conversions_only=true + min_cost) to find the waste, then exclude it here in the same workflow.
add_product_group
ChatGPTSubdivide a Shopping ad group's products by a dimension — set a bid for a partition or exclude it. Splits products by dimension_type=value (e.g. product_brand=Nike, product_type=Shoes with level=LEVEL1, product_item_id=SKU123, product_condition=NEW). Creates a biddable partition (bid_micros) OR an excluded one (exclude=true) — plus the required "everything else" sibling automatically. FIRST call on a serve-all ad group subdivides the root. To split an EXISTING partition further, pass parent_criterion_id (the UNIT to subdivide, from get_product_groups). Required: ad_group_id, dimension_type, value. Optional: level (for type/category), index (for custom_attribute), bid_micros OR exclude, parent_criterion_id.
add_shopping_ad_group
ChatGPTAdd a new ad group to an existing Standard Shopping campaign. Creates a SHOPPING_PRODUCT_ADS ad group plus its product ad(s). Use this to structure a Shopping campaign into multiple ad groups (e.g. one per product category) after it's created — each ad group can then get its own product-partition tree via add_product_group and its own CPC bid. To edit/pause/remove an ad group afterward, use the channel-neutral tools update_ad_group_settings / pause_ad_group / resume_ad_group / remove_ad_group (they work on Shopping ad groups). Required: campaign_id (a Shopping campaign). Optional: name, cpc_bid_micros, num_product_ads.
add_shopping_product_ad
ChatGPTAdd product ad(s) to an existing Shopping ad group. A Shopping product ad is a marker that lets the ad group serve products from the linked Merchant Center feed (it has no creative — the products come from the feed). Most ad groups need only one. Use this if an ad group has no product ad (so it can't serve) or you want extras. To LIST an ad group's ads use get_campaign_structure; to REMOVE one use remove_ad. Required: ad_group_id (a Shopping ad group). Optional: count (default 1).
analyze_meta_catalog_performance
ChatGPTUser wants to analyze how their Advantage+ Catalog / Dynamic Product Ads are performing AT THE PRODUCT or PRODUCT-SET level. Keywords: "which products are selling", "catalog performance", "best/worst products", "product ROAS", "product set performance", "which SKUs are wasting money". Breaks catalog performance down by PRODUCT and PRODUCT SET (the campaign-level perf tools can't do this). Returns: - Top products by catalog-attributed ROAS, and underperforming products (below target) - Products spending with ZERO conversions (the catalog waste signal) and zero-impression products - Per-product-set ROAS comparison + the funnel (views → carts → checkouts → purchases) - Units sold, and actionable recommendations (scale winners, exclude losers, shift budget between sets) Uses the same target-ROAS, severity and data-confidence conventions as the other performance tools. Reads cached nightly product metrics — if none exist yet, says so. When to use: "How are my catalog products doing?", "Which products should I scale or pause?", "What's my ROAS by product set?"
analyze_pmax_search_categories
ChatGPTSee the search CATEGORIES a Performance Max campaign matched (grouped queries), with metrics. ⚠️ READ-ONLY. Safe to call repeatedly. This reads campaign_search_term_insight — Google's aggregated view that groups a Performance Max campaign's queries into search categories (themes), each with its own clicks, impressions, conversions, and conversion value. It complements analyze_pmax_search_terms (individual terms): categories show the shape of demand at a theme level. Google returns a residual "(Other search terms)" bucket for long-tail queries it doesn't categorize. High-volume — this pages (same interface as analyze_pmax_search_terms): - sort_by: impressions (default), clicks, conversions, conversion_value - sort_order: desc (default) or asc - query: free-text filter on the category name - offset / limit: check has_more and re-call with a bigger offset Parameters: - campaign_id (required): the Performance Max campaign ID (from list_campaigns) - lookback_days: 7, 30, 60, 90, or 120 (default 30) - customer_id: required for multi-account users Use when: "what search themes is my PMax campaign showing for?", "break down PMax demand by category", "which search categories convert best in Performance Max".
analyze_pmax_search_terms
ChatGPTSee the actual search terms a Performance Max campaign matched, with per-term metrics. ⚠️ READ-ONLY. Safe to call repeatedly. Performance Max search terms live in a different Google Ads resource (campaign_search_term_view) than Search-campaign terms, so analyze_search_terms returns "No search term data" for a PMax campaign. Use THIS tool for a PMax campaign. What you get, per search term: cost, clicks, impressions, conversions, conversion value, CTR, CPC — the raw numbers the user needs to spot high-cost / zero-conversion queries and converting queries, and decide what to do. High-volume — do NOT page through everything. PMax campaigns can have thousands of search terms. The response ALREADY gives you the answer without paging: - Results are sorted by cost (biggest spender first), so the top page is the highest-spend set — the terms most worth reviewing. - A summary line reports totals over the WHOLE set (term count, total cost, total conversions, and how many terms recorded 0 conversions and the spend on them) — read that instead of enumerating every term. These are facts; whether a 0-conversion term is a problem depends on the account (some are upper-funnel or tracked elsewhere) — surface the number, let the user decide. - To find something specific, filter with `query` or re-rank with `sort_by` — don't walk page after page. Paging is capped (you cannot page past the top ~100). Controls: - sort_by: cost (default), clicks, impressions, conversions, conversion_value, ctr, cpc - sort_order: desc (default) or asc - query: free-text filter on the term (e.g. 'free' to surface low-intent queries) - offset / limit: only if you truly need more of the same ranking; check has_more Parameters: - campaign_id (required): the Performance Max campaign ID (from list_campaigns) - lookback_days: 7, 30, 60, 90, or 120 (default 30) - customer_id: required for multi-account users (from get_connections_status) Use when: "show me the search terms for my PMax campaign", "what queries is Performance Max spending on?", "find wasted spend / irrelevant queries in PMax".
analyze_wasted_spend
ChatGPTAnalyze wasted ad spend and identify campaigns losing money or underperforming. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. 🎯 What This Tool Does (Performance Agent - Phase 1): - Identifies campaigns LOSING money (ROAS < 1.0x) - Identifies campaigns UNDERPERFORMING (1.0x ≤ ROAS < target) - Separates true waste from opportunity cost - Provides severity-based classification (CRITICAL/HIGH/MEDIUM) - Generates actionable recommendations with expected impact - Shows top performing campaigns for budget reallocation Returns detailed analysis: - Total wasted spend (campaigns with ROAS < 1.0) - Total underperforming spend (profitable but below target) - Campaign-by-campaign breakdown with severity levels - Specific recommendations (PAUSE/REDUCE/OPTIMIZE) - Quick actions for immediate implementation - Budget reallocation suggestions Target ROAS Resolution (3-tier priority): 1. Account goals table (user-set or API-pulled) 2. 90-day historical average ROAS 3. Default to 2.0x if no data available Severity Levels: - 🚨 CRITICAL: ROAS < 0.5x (losing money severely) - 🔴 HIGH: ROAS < 1.0x (unprofitable/breakeven) - 🟡 MEDIUM: 1.0x ≤ ROAS < target (profitable but underperforming) Parameters: - lookback_days: 7, 30, 60, 90, or 120 days (default: 30) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - target_roas: Optional override (e.g., 3.0 for 3.0x ROAS) - customer_id: Optional (uses connected account if omitted) Execution time: 1-3 seconds (cached database query) Data source: campaign_daily_metrics table (updated nightly) Use this tool when: - User asks "where is my money going?" - User wants to identify wasted spend - User wants to optimize campaign budgets - User asks which campaigns to pause/reduce - User wants to know which campaigns are losing money
attach_negative_keyword_list_to_campaign
ChatGPTAttach a shared negative keyword list to a campaign. Links an existing negative keyword list (SharedSet) to a campaign so the campaign starts excluding the list's keywords. One list can be attached to many campaigns. Parameters: - shared_set_id (required — from list_negative_keyword_lists) - campaign_id (required — from list_campaigns) Use when: "attach my negatives list to this campaign", "apply the shared negative list to campaign X".
audit_conversion_tracking
ChatGPTReview your conversion tracking setup across ad platforms. Checks Meta Pixel (event volume, CAPI status, dedup, diagnostics), LinkedIn (conversion rules, CAPI, Insight Tag), and Google Ads (conversion actions, enhanced conversions, attribution). Returns a health score (0-100), grade (A-F), detailed findings, and suggestions with self-validation steps for each platform. Note: Some checks rely on API data availability and may not capture all configurations. Where findings are inconclusive, the tool provides guidance on how to verify directly in the platform's dashboard. Parameters: - platform (optional): 'google_ads', 'meta_ads', or 'linkedin_ads'. If omitted, reviews all connected platforms. - lookback_days (optional): 7, 14, 30, 60, or 90 days (default: 30) Execution time: ~5-15 seconds (includes live API calls to ad platforms).
browse_meta_targeting
ChatGPTUser wants to browse all targeting options in a specific category without a search query. This tool retrieves all options in a Meta targeting category for exploration and discovery. Returns: - List of all targeting options in the category - IDs, names, and audience sizes - Useful for discovering targeting options when user doesn't have a specific query When to use this tool: - "Show me all available behaviors for Meta targeting" - "What interest categories are available?" - "Browse demographic targeting options" - "List all life events I can target" - "What income targeting options exist?" Categories Available: - interests: All interest targeting categories - behaviors: All behavior targeting options - demographics: All demographic targeting options - life_events: All life event targeting options - industries: Industry targeting options - income: Income bracket targeting options - family_statuses: Family status targeting options Parameters: - category: Category to browse (required) - limit: Maximum results (1-500, default: 100) - locale: Locale for results (default: en_US) - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds Data source: Meta Marketing API Targeting Search
compare_meta_catalog_product_sets
ChatGPTUser wants to compare their catalog PRODUCT SETS against each other and decide where to put budget. Keywords: "which product set is best", "compare product sets", "where should budget go", "best sellers vs the rest", "product set ROAS". Ranks product sets by catalog-attributed ROAS, sizes a suggested budget shift from the weakest set toward the strongest, and flags OVERLAP — the same product spending across multiple sets (self-competition that fragments budget and inflates costs). Reads cached nightly product metrics (never calls Meta live). When to use: "Which product set performs best?", "Should I move budget between my product sets?"
competitor_ads_research
ChatGPTResearch what a COMPETITOR is actually advertising right now — their live ad creatives, headlines, offers, calls to action, formats, and how long each ad has been running — pulled from public ad-transparency sources and read with vision analysis, then placed SIDE BY SIDE with the user's own connected ad account. Call this when the user asks: - "what ads is <competitor> running", "show me my competitor's ads" - "what are competitors doing", "competitor ad research/analysis/intelligence" - "what messaging/offers/creatives do they use", "what's working for them" - "how do my ads compare to <competitor>", "am I bidding on their brand" - anything about competitor creative, competitor copy, or competitive ad strategy Inputs: competitor_domains (REQUIRED — a list of competitor WEBSITE DOMAINS like ['semrush.com','ahrefs.com']). ⛔ It must be a DOMAIN, not a brand name: a bare brand returns zero results. If the user names a company without giving a website, ASK for the domain — do NOT guess it and do NOT auto-discover competitors. region (optional ISO country like 'US','IN','GB' — defaults to the user's own account market; note TikTok and LinkedIn ads are worldwide and cannot be filtered by market). sources (optional list — which ad platforms to pull: ['google'] (default, Google Search/Display/YouTube ads), add 'meta' for their Facebook/Instagram ads, 'tiktok' for their TikTok ads, and/or 'linkedin' for their LinkedIn ads — e.g. ['google','meta','tiktok','linkedin']. Add 'meta' when the user asks about Facebook/Instagram/Meta ads, 'tiktok' when they ask about TikTok ads, and 'linkedin' when they ask about LinkedIn/B2B ads or want a fuller picture). max_creatives (optional cap). What it returns: an interactive gallery of their real creatives with run-durations, plus the user's own ads and any competitor brand terms they already pay for. ⛔ It does NOT return competitor spend, ROAS, conversions, CPC or impressions — no source publishes those, so the tool never estimates them. Do not ask it for, or infer, how a competitor's ads PERFORM; a long run-duration is a duration, not proof it works. ⚠️ Plus, Pro & Max (not Free). Renders an interactive widget; the text fallback carries the same findings.
create_app_campaign
ChatGPTCreate a Google App campaign (Universal App Campaign / UAC) to drive app installs, in-app engagement, or Play pre-registrations. ⚠️ Creates a REAL campaign (starts PAUSED — resume_campaign when ready). Call ONCE; do NOT auto-retry. PREREQUISITE: a real, published app listing. Pass its store id as app_id (Play package name for GOOGLE_APP_STORE, e.g. com.company.app; numeric App Store id for APPLE_APP_STORE, e.g. 1234567890) and the matching app_store. Google validates the app_id against the store — a made-up id is rejected. WHAT THIS BUILDS: budget + MULTI_CHANNEL/App campaign (with the app + bidding goal) + one auto-managed ad group + one app ad. App campaigns are largely automated — Google assembles ads from your store listing plus the assets you provide. TYPES (app_campaign_type): install (default) | engagement (re-engagement — needs a deep-link + audience) | pre_registration (Google Play only). Install is the common case. Required: campaign_name, budget_daily, app_id, app_store. Bidding: bidding_strategy (leave UNSET to auto-pick the strategy that matches the goal | TARGET_CPA | MAXIMIZE_CONVERSIONS | TARGET_ROAS) + target_cpa_micros / target_roas + optional bidding_goal_type. Creative (`ad`): headlines (≤30), descriptions (≤90), image_assets / video_assets (resource names of EXISTING assets). start_date/end_date (YYYYMMDD).
create_conversion_action
ChatGPTCreate a WEBPAGE conversion action so the account can use TARGET_CPA / MAXIMIZE_CONVERSIONS / TARGET_ROAS bidding. Why this matters: Without conversion actions, Smart Bidding strategies (TARGET_CPA, MAXIMIZE_CONVERSIONS, TARGET_ROAS) can't function correctly. They need a "what counts as a conversion" definition to optimize toward. This tool creates that definition. v1 scope: WEBPAGE conversion actions only. After creating, the customer must: 1. Install the Google site tag (gtag.js) on their website if not already present 2. Add an event snippet on the conversion page (or fire it on a click/form submit) 3. Wait 24-48 hours for the first conversions to flow in 4. THEN apply TARGET_CPA bidding (it needs a few conversions to optimize) Phone-call / app / Firebase / Floodlight conversion types are deferred to a future tool. Pick the right category: - E-commerce purchase → PURCHASE (set value + currency) - Lead-gen form submit → SUBMIT_LEAD_FORM (set value if leads have known $ worth) - Newsletter signup / account creation → SIGNUP - Add-to-cart tracking → ADD_TO_CART - Begin-checkout (abandonment funnel) → BEGIN_CHECKOUT - Phone-call lead from ad → PHONE_CALL_LEAD - Outbound click on partner site → OUTBOUND_CLICK - Engagement metric (page time, scroll, video play) → ENGAGEMENT - "Get directions" tap on a map ad → GET_DIRECTIONS - Quote request → REQUEST_QUOTE - Appointment booked → BOOK_APPOINTMENT - Generic contact form → CONTACT - Use DEFAULT only if none fit. Counting type: - ONE_PER_CLICK (default): one conversion per ad click. Use for lead-gen, signups, downloads. - MANY_PER_CLICK: every purchase counts, even multiple from same click. Use for e-commerce. Value settings: - Recommended for lead-gen: set value to your average lead $ worth (e.g. 50.0 for $50/lead). This gives TARGET_CPA something to optimize. - Set always_use_default_value=true if every conversion has the same value (lead-gen). - Leave both unset for e-commerce — the tag sends actual transaction values. Example: User: "Set up TARGET_CPA bidding for my lead-gen campaign" Agent: 1. Calls create_conversion_action(name="Lead Form Submit", category="SUBMIT_LEAD_FORM", value=50.0, always_use_default_value=true) 2. Tells user: "Created the conversion goal. Now install the Google tag on your thank-you page, then I'll switch the campaign to TARGET_CPA." 3. After tag is installed and conversions are flowing, calls update_bid_strategy(strategy="TARGET_CPA", target_cpa=20.0).
create_demandgen_campaign
ChatGPT🔄 LONG-RUNNING TOOL: Creates a Demand Gen campaign across ALL Google channels — YouTube, Discover, Gmail, Display, and Maps. Emits MCP progress updates during creation (typically 10-20 seconds). ⚠️ CRITICAL WARNING ⚠️ - Call this tool ONLY ONCE per campaign - Creates REAL campaigns that cost REAL money - Do NOT retry automatically if errors occur - Report errors to user instead of retrying 🌐 Demand Gen Campaign Channels (ALL enabled by default): ✅ YouTube In-Feed (search results & related videos) ✅ YouTube In-Stream (before/during/after videos) ✅ YouTube Shorts (Shorts feed) ✅ Gmail (Promotions & Social tabs) ✅ Discover (Google Discover feed) ✅ Display (Google Display Network) ❌ Maps (opt-in, disabled by default) 📋 YOUR CRITICAL ROLE: Campaign Strategist & Text Creator STEP 1: Collect Campaign Details from User YOU MUST collect these from the user: 1. Campaign Name - Descriptive and unique 2. Daily Budget - In account's native currency (recommended $20+/day) 3. Ad Format - multi_asset (images) or video_responsive (videos) 4. Final URL - Landing page 5. Business Name - Max 25 characters STEP 2: Discover Existing Assets 🔴 MANDATORY: Call discover_existing_assets to find existing logos/images. - If logos found → use logo_asset_id or existing_images.logos_square - If NO logos → ask user for logo URL, run validate_and_prepare_assets STEP 3: Generate Ad Copy - Headlines (1-5): STRICT 40 character max each - Descriptions (1-5): STRICT 90 character max each - Long Headlines (optional, for video_responsive): 90 char max each STEP 4: Prepare Images/Videos For multi_asset: Need landscape (1.91:1) OR square (1:1) marketing images + logo For video_responsive: Need YouTube video IDs (validate first) + logo STEP 5: Call create_demandgen_campaign with complete payload Bidding Options (your choice is honored — engine is advisory only): - MAXIMIZE_CLICKS: Default, works without conversion tracking - MAXIMIZE_CONVERSIONS: Requires conversion tracking - TARGET_CPA: Requires target_cpa value - MAXIMIZE_CONVERSION_VALUE: Requires conversion tracking - TARGET_ROAS: Requires target_roas value Channel Controls (optional): Pass channels dict to disable specific channels: {"gmail": false, "display": false} → YouTube + Discover only STEP 6: MANDATORY — Add Extensions After Creation After success, add sitelinks, callouts, and structured snippets. Execution Time: 10-20 seconds CRITICAL REMINDERS: - Campaign starts PAUSED for user safety - This costs real money — be transparent - Never retry on failure — report error to user
create_display_campaign
ChatGPTCreate a Google Display campaign with a Responsive Display Ad on the Google Display Network (GDN). 🛑 STOP — IMAGES ARE MANDATORY. ASK THE USER FIRST. 🛑 A Display campaign cannot be created without images. Before calling this tool you MUST have: - At least 1 landscape image URL (1.91:1 aspect ratio, min 600×314, max 5 MB) - At least 1 square image URL (1:1 aspect ratio, min 300×300, max 5 MB) If the user has not provided image URLs, ASK THEM — do not invent URLs, do not guess Wikipedia/stock-photo URLs (they 403 to server fetches), do not pass marketing_images: null. Suggest the user upload to a host like postimages.org and paste the direct .jpg/.png URLs. ✅ STRONGLY RECOMMENDED — pre-validate first: call validate_and_prepare_assets with the user's image URLs BEFORE calling this tool. It checks aspect ratio, dimensions, file size, and content-type, then returns an asset_bundle_id you can pass here. This avoids a Google Ads API rejection mid-create (e.g., "aspect ratio doesn't match expected"). When to use this tool: - User explicitly asks for "Display campaign", "Google Display Network", "GDN", "banner ads", or "display ads" - User wants visual/banner placements across millions of websites, mobile apps, YouTube, and Gmail (display slots only) - User wants Smart Display (Google-managed automation): pass smart_display=true and bidding_strategy='TARGET_CPA' When NOT to use: - User wants text ads in Google Search → use create_search_campaign - User wants cross-channel (YouTube + Discover + Gmail + Display together) → use create_demandgen_campaign - User wants a PMax-like multi-channel approach → use create_pmax_campaign Step-by-step workflow: 1. Ask user for: budget, landing URL, business name, AT LEAST 1 LANDSCAPE + 1 SQUARE IMAGE URL, headlines (1-5 @ 30 chars), long headline (1 @ 90 chars), descriptions (1-5 @ 90 chars) 2. Resolve any free-text locations via resolve_google_locations first (returns exact geoTargetConstants/<id> to avoid ambiguity) 3. Pre-validate the image URLs with validate_and_prepare_assets → use the returned asset_bundle_id (recommended) OR pass the URLs directly as marketing_images / square_marketing_images (we'll validate before upload, but the API may still reject for subtle aspect-ratio mismatches) 4. Optional: logos, YouTube videos, audience/topic/placement targeting 5. Call create_display_campaign with the full payload (must include images one way or another) 6. After success, add extensions: add_sitelinks, add_callout_extensions, add_structured_snippets Targeting surfaces supported (ad-group level, ignored for Smart Display): - audience_segments: user_interests (affinity/in-market via search_audiences), custom_audiences, user_lists, combined_audiences - topics: topic constants - managed_placements: specific websites/apps/YouTube channels/videos - display_keywords: contextual keywords (always BROAD match on Display) - demographics: age/gender/parental/income (exclude-the-inverse pattern) Bidding strategies: - MAXIMIZE_CLICKS (default, works without conversion tracking) - MAXIMIZE_CONVERSIONS (needs conversion tracking) - TARGET_CPA (needs target_cpa + conversion tracking) - TARGET_ROAS (needs target_roas + conversion tracking) - MANUAL_CPC (enhanced CPC, needs cpc_bid in account currency) - MANUAL_CPM (viewable CPM, needs cpm_bid in account currency) Smart Display (smart_display=true): - sub_type=DISPLAY_SMART_CAMPAIGN (Google-managed) - Bidding MUST be TARGET_CPA - Manual audience/topic/placement/keyword/demographic inputs are REJECTED - Account needs conversion tracking with enough history (≥50 Display conversions or ≥100 Search conversions in last 30 days) Character limits (strictly enforced — validation will reject before hitting the API): - Headlines: MAX 30 chars each (1-5) - Long headline: MAX 90 chars (exactly 1) - Descriptions: MAX 90 chars each (1-5) - Business name: MAX 25 chars - Price prefix: MAX 10 chars - Promo text: MAX 20 chars Image requirements: - Landscape (1.91:1): min 600x314, max 5MB, 1-15 images…
create_label
ChatGPTCreate an account label — a reusable tag for organizing campaigns (e.g. 'Q3 Promo', 'Brand'). After creating, use add_campaign_label to attach it to a campaign. Check list_labels first to avoid duplicates. Required: name. Optional: description, background_color (hex like '#FF5733').
create_meta_catalog_campaign
ChatGPTUser wants to create an Advantage+ Catalog ad / Dynamic Product Ad (DPA) — ads that automatically show products from their Meta product catalog. Keywords: "catalog ad", "dynamic product ads", "DPA", "advantage+ catalog", "shopping ads", "retarget products", "show my products". Meta renders each product's image, name and price from the catalog at delivery — the user does NOT upload images. Always OUTCOME_SALES. Two audience strategies: - prospecting — broad audience to find new buyers (no pixel needed) - retargeting — show products to people who engaged via the Pixel (REQUIRES pixel_id). Presets: viewed_not_purchased, carted_not_purchased, all_engaged_not_purchased, cross_sell_purchasers, or custom. REQUIRED FIRST: run validate_catalog_readiness (confirms the catalog has products with images and whether retargeting is viable), and resolve catalog_id + product_set_id via list_meta_catalogs / list_meta_product_sets. For retargeting, get pixel_id from list_meta_pixels. The campaign is created PAUSED so the user can review it in Ads Manager before spending.
create_meta_dco_ad
ChatGPTUser wants Meta to automatically TEST MULTIPLE IMAGES and find the best combination. This is Dynamic Creative Optimization (DCO). Meta tests all combinations of images × headlines × primary texts and optimizes delivery automatically. USE THIS TOOL when the user says ANY of these: - "test these images" / "test multiple images" - "let Meta find the winner" / "let Meta optimize" - "Dynamic Creative" / "DCO" - "which image performs best" - Provides multiple images and wants Meta to choose the best - "test combinations" / "mix and match" - "10 images × 5 headlines" DO NOT USE add_meta_ad multiple times for this — that creates separate ads (A/B test). DCO is ONE ad with multiple assets that Meta mixes and optimizes. Prerequisites: 1. You need an ad_set_id with is_dynamic_creative=true 2. If the user doesn't have one, first call add_meta_ad_set with is_dynamic_creative=true 3. Then call this tool with the image_urls and text variations Asset limits (from Meta): - Images: 2-10 (required) - Headlines: up to 5 (optional) - Primary texts: up to 5 (optional) - Descriptions: up to 5 (optional) - Total assets: max 30 DCO ad sets support only 1 ad — do NOT add more ads to a DCO ad set. Example: 5 images × 3 headlines × 2 primary texts = 30 combinations, Meta finds the winner.
create_meta_product_set
ChatGPTUser wants to advertise a SUBSET of their catalog — "boost just these items / these SKUs", "promote my sale items", "make a set of my new arrivals". Creates a product SET (a filtered grouping of EXISTING catalog products) — it does NOT create or upload products (those come from Shopify / Commerce Manager). Provide either: - retailer_ids: a list of SKUs to include (simplest — "boost just these items"), or - filter: an advanced raw Meta product-set filter When to use: - "Boost these 3 products", "create a set of my sale items" - Before a catalog ad when the user wants a specific subset, not the whole catalog
create_negative_keyword_list
ChatGPTCreate a new (empty) shared negative keyword list. Creates a reusable negative keyword list (SharedSet) you can then fill with add_negative_keywords_to_list and attach to campaigns with attach_negative_keyword_list_to_campaign. Parameters: name (required). Use when: "create a negative keyword list called ...", "make a shared negatives list".
create_pmax_campaign
ChatGPT🔄 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 performanc…
create_search_campaign
ChatGPT🔄 LONG-RUNNING TOOL: Creates a Google Ads Search campaign with full structure. Emits MCP progress updates during authentication and campaign creation (typically 5-10 seconds). Progress stages: validate → commit. ⚠️ CRITICAL WARNING ⚠️ - Call this tool ONLY ONCE per campaign - Creates REAL campaigns that cost REAL money - Do NOT retry automatically if errors occur - Report errors to user instead of retrying ⚠️ 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 ROLE: Expert Google Ads Campaign Strategist BEFORE calling this tool, YOU MUST: 1. Research the business thoroughly: - Understand products/services, target audience, value propositions - Analyze competitive landscape and market positioning - Review website messaging and offers - Consider seasonal factors and current trends 2. 🔍 KEYWORD RESEARCH (CRITICAL - Call research_keywords tool FIRST): Do NOT use generic SEO keywords. Get HIGH-INTENT keywords with real CPC data! YOU MUST call the research_keywords tool BEFORE this tool: Steps: a) Call the research_keywords tool: `` Tool: research_keywords Arguments: { "business_description": "Emergency plumbing services for homeowners", "website_url": "https://example.com", "target_location": "New York, NY" } `` b) The tool will return: - Keyword table with dynamic CPC thresholds (adapts to industry) - HIGH/MEDIUM/LOW intent keywords - Budget recommendations (Conservative/Moderate/Aggressive) - Top 15-20 recommended keywords c) Show the keyword table to the user d) Ask user if they want to modify keyword selection: - Can add/remove specific keywords - Can use only HIGH intent keywords - Default: use recommended keywords e) Extract keyword texts from the research_keywords result - Use the recommended keywords for this tool's 'keywords' parameter - Max 15-20 keywords per ad group - Will use BROAD match automatically (Google's 2025 recommendation) 3. Analyze Target Demographics: For each ad group, consider who the ideal customer is: - Age: What age groups are most likely to buy? (e.g., luxury products → 35-54, gaming → 18-34) - Gender: Is the product/service gender-specific? (e.g., women's fashion → FEMALE) - Income: What income level can afford this? (e.g., luxury → TOP_10/80_90, budget → 0_50/50_60) Examples: - Luxury watches: Males 35-54, income top 20% - Budget fashion: Females 18-34, all income levels - Senior services: Age 65+, income 50%+ - Gaming products: 18-34, all genders, middle income If unclear, leave demographics empty for broad reach. 3. Generate complete campaign structure with ALL details: Required Fields (all mandatory): 1. campaign_name - Unique descriptive name 2. business_description - What the business sells 3. website_url - Landing page URL 4. budget_daily - Daily budget in the account's native currency (do NOT convert — pass user's amount as-is) 5. target_locations - Geographic targets (cities/states/countries) 6. ad_groups - Array of 2-4 ad groups, each containing: - name: Ad group theme (e.g., "Premium Care Services") - keywords: 15-20 keywords from Keyword Planner research (will use BROAD match - Google's 2025 recommendation) - headlines: Exactly 15 headlines (MAXIMUM 30 chars each - NO EXCEPTIONS) - descriptions: Exactly 4 descriptions (MAXIMUM 80 chars each - NO EXCEPTIONS) - final_url: Landing page for this ad group - sitelinks (optional): 2-4 additional links below ad - audiences (optional): Demographics and audience targeting - demographics: {age_ranges: [...], genders: [...], income_ranges: [...]} - custom_audiences: [...], in_market_audiences: [...], affinity_audiences: [...] 7. negative_keywords (optional) - Terms to exclude 🚨 CRITICAL CHARACTER LIMITS - COUNT BEFORE CALLING 🚨 - Headlines: MAXIMUM 30 characters (NO EXCEPTIONS - will be rejected!) - Descriptions: M…
create_shopping_campaign
ChatGPTCreate a full Standard Shopping campaign advertising the products in a linked Merchant Center feed. ⚠️ Creates a REAL campaign (starts PAUSED — resume_campaign when ready). Call ONCE; do NOT auto-retry. PREREQUISITE: a Merchant Center account must be linked. Check get_merchant_center_links; if none, link one with link_merchant_center first. Pass that MC id as merchant_id. WHAT THIS BUILDS: budget + SHOPPING campaign (bound to the MC feed) + one or MORE ad groups, each with one or more product ads. Supports the full bidding + settings surface. The campaign serves ALL products in the feed until you subdivide with add_product_group (the listing-group tree). MULTIPLE AD GROUPS: pass ad_groups: [{name, cpc_bid_micros, num_product_ads}, ...] to build several at once (e.g. one ad group per product category). Omit it to create a single ad group from ad_group_name/cpc_bid_micros. Required: campaign_name, budget_daily, merchant_id. Bidding: bidding_strategy (MANUAL_CPC default | TARGET_SPEND=MaxClicks | TARGET_ROAS | MAXIMIZE_CONVERSION_VALUE | MAXIMIZE_CONVERSIONS | TARGET_CPA) + target_roas / target_cpa_micros / cpc_bid_ceiling_micros / cpc_bid_floor_micros / enhanced_cpc as applicable. Settings: campaign_priority (0-2), enable_local, disable_product_feed, network_settings, feed_label (omit unless the MC account uses feed labels — a wrong value serves zero products), start_date/end_date (YYYYMMDD).
create_youtube_campaign
ChatGPT🔄 LONG-RUNNING TOOL: Creates a YouTube Video campaign using Google Ads Demand Gen format with YouTube-only placements. Emits MCP progress updates during authentication and campaign creation (typically 10-20 seconds). Progress stages: validate → commit. ⚠️ CRITICAL WARNING ⚠️ - Call this tool ONLY ONCE per campaign - Creates REAL campaigns that cost REAL money - Do NOT retry automatically if errors occur - Report errors to user instead of retrying ⚠️ CRITICAL PREREQUISITE: - MUST validate the YouTube video first using validate_video tool - Video must be public or unlisted on YouTube (NOT private) 🎬 YouTube Campaign Placements: ✅ YouTube In-Feed (appears in search results & related videos) ✅ YouTube In-Stream (plays before/during/after videos) ✅ YouTube Shorts (appears in Shorts feed) ❌ Gmail (disabled for YouTube campaigns) ❌ Discover (disabled for YouTube campaigns) ❌ Display (disabled for YouTube campaigns) 📋 YOUR CRITICAL ROLE: Campaign Strategist & Text Creator STEP 1: Validate Video First Before calling this tool: 1. Get user's YouTube video URL or ID 2. Call validate_video tool with platform="pmax" to verify it 3. Confirm video is accessible (public or unlisted) 🔴 STEP 1.5: MANDATORY — Discover Existing Assets BEFORE proceeding, you MUST call discover_existing_assets to check for existing image/logo assets: 1. Call: discover_existing_assets(asset_types=["image", "logo"], target_domain="<user's domain>") 2. Present findings to the user: - Show all available logos and images with dimensions - Show count of assets found per type 3. Ask the user: "I found [N] existing assets in your account. Would you like to: A) Reuse an existing logo (saves time, consistent branding) B) Upload a new logo image C) Upload a new logo from URL" 4. Based on answer: - Reuse → Use logo_asset_id from discovered assets - Upload new → Use validate_and_prepare_assets with logos_square → asset_bundle_id 5. 🚫 NEVER skip this step — even if the user didn't mention assets STEP 2: Collect Campaign Details from User YOU MUST collect these from the user (ask if not provided): REQUIRED Fields: 1. Campaign Name - Descriptive and unique 2. Daily Budget - Minimum $15/day (recommended $50+) 3. YouTube Video ID - 11-character video ID (validated in Step 1) 4. Final URL - Landing page (must match verified domain) 5. Business Name - Max 25 characters STEP 3: Generate High-Quality Ad Copy 🚨 BEFORE GENERATING TEXT - READ CHARACTER LIMITS 🚨 Headlines (1-5 required): - STRICT LIMIT: 40 characters maximum per headline - Count characters BEFORE calling this tool! - Examples: - "Shop Premium Watches Today" (26 chars) ✅ - "Free Worldwide Shipping Now" (27 chars) ✅ Descriptions (1-5 required): - STRICT LIMIT: 90 characters maximum per description - Count characters BEFORE calling this tool! - Examples: - "Shop authentic luxury timepieces with expert curation and free worldwide shipping." (82 chars) ✅ Long Headlines (optional, 1-5): - STRICT LIMIT: 90 characters maximum per long headline - Falls back to regular headlines if not provided ⚠️ WILL BE REJECTED IF YOU EXCEED LIMITS - NO RETRIES! LOGO (REQUIRED - one of two options): - Option A (existing logo): logo_asset_id from discover_existing_assets — use this if the account already has logo images - Option B (new upload): asset_bundle_id from validate_and_prepare_assets — use this if the account has NO existing logos (e.g., Search-only accounts) Workflow: 1. First try discover_existing_assets to find existing logos 2. If logos found → use logo_asset_id 3. If NO logos found → ask user for a logo image URL, run validate_and_prepare_assets with logos_square, then use the returned asset_bundle_id OPTIONAL Fields (use defaults if not provided): - call_to_action: Default "LEARN_MORE". Options: SHOP_NOW, SIGN_UP, SUBSCRIBE, DOWNLOAD, BOOK_NOW, CONTACT_US, GET_QUOTE, APPLY_NOW, WATCH_NOW, ORDER_NOW, BUY_NOW, SEE_MORE, START_NOW, VISIT_SITE, REGISTER - target_locations: Defaults to ["United States"] - target_languages: Defa…
detect_meta_catalog_waste
ChatGPTUser wants to find and recover WASTED catalog spend at the PRODUCT level. Keywords: "which products waste money", "recover spend", "stop wasting budget", "SKUs that don't convert", "products below break-even". Detects recoverable spend: SKUs spending with ZERO conversions + SKUs converting BELOW break-even (1.0x ROAS). Returns the account recoverable-spend total and a prioritized, severity-ranked SKU action list. Carries the same guards as the campaign-level wasted-spend tool: never "pause" a SKU that still converts (says reduce/tighten instead), respects minimum spend, and softens copy when conversion tracking looks incomplete. Reads cached nightly product metrics (never calls Meta live). When to use: "Which products are wasting my budget?", "How much catalog spend can I recover?"
diagnose_funnel
ChatGPTDIAGNOSE why a user's ads aren't producing sales/leads — the ordered root-cause check that tells them WHICH part of their funnel is broken and what to do about it. Call this when the user asks: - "why aren't my ads selling / working / converting?", "I'm not getting any sales", "my ads aren't performing", "what's wrong with my account?", "what would you do to increase sales?", "I'm losing money on ads" - any open-ended "something is wrong and I don't know what" question How it differs from the performance tools: those DESCRIBE the numbers for one platform. This walks the whole chain in ORDER — is conversion tracking real → should there even be revenue → is there traffic → is it converting → (we can't see the landing page) → where is the money going — and STOPS at the first broken step, reporting the rest as 'not assessed' rather than 'fine'. That ordering is the point: a broken pixel makes every number below it meaningless, and advice about bids or budgets would be guesswork until it's fixed. Inputs (all optional): platform and account_id to narrow to one account; lookback_days (14-90, default 60). With no arguments it checks every connected account and leads with the worst one — call it bare. ⛔ It ABSTAINS honestly: if the account has too little data, or the numbers can't be verified, it says so and says what would unlock an answer, rather than guessing. It never invents benchmarks or promises outcomes. If the funnel is healthy and the user wants budget advice, follow up with generate_media_plan. Renders an interactive widget; the text carries the same diagnosis.
diagnose_meta_catalog_funnel
ChatGPTUser wants to know WHERE in the catalog shopping funnel they're losing shoppers. Keywords: "funnel", "drop-off", "people add to cart but don't buy", "abandoned carts", "why aren't products converting", "checkout drop". Reports the catalog funnel (product view → add to cart → checkout → purchase) per product and account-wide, from cached nightly metrics. For each product and the account it computes the stage-to-stage drop-off RATES and states, as a MEASURED FACT, the stage with the largest drop (e.g. "82% of carts didn't reach checkout"). It does NOT label a drop "severe" or assert a diagnosed cause — it offers COMMON REASONS to check at that stage (creative/feed at view→cart; price/shipping at cart→checkout; payment/checkout friction or pixel firing at checkout→purchase) as guidance, not a verdict. Reads cached nightly product metrics (never calls Meta live). When to use: "Where are shoppers dropping off in my catalog funnel?", "Why am I getting carts but fewer sales?"
discover_existing_assets
ChatGPT🔍 Discover existing assets in the Google Ads account (images, sitelinks, callouts, structured snippets). Phase 0: Asset Discovery - Read-only tool, safe to call anytime. 🔴 MANDATORY WORKFLOW - ALWAYS DO THIS FIRST: BEFORE creating ANY Performance Max campaign, you MUST: 1. Call this tool: discover_existing_assets(target_domain="<user's domain>") 2. Show the user what was found (images, sitelinks) 3. Ask: "Would you like to reuse these assets or upload new ones?" 4. 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 create PMAX without discovering assets first (unless user explicitly says "skip discovery, upload new") What This Tool Does: - Queries Google Ads Asset Library for existing validated assets - Returns campaign-validated assets FIRST, then the rest of the asset library - Includes downloadable image URLs (full-size, from Google's CDN) 📄 Paginated: results come in pages of 50 per asset type. The response footer states whether more pages exist; if it does, call again with page=2 (then 3, …) until it reports all assets have been returned. The full inventory is the pages combined, so page 1 alone is not the complete list. 2-Tier Smart Discovery: Tier 1: Campaign-Validated Assets (High Confidence) ✅ - Assets currently attached to ENABLED, PAUSED, or REMOVED campaigns - These have been validated by Google and won't fail - Includes domain filtering for sitelinks - Best option for reuse Tier 2: No Validated Assets (Ask User) ⚠️ - Account has no suitable assets in campaigns - Recommends uploading fresh assets or website research - Safer than using orphaned assets from library Parameters: - target_domain: Optional domain to filter sitelinks (e.g., "rooterhero.com") - CRITICAL for multi-domain accounts! Google rejects wrong-domain sitelinks - Extract the base domain from campaign URL (just the domain part) - Examples: "https://www.rooterhero.com/services" → "rooterhero.com", "sahaayak.life" → "sahaayak.life" - Only sitelinks matching this domain will be returned - Prevents Google API errors for domain mismatches Returns: - images: List of validated images (landscape, square, portrait, logos) - sitelinks: List of validated sitelinks (filtered by domain if provided) - callouts: List of validated callouts - structured_snippets: List of validated structured snippets - recommendation: Smart guidance on whether to reuse or upload new Example ChatGPT Flow: User: "Create a campaign for rooterhero.com" (or "https://www.rooterhero.com/services") Step 1: Extract base domain → "rooterhero.com" Step 2: Call discover_existing_assets(target_domain="rooterhero.com") If Tier 1 (validated assets found): ChatGPT: "I found 8 sitelinks and 11 images from your previous Rooter Hero campaigns. These were validated by Google. Would you like to reuse them, or upload fresh assets?" User: "Reuse them" → Use those assets in Phase 1 User: "Upload new" → Follow current upload flow If Tier 2 (no validated assets): ChatGPT: "No validated assets found for rooterhero.com in your campaigns. Options: 1. Upload fresh images/sitelinks 2. Let me research rooterhero.com and suggest sitelinks 3. Create campaign without extensions" When to Call: - BEFORE creating Search campaigns (to discover sitelinks, callouts, snippets) - BEFORE creating PMAX campaigns (to discover images) - When user asks "What assets do I have?" - When user wants to reuse existing assets When NOT to Call: - User explicitly says "I'll upload new images" - User wants to create minimal campaign without extensions Execution Time: 1-3 seconds (read-only query) Authentication: Required (MCP OAuth 2.1) Note: This is Phase 0 - discovery only. Phase 1 will enable reusing discovered assets in campaigns.
duplicate_meta_campaign
ChatGPTUser wants to duplicate/copy an existing Meta campaign with all its ad sets, ads, and settings. IMPORTANT: This creates a NEW real campaign in Meta Ads. The duplicate starts in PAUSED status by default for review. This tool copies the entire campaign structure including: - Campaign settings (objective, budget strategy) - All ad sets (targeting, budgets, schedules, promoted_object) - All ads (creatives, text, CTAs, app_link_spec deep links) App Campaigns (OUTCOME_APP_PROMOTION) — preserved on duplicate: - ad-set promoted_object (application_id + object_store_url + custom_event_type) - creative app_link_spec (deep_link_url_ios / deep_link_url_android) - creative asset_feed_spec.link_urls.ios_url / android_url (DCO ads) After duplicating an app campaign, run get_meta_campaign_details on the new campaign ID to verify the 'App Campaign:' section shows the same app_id, store URL, and event type as the original. Returns: - Original and new campaign IDs - New campaign status - Ads Manager URL for the new campaign - Next steps for review and activation When to use this tool: - "Duplicate my campaign" - "Copy campaign [ID]" - "Create a copy of this campaign" - "I want to A/B test with a copy of my campaign" - "Clone my campaign with different targeting" Parameters: - campaign_id: The Meta Campaign ID to duplicate (required) - new_name: Name for the new campaign (optional, defaults to original + " - Copy") - status: Status for new campaign — 'PAUSED' (default, recommended) or 'ACTIVE' Execution time: 10-30 seconds (depends on campaign size) Creates: New real campaign in Meta Ads Common use cases: 1. A/B Testing: Duplicate, then modify targeting or creative on the copy 2. Seasonal variants: Copy a proven campaign, update copy and dates 3. New market expansion: Duplicate, change location targeting 4. Budget testing: Copy, change budget levels Workflow: 1. Use list_meta_campaigns to find the campaign ID 2. Use duplicate_meta_campaign to create the copy 3. Use update_meta_campaign or update_meta_ad_set to modify the copy 4. Use resume_meta_campaign when ready to launch
echo_test
ChatGPTEcho back the input message. Used for testing MCP connectivity and session management.
explain_performance_anomaly
ChatGPTExplain why a performance metric changed using statistical analysis and historical context. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. Uses statistical analysis only (no ML models). 🎯 What This Tool Does (Performance Agent - Phase 1 Feature 4): - Explains why metrics changed (ROAS, CTR, CPC, conversions, conversion rate) - Compares current period to historical averages (30/60/90-day) - Identifies contributing factors with severity levels - Detects campaign changes (paused, new, budget changes) - Finds similar historical periods (seasonality detection) - Provides actionable recommendations to address issues Returns comprehensive anomaly explanation: - Current metric value vs historical averages - Deviation percentages (how much it changed) - Contributing factors: - CPC changes (>15% = auction competition shifts) - Conversion rate changes (>10% = landing page/seasonality issues) - Campaign changes (paused high-performers, new campaigns, budget changes) - Day-of-week patterns (weekend vs weekday effects) - Similar historical periods for context - Assessment (normal variation vs requires action) - Specific recommendations to fix the issue 🔍 How Anomaly Detection Works: Historical Comparison: - Compares current period to 30/60/90-day averages - ±15% deviation considered "normal variation" - >15% deviation flagged as requiring attention Contributing Factor Detection: 1. CPC Changes (>15% threshold) - Increased CPC = auction competition increased - Decreased CPC = auction competition decreased or bid adjustments 2. Conversion Rate Changes (>10% threshold) - Decreased = landing page issues, seasonality, audience quality - Increased = landing page improved, better targeting 3. Campaign Changes: - Paused high-performers (ROAS > 3.0x) = lost revenue driver - New campaigns (>$1K spend) = learning phase affecting overall performance - Budget changes (>20%) = delivery and auction participation affected 4. Day-of-Week Patterns: - Weekend-heavy periods often show different performance - Normal for B2C (higher weekend conversion) - Normal for B2B (lower weekend conversion) 5. Seasonality Detection: - Finds similar historical periods (±10% metric value) - Helps identify if drop is seasonal vs real issue Parameters: - metric: 'roas', 'ctr', 'cpc', 'conversions', 'conversion_rate' (REQUIRED) - period_start: Start date in YYYY-MM-DD format (REQUIRED) - period_end: End date in YYYY-MM-DD format (REQUIRED, max 30 days period) - customer_id: Optional (uses connected account if omitted) Execution time: 2-4 seconds (statistical analysis + database queries) Data source: campaign_daily_metrics table (updated nightly, 120-day retention) Analysis method: Statistical comparison (no ML models) Trigger: Reactive (user asks "why?"), not proactive alerts Use this tool when: - User asks "why did my ROAS drop?" - User asks "why did my CTR increase?" - User notices unexpected metric changes - User wants to understand performance fluctuations - After seeing performance changes in dashboards
get_ad_creative
ChatGPTRead/export the creative composition of existing ads — videos, images (downloadable URLs), and all text. This tool retrieves READ-ONLY data via 2 live GAQL queries (cached 15 min in Redis). Safe to call multiple times. Why this tool: get_campaign_structure shows ads but not what they're made of. This tool returns the full creative payload of any existing ad so you can audit, archive, or rebuild winners into other formats. Returns per ad: - Identity: ad_id, ad_name, ad_type, status, ad_strength, ad group + campaign context - Videos: YouTube video_id + watch_url + thumbnail_url + title per video asset - Images: direct downloadable url (Google CDN) + width/height + mime_type + role (marketing / square_marketing / portrait_marketing / logo / square_logo) - Text: headlines[], long_headlines[], descriptions[], business_name, call_to_actions[] - Carousel ads: per-card headline + CTA + card images (resolved to URLs) - final_urls, display_url; RSA path1/path2; RDA colors Supported ad types (v1): DEMAND_GEN_VIDEO_RESPONSIVE_AD, DEMAND_GEN_MULTI_ASSET_AD, DEMAND_GEN_CAROUSEL_AD, RESPONSIVE_SEARCH_AD, RESPONSIVE_DISPLAY_AD. PMax creative lives in asset groups (no per-ad rows) — not covered; use list_pmax_asset_group_images. Known API limits (not bugs): video files are NOT downloadable via the Google Ads API (YouTube watch URL is the canonical reference); per-video orientation (landscape/square/portrait) is not exposed by the API. Parameters: - customer_id: Optional (uses connected account if omitted) - ad_id: single ad — OR ad_group_id — OR campaign_id (bulk). At least one required. - status_filter: 'all' (default — includes paused, useful for archiving) | 'enabled' - limit: max ads (default 50, max 100) Execution time: 2-5 seconds (2 GAQL queries, then cached 15 min) Use this tool when: - User asks "what's in this ad?", "download/export my creatives", "which video/image does this ad use?" - After get_ad_performance identified a winner/loser and the user wants to see or reuse its creative - User wants to rebuild a winning ad in another format or audit live creatives Tip: Pair with get_ad_performance — performance tells you WHICH ad wins, this tells you WHAT it's made of.
get_ad_performance
ChatGPTPer-AD performance breakdown — one row per ad, with individual metrics. This tool retrieves READ-ONLY data via 1 live GAQL query (cached 5 min in Redis). Safe to call multiple times. Why this tool: get_campaign_performance stops at ad-group granularity. When an ad group contains several live ads, this is the only tool that shows which creative is winning so you can pause losers and scale winners. Returns one row per ad: - Identity: ad_id, ad_name, ad_group_id, ad_group_name, campaign_id, campaign_name - State: ad_type (e.g. DEMAND_GEN_VIDEO_RESPONSIVE_AD, DEMAND_GEN_MULTI_ASSET_AD, RESPONSIVE_SEARCH_AD), status, ad_strength, is_live (ad + ad group + campaign all ENABLED) - Metrics for the date range: impressions, clicks, ctr, cost, conversions, conversion_value, cpc, cpa, roas, video_views, video_view_rate (video ads) - totals block + explicit truncation info (total_ads_matched vs returned) Coverage: Search, Display, Demand Gen, YouTube campaigns. NOT PMax — PMax has no per-ad rows (asset-group model); use get_pmax_asset_performance instead. Row filter: REMOVED ads excluded. Paused ads are included only if they actually served in the window (so per-ad numbers still roll up to ad-group totals without zero-row noise). Parameters: - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90, 120 (default 30). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided) - campaign_id: Optional — scope to one campaign - ad_group_id: Optional — scope to one ad group - limit: Max ads returned, cost-desc (default 100, max 500) Execution time: 1-3 seconds (1 GAQL query, then cached 5 min) Use this tool when: - User asks "which ad/creative is performing best?" or "which video is winning?" - User wants to pause losing creatives or scale winning ones (follow with pause_ad) - User needs per-ad CTR / CPA / ROAS / video view rate inside an ad group - After get_campaign_performance shows an ad group worth drilling into Tip: Pair with get_ad_creative to see WHAT each winning/losing ad is made of (videos, images, headlines).
get_asset_group_listing_filters
ChatGPTRead a retail Performance Max asset group's product listing-filter tree. Retail PMax (a PMax campaign linked to a Merchant Center account) can partition which products each asset group promotes. Returns each filter node: filter_id, parent_id, node_type (SUBDIVISION / UNIT_INCLUDED / UNIT_EXCLUDED), the dimension it represents, and whether it's excluded. An empty tree means the asset group promotes ALL feed products. Required: asset_group_id (a retail-PMax asset group, from get_pmax_asset_groups).
get_benchmark_context
ChatGPTGet industry benchmark context for AI-powered recommendations. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. 🎯 What This Tool Does (Performance Agent - Phase 1 Feature 5): - Generates contextual benchmark data for the user's business - Combines business profile with industry benchmarks - Provides recommended ROAS targets based on vertical - Returns formatted context for AI prompts Returns benchmark context: - Business vertical and size context - Industry-specific ROAS benchmarks (typical, good, excellent) - CTR benchmarks by industry - CPC expectations for the vertical - Seasonality considerations - Custom recommendations based on profile Industry Benchmarks Included: | Vertical | Typical ROAS | Good ROAS | Excellent ROAS | |----------|--------------|-----------|----------------| | Retail | 4.0x | 6.0x | 8.0x | | Services | 3.0x | 5.0x | 7.0x | | Technology | 3.5x | 5.5x | 8.0x | | Healthcare | 2.5x | 4.0x | 6.0x | | Finance | 5.0x | 8.0x | 12.0x | | Education | 2.0x | 3.5x | 5.0x | Parameters: - include_recommendations: Include performance recommendations (default: true) - customer_id: Optional (uses connected account if omitted) Use this tool when: - Before providing performance analysis - When comparing user's metrics to industry standards - User asks "how am I doing compared to others?" - You need context for optimization recommendations Integration with Other Tools: Call this BEFORE or AFTER these tools for enhanced recommendations: - analyze_wasted_spend - Contextualize waste against industry norms - optimize_budget_allocation - Use industry-appropriate ROAS targets - get_campaign_performance - Compare metrics to benchmarks - explain_performance_anomaly - Understand if changes are industry-wide Execution time: 1-2 seconds (profile lookup + benchmark calculation)
get_business_profile
ChatGPTGet the user's business profile for contextual recommendations. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. 🎯 What This Tool Does (Performance Agent - Phase 1 Feature 5): - Retrieves the user's saved business profile - Returns business vertical, size, goals, target audience - Provides context for more relevant recommendations - Shows profile source (user-set, inferred, or none) Returns business context: - Business vertical (retail, services, technology, etc.) - Business size (small, medium, large) - Primary goal (leads, sales, awareness, traffic) - Target audience description - Geographic focus (local, regional, national, international) - Seasonality patterns - Profile confidence level Use this tool when: - You need business context for recommendations - Before providing industry-specific advice - User asks "what type of business am I?" - You want to personalize optimization suggestions If no profile exists: - Use infer_business_profile to automatically detect from campaign data - Or ask user to provide business details via save_business_profile Execution time: 1-2 seconds (database lookup)
get_campaign_dates
ChatGPTRead a campaign's start and end dates. Returns start_date and end_date (YYYY-MM-DD). An end_date far in the future (e.g. 2037-12-30) or empty means the campaign has no scheduled end. Works on any campaign type. Required: campaign_id (from list_campaigns).
get_campaign_frequency_caps
ChatGPTRead a campaign's frequency caps (how often a user can see the ads). Returns the list of caps, each with level, event_type, time_unit, time_length, and cap. An empty list means no frequency capping is configured. Works on any campaign type. Required: campaign_id (from list_campaigns).
get_campaign_labels
ChatGPTList the labels currently attached to a campaign. Returns each attached label's id, name, and description. Use remove_campaign_label with a label id to detach it. Required: campaign_id (from list_campaigns).
get_campaign_performance
ChatGPTAnalyze Google Ads campaign performance with comprehensive insights and recommendations. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. Returns detailed analysis: - Campaign structure and ad group organization - Keyword performance with quality scores and match types - Ad group performance breakdown - Performance metrics (CTR, conversions, CPC, cost, ROAS) - Optimization recommendations with actionable insights - Performance trends (last 7 days) Parameters: - lookback_days: 7, 30, 60, 90, or 120 days (default: 30) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - customer_id: Optional (uses connected account if omitted) - campaign_id: Optional. When provided, scopes the analysis to a single campaign (all metrics, ad groups, keywords, and trends reflect that campaign only). Omit for account-wide analysis. Use list_campaigns first to find the campaign ID. Execution time: 2-5 seconds (direct backend API call) Data source: Cached database (updated nightly via metrics collection) Use this tool to: - Review current campaign performance - Identify optimization opportunities - Get data-driven recommendations - Analyze keyword and ad effectiveness - Understand what's working and what needs improvement
get_campaign_structure
ChatGPTGet campaign structure with ad groups, keywords, ads, and extensions. Supports pagination for large campaigns. This tool retrieves READ-ONLY data. Safe to call multiple times. Returns campaign hierarchy (paginated by ad groups): - Campaign details (name, status, budget, bidding strategy) - Ad groups with their settings (paginated — default 5 per page) - Keywords per ad group (including match types, bids, status) - Ads per ad group (including RSA headlines/descriptions, ad strength) - Negative keywords per ad group - Campaign-level extensions and negative keywords (on page 1 only) - Pagination metadata (page, total_pages, has_more) - Summary counts (total ad groups, keywords, ads across ALL pages) Parameters: - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - customer_id: Optional (uses connected account if omitted) - page: Page number, 1-based (default: 1) - page_size: Ad groups per page, 1-50 (default: 5) - ad_group_id: Optional — fetch only this single ad group (bypasses pagination) - include: What detail per ad group: 'all' (default), 'summary' (counts only), 'keywords', 'ads' ⚡ PAGINATION CONTRACT (IMPORTANT FOR AI AGENTS): - The response includes pagination.has_more — if true, you MUST call again with page incremented - Continue calling until has_more is false - Then consolidate all pages and present the complete campaign structure to the user - The summary section is always included and shows total counts across ALL ad groups (not just the current page) - Extensions and campaign-level negative keywords are only returned on page 1 - Use ad_group_id to drill into a single ad group when the user asks about a specific one - Use include='summary' for a quick overview without nested keyword/ad data Execution time: 3-8 seconds per page (multiple API queries) Use this tool when: - User wants to update an existing campaign - User wants to see current keywords/ads - User wants to add extensions to existing campaign - User says "show me what's in this campaign" - Before making any updates to a campaign Important IDs returned: - campaign.id - For campaign-level updates (budget, status) - ad_groups[].id - For adding keywords/ads - keywords[].id - For keyword updates (status, bids) - ads[].id - For ad content updates Example flow: 1. User: "I want to update my campaign" 2. Agent: Uses list_campaigns to show all campaigns 3. User: Selects campaign "Summer Sale 2025" 4. Agent: Uses get_campaign_structure with that campaign_id 5. If has_more=true, agent calls again with page=2, page=3, etc. 6. Agent: Shows consolidated structure and asks what to update 7. User: "Change the headlines" 8. Agent: Uses update_ad_headlines with the ad_id from structure
get_campaign_targeting
ChatGPTFull targeting view for a Google Ads campaign — locations, languages, demographics, audiences, devices, ad schedule, topics, placements, keywords, AND negative variants of each. This tool retrieves READ-ONLY data via 2 GAQL queries (cached 15 min in Redis). Safe to call multiple times. Returns sections (only the ones with data are rendered): - 📍 Locations — geo target constants + bid modifiers - 🌐 Languages — language constants - 👥 Demographics — gender, age range, parental status, income range (campaign or ad-group level, with bid modifiers) - 🎯 Audiences — user lists (remarketing), user interests (in-market/affinity), custom audiences, combined audiences, AUDIENCE resource - 📱 Devices — device type + bid modifier - ⏰ Ad Schedule — day of week + hour window + bid modifier - 📺 Topics — topic constants (Display) - 🌐 Placements — managed placement URLs (Display) - 🔑 Keywords — keyword text + match type - 🚫 Negatives — exclusion list across the same dimensions Parameters: - campaign_id: The campaign ID (REQUIRED — get from list_campaigns) - customer_id: Optional (uses connected account if omitted) Execution time: 2-5 seconds (2 GAQL queries, then cached 15 min) Use this tool when: - User asks "what is this campaign targeting?" — covers ALL targeting axes - User asks "what audiences/demographics/devices does this campaign target?" - User wants ad schedule, placement, or topic exclusions - Before recommending targeting changes - To audit targeting setup post-creation Out of scope (tracked separately): - PMax asset_group_signals (different resource) - Customer-level negative criterion lists (account-wide negatives) - Shared negative keyword lists (separate resource) - 3rd-party brand safety / IVT services
get_campaign_tracking
ChatGPTRead a campaign's URL tracking settings. Returns the campaign-level tracking_url_template (click-measurement/redirect URL), final_url_suffix (query params appended to the landing page), and url_custom_parameters (the {key,value} params usable as {_key} in the template). Use this to see or verify what update_campaign set. Reads/writes of these tracking fields are campaign-level and apply to all ads in the campaign. Required: campaign_id (from list_campaigns).
get_connections_status
ChatGPTView connected ad accounts and OAuth connections. Shows all connected ad platforms (Google Ads, TikTok Ads, Meta Ads, LinkedIn Ads) with: - Connection status and account details - Primary account indicator - Option to switch primary account - Quick links to connect new platforms Use this tool when user asks about: - "how many accounts do I have" / "how many ad accounts" - "what accounts are connected" / "connected accounts" - "which account am I using" / "current account" - "show my connections" / "list my accounts" - "connection status" / "account status" - "what platforms do I have connected" - Account count, account list, or connection overview Do not use for: - Discovering campaigns, ads, or keywords (use discover_existing_assets) - Performance data or metrics (use performance tools) - Creating or managing campaigns This is specifically for OAuth connections and account management.
get_conversion_action_performance
ChatGPTPer-conversion-action performance breakdown. This tool retrieves READ-ONLY data via 2 live GAQL queries (cached 5 min in Redis). Safe to call multiple times. Returns: - totals — account or campaign aggregate: cost, conversions, conversion_value, CPA, ROAS, clicks, impressions - breakdown — per-conversion-action rows: conversions, conversion_value, all_conversions, all_conversions_value, avg_value_per_conversion, share_of_conversions, share_of_value - note — explains why per-action CPA/ROAS are NOT computed Important — what this tool does NOT do: Per-action CPA and ROAS are NOT shown. Google Ads rejects cost_micros when segmenting by conversion_action because cost is shared across all actions a click can produce. We do NOT prorate cost per action — that would fabricate data. Account/campaign-level CPA + ROAS appear in totals. Use share_of_conversions and share_of_value to see relative contribution per action. Parameters: - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90, 120 (default 30). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided) - campaign_id: Optional. Scopes the breakdown to a single campaign. Execution time: 2-5 seconds (2 GAQL queries, then cached 5 min) Use this tool when: - User asks "which conversion action drove the most conversions / value?" - User wants per-action breakdown for accounts with multiple conversion actions (e.g., lead vs purchase) - User wants to see relative contribution of each action to total conversions/value - After list_conversion_actions to map IDs to performance Tip: Use this AFTER list_conversion_actions so you know action names/IDs/categories. For a single campaign: pass campaign_id from list_campaigns.
get_display_ad_group_settings
ChatGPTRead every editable setting on a Display ad group. Returns: id, name, status, type (DISPLAY_STANDARD), campaign resource, current cpc_bid + cpm_bid (both in account currency AND micros), ad_rotation_mode, optimized_targeting_enabled, exclude_demographic_expansion. Use this before update_display_ad_group so you can show the user the current state and ask for which fields to change. Execution time: 1-3 seconds (read-only).
get_display_audiences
ChatGPTList audience targeting on a Display campaign's ad groups. Returns entries with type ∈ {USER_LIST, CUSTOM_AUDIENCE, USER_INTEREST, COMBINED_AUDIENCE}. Execution time: 1-3 seconds (read-only).
get_display_demographics
ChatGPTList demographic targeting (age, gender, parental status, income) on a Display campaign's ad groups. Each entry has a negative flag — Google targets via exclude-the-inverse: to target MALE only, everything else is listed as negative criteria. Execution time: 1-3 seconds (read-only).
get_display_frequency_caps
ChatGPTRead the frequency caps currently configured on a Display campaign. Returns a list of {level, event_type, time_unit, time_length, cap} entries. Execution time: 1-3 seconds (read-only).
get_display_keywords
ChatGPTList contextual display keywords on a Display campaign's ad groups. Display keywords are always BROAD-match (Google ignores match_type on Display). Execution time: 1-3 seconds (read-only).
get_display_placements
ChatGPTList all managed placements (websites, mobile apps, YouTube channels, YouTube videos) on a Display campaign's ad groups. Returns list of placements with ad_group_id, criterion_id, type, value, status. Use criterion_id + ad_group_id to construct a resource name for remove_display_criteria: customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id} Execution time: 1-3 seconds (read-only).
get_display_topics
ChatGPTList topic targeting on a Display campaign's ad groups. Topics are Google's content categories (e.g., Finance, Travel, Technology). See Google's topic taxonomy at https://developers.google.com/google-ads/api/data/codes-formats#verticals Execution time: 1-3 seconds (read-only).
get_merchant_center_links
ChatGPTList the Merchant Center accounts linked to this Google Ads account. A Merchant Center link is required before you can create a Shopping campaign. Returns each link's merchant_center_id and product_link_id. An empty list means no Merchant Center account is linked yet — use link_merchant_center to add one.
get_meta_ad_creatives
ChatGPTUser wants to see their Meta ad creatives, ad copy, media URLs, or creative performance. Returns ad-level data including full creative content and media URLs alongside performance metrics. When to use this tool: - "Show me my Meta ad creatives" - "What ads are running and how are they performing?" - "Show me the headlines and images for my ads" - "Which ad creatives are performing best?" - "What's the creative content for campaign X?" - "Show me ad performance with creative details" - "Get me the image URLs for my ads" - "Export my ad copy" - "What images and videos are my ads using?" Returns per ad — ALWAYS display ALL of these fields when present: - Ad copy: headline, primary_text, description, call_to_action_type - Media URLs: image_url (direct CDN link to ad image), thumbnail_url, video_url (playable video source), video_id - Landing page: landing_page_url - Carousel cards: carousel_cards array with per-card image_url, headline, description, landing_page_url - Performance: spend, impressions, clicks, CTR, CPC, reach, frequency - Video engagement: 25%, 50%, 75%, 100% watched (for video ads) - Creative metadata: creative_type (image/video/carousel/dynamic_creative), first_seen_date IMPORTANT: Always show the full image_url, thumbnail_url, video_url, and landing_page_url values — these are direct CDN links users need to download/export their creative media. Do not summarize or omit URLs. Parameters: - lookback_days: Number of days to analyze (7, 14, 30, 60, 90). Default: 30 - campaign_id: Optional filter to specific campaign - ad_set_id: Optional filter to specific ad set - ad_account_id: Required for multi-account users. Get from list_connected_accounts - start_date/end_date: Optional custom date range (overrides lookback_days) - limit: Max ads per page (default 20, max 50). Use for pagination. - offset: Number of ads to skip (default 0). Use with limit to page through results. Pagination: Results are paginated. Response includes total_ads count and has_more flag. To get next page, increase offset by limit. Execution time: 1-3 seconds Data source: Cached database (collected daily)
get_meta_app_adsets
ChatGPTUser wants PER-AD-SET install cost for app-promotion (AEO) campaigns — drill into a campaign's ad sets to see which audiences/placements deliver the cheapest installs. Keywords: "CPI by ad set", "which ad set / audience has the cheapest installs", "ad set install cost". Pass campaign_id (from get_meta_app_campaigns) to scope to one campaign. Each ad set shows installs, CPI, and a self-relative comparison to the account average. Reads cached nightly metrics. When to use: "Which ad set in this campaign has the lowest CPI?", "Cost per install by audience".
get_meta_app_campaigns
ChatGPTUser wants PER-CAMPAIGN install cost for their app-promotion (AEO) campaigns. Keywords: "CPI by campaign", "which campaign has the cheapest/most expensive installs", "per-campaign cost per install", "compare install cost across app campaigns". Lists each app campaign's installs and CPI, with a self-relative comparison to the account average CPI (e.g. "+105% vs account" = pricier installs). Honest CPI severity is applied to the top spenders; the rest show install/CPI facts. Run get_meta_app_summary first for the account headline, then this to find the cheap and expensive campaigns. Reads cached nightly metrics. When to use: "Which app campaign has the lowest CPI?", "Break down cost per install by campaign".
get_meta_app_creatives
ChatGPTUser wants PER-CREATIVE (per-ad) install cost for app-promotion (AEO) campaigns — which creatives/videos drive the cheapest installs. Keywords: "CPI by creative/ad", "best/worst creative for installs", "which ad has the cheapest installs", "creative install cost". Ranks creatives cheapest-install-first. Pass campaign_id or ad_group_id (from the campaigns/ad-sets tools) to scope. Reads cached nightly metrics. When to use: "Which creative has the lowest CPI?", "Best-performing ad for installs".
get_meta_app_summary
ChatGPTUser wants their mobile-APP-promotion (AEO / App Installs / OUTCOME_APP_PROMOTION) performance — INSTALLS and COST PER INSTALL (CPI). Keywords: "CPI", "cost per install", "how many installs", "app installs", "install cost", "AEO performance", "mobile game/app campaign performance", "UA performance", "cost per registration/purchase in-app". The account headline for app campaigns: total installs, CPI (cost per install) graded against the account's OWN goal or 90-day average (never an invented benchmark — abstains honestly if there's no goal/history), and the in-app-event FUNNEL cost ladder (install → activate → registration → add-to-wishlist → checkout → level → purchase) with the cost per event. This is the fast entry point — then drill into per-campaign / ad-set / creative install cost. Reads cached nightly metrics (never calls Meta live). When to use: "What's my CPI?", "How are my app install campaigns doing?", "Cost per install this month?", "Show my install funnel / cost per in-app event".
get_meta_campaign_performance
ChatGPTUser asks about Meta/Facebook/Instagram ad performance, campaign metrics, ROAS, spend analysis, or wants to understand how their Meta ads are performing. This tool retrieves comprehensive campaign performance metrics from Meta Ads. Returns: - Account summary (total spend, impressions, reach, conversions, ROAS) - Campaign breakdown with status and objectives - Top performing campaigns by ROAS - Meta-specific metrics (reach, frequency, reach/impressions ratio) - Optimization recommendations When to use this tool: - "How are my Meta ads performing?" - "What's my Facebook campaign ROAS?" - "Show me Instagram ad performance" - "Which Meta campaigns are doing best?" - "Analyze my Meta ad spend" Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - include_recommendations: true (default) or false - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds (cached database query) Data source: campaign_daily_metrics table (updated nightly) Note: Unlike Google Ads, Meta does not have keyword or search term data. Meta uses interest-based targeting.
get_meta_pixel_stats
ChatGPTUser wants to set up RETARGETING catalog ads, or check whether a pixel is firing product events. Returns pixel health (last fired time, availability) and recent event breakdown. Use to confirm ViewContent / AddToCart / Purchase are firing before building a retargeting catalog campaign; if they aren't, recommend prospecting instead. When to use: - Before a retargeting catalog ad - "Is my pixel working?", "what events is my pixel getting?"
get_meta_product_performance
ChatGPTUser wants to drill into ONE specific catalog product's performance over time — its daily spend/ROAS trend and full funnel (views → carts → checkouts → purchases). Get the product_id from analyze_meta_catalog_performance first. When to use: "How is product X doing?", "Show me the trend for this SKU", "What's the funnel for this product?"
get_negative_keyword_list
ChatGPTShow the keywords inside one shared negative keyword list. ⚠️ READ-ONLY. Safe to call repeatedly. Lists the negative keywords (text + match type) in a specific shared list. Paged and filterable (query, sort_by, offset/limit) for large lists. Parameters: shared_set_id (required — from list_negative_keyword_lists). Use when: "what's in my negative keyword list?", "show the keywords in list X".
get_placement_performance
ChatGPTPer-PLACEMENT performance WITH conversions — where your ads actually ran (websites, YouTube channels/videos, apps) and what each placement cost and produced. This tool retrieves READ-ONLY data via 1 live GAQL query (cached 5 min in Redis). Safe to call multiple times. Why this tool: get_display_placements shows only the placements you manually targeted (config, no metrics). get_campaign_performance stops at ad-group granularity. This is the ONLY tool that shows WHERE Display / Demand Gen / Video / Smart ads actually delivered — including automatic placements Google chose — with cost AND conversions per placement. It's the data behind the Google Ads UI "Where ads showed" / Content → Placements report. Returns one row per placement (or per domain/channel when group_view=true): - Identity: placement_type (WEBSITE / YOUTUBE_CHANNEL / YOUTUBE_VIDEO / MOBILE_APPLICATION / …), display_name, target_url (the site / channel / app), campaign_name, ad_group_name (detail view) - Metrics for the date range: impressions, clicks, ctr, cost, conversions, conversion_value, all_conversions, cpc, cpa, roas - totals block + pagination (page / total_pages / has_more) These reports are huge (a Demand Gen account can have 150,000+ placements). Filter SERVER-SIDE so you don't pull everything: - min_cost — only placements that spent at least this much (account currency) - min_impressions — only placements above an impression floor - zero_conversions_only — only placements with ZERO conversions (spent money, no conversions). Pair with min_cost to find wasted spend to exclude. - placement_type — restrict to WEBSITE / YOUTUBE_CHANNEL / etc. - order_by — cost | conversions | impressions | clicks - group_view=true — roll up per domain/channel for fewer rows Pagination: results are paged. Check pagination.has_more in the response — if true, call again with page incremented (page=2, page=3, …) to get the next set of placements. Continue until has_more is false. Coverage: Display, Demand Gen, Video, Smart campaigns (any campaign that runs on the Display/YouTube network). Search campaigns have no placement rows. These numbers are the account's own measured data — this tool renders NO verdicts, invents no "good/bad" thresholds, and applies no baseline. It shows the placements and their metrics so you (and the user) can decide. zero_conversions_only is a factual filter, not a judgement. Parameters: - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90, 120 (default 30). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided) - campaign_id: Optional — scope to one campaign - placement_type / group_view / min_cost / min_impressions / zero_conversions_only / order_by: filters above - page / page_size: pagination (page_size default 50, max 200) Execution time: 1-4 seconds (1 GAQL query, then cached 5 min) Use this tool when: - User asks "where did my ads show?", "which websites / YouTube channels / apps converted?", "where is Display/Demand Gen wasting money?" - User wants to find placements with spend but no conversions to exclude them - User wants per-placement cost / conversions / CPA to optimize Display or Demand Gen Tip: Find waste with zero_conversions_only=true + min_cost, then exclude it with add_placement_exclusions.
get_product_groups
ChatGPTRead a Shopping ad group's product-partition (listing-group) tree. Shows how the ad group's products are subdivided for bidding. Returns each node: criterion_id, parent_id, node_type (SUBDIVISION branch / UNIT leaf), the dimension it represents, its bid, and whether it's excluded. An empty tree means the ad group serves ALL products at the ad-group bid. Required: ad_group_id (a Shopping ad group).
get_reach_frequency
ChatGPTReach & frequency — how many UNIQUE users your campaigns reached, and the average number of times each person saw your ads. This tool retrieves READ-ONLY data via 1 live GAQL query (cached 5 min in Redis). Safe to call multiple times. Why this tool: get_campaign_performance reports impressions but not unique reach. This is the only tool that returns unique_users (de-duplicated people reached) and average_impression_frequency_per_user (the "Avg. impr. freq. / user" column in the Google Ads UI) — the direct signal for creative-fatigue and rotation decisions on YouTube / Demand Gen / Video campaigns, instead of proxying frequency from CPM/CTR trends. Returns one row per campaign (sorted by impressions): - campaign_id, campaign_name, campaign_type, status - impressions, unique_users, avg_impression_frequency_per_user Google constraints (surfaced honestly, not bugs): - Reach metrics are campaign-level only — Google REJECTS them at the ad-group level, so this tool cannot break reach down by ad group. - Reach is populated for reach-eligible campaign types (Demand Gen, Video/YouTube, Performance Max, Display). Search campaigns typically report 0 unique users. - Google reports unique reach only for a trailing ~92-day window; a longer window silently returns zeros, so the lookback is clamped to 92 days (the tool tells you when it clamped). - unique_users is de-duplicated over the window and is NOT summed across campaigns (the same person can be reached by more than one campaign). These are the account's own measured numbers — the tool renders NO verdict and invents no "healthy frequency" threshold. Whether a given frequency is too high depends on the campaign and goal; the tool reports the number and leaves the call to you. Parameters: - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90 (clamped to ≤92). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided; clamped to last 92 days) - campaign_id: Optional — scope to one campaign Execution time: 1-3 seconds (1 GAQL query, then cached 5 min) Use this tool when: - User asks "what's my reach / frequency?", "how many unique users did I reach?", "how often is each person seeing my ad?" - User is deciding whether to rotate/refresh creative on a YouTube or Demand Gen campaign (frequency is the fatigue signal) - User wants unique reach instead of raw impressions
get_shopping_settings
ChatGPTRead a Shopping campaign's Merchant Center settings. Returns the shopping_setting that binds the campaign to Merchant Center: merchant_id, feed_label, campaign_priority (0-2), enable_local, disable_product_feed. Use get_campaign_structure for the ad groups / ads / budget / bidding / network; this tool is specifically for the Merchant-Center binding. Required: campaign_id (a Shopping campaign — from list_campaigns).
get_usage_status
ChatGPTGet your current usage status with interactive quota widget. This tool shows your tool call usage for the current billing period and provides upgrade options if needed. For annual subscribers it shows the pooled yearly allowance ("X / 1,800 used this year"), the annual reset date, and confirms there is no monthly cap. Returns: - Current usage (calls used / limit) — monthly limit or annual pool - Subscription tier (Free, Plus, Pro, Enterprise) and billing period (monthly / annual) - When the quota or annual pool resets - Upgrade options with pricing Use this tool when: - User asks "how many calls do I have left?" - User asks about their subscription or quota - User wants to check their usage - User asks about upgrading their plan Widget Display (ChatGPT): In ChatGPT, this tool displays an interactive widget with: - Visual progress bar showing usage - Upgrade buttons that open Stripe checkout - Plan comparison with pricing Note: This tool is READ-ONLY and safe to call anytime.
google_ads
ChatGPTAccess all Google Ads campaign management tools. Use action="list_tools" first to see available operations and their parameters. Then use action="execute" with the specific tool_name and arguments. Available capabilities: - Campaign Performance: Analyze metrics, wasted spend, budget optimization, search terms, anomaly detection - Campaign Creation: Search, Performance Max, YouTube, Demand Gen, Display (+ Smart Display) campaigns with full asset validation - Campaign Management: Update settings, pause/resume, bid strategies, budget changes - Keyword Management: Add/remove/update keywords and negative keywords - Ad Management: Create ads, update headlines/descriptions/content, pause/resume ads - Extensions: Callout extensions, structured snippets, sitelinks - PMax Controls: Search themes, audience signals - Audiences: Search and discover audience segments - Business Profile: Get/infer/save business profile, benchmarking context - Asset Management: Upload images, validate and prepare assets, discover existing assets ⚠️ Side effects & confirmation: Write operations change a live Google Ads account. New campaigns are created PAUSED and must be explicitly confirmed by the user before launch. Budget, bid, and status changes (pause/resume) take effect immediately and can disrupt ad delivery. Keyword and ad removals may not be reversible. When to use this tool: - "How are my Google Ads campaigns performing?" - "Create a new search campaign" - "Pause my underperforming campaigns" - "Add negative keywords to reduce wasted spend" - "Research keywords for my business" - "What's my campaign structure?" Raw data mode (performance tools only): If the user asks for "raw data", "raw metrics", "just the numbers", "no recommendations", or "no commentary" — pass raw_data: true inside arguments when calling any performance tool (get_campaign_performance, analyze_wasted_spend, optimize_budget_allocation, analyze_search_terms, explain_performance_anomaly). You receive a JSON code block of metrics only: spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, ROAS by campaign/date. Severity labels, suggested bids, suggested budgets, industry benchmarks, and optimization recommendations are stripped. Default is false (full formatted analysis). Example — list tools: action: "list_tools" Example — get performance: action: "execute" tool_name: "get_campaign_performance" arguments: {"customer_id": "123-456-7890", "lookback_days": 30} Example — raw performance (user asked for raw data): action: "execute" tool_name: "get_campaign_performance" arguments: {"customer_id": "123-456-7890", "lookback_days": 30, "raw_data": true}
google_analytics
ChatGPTRead Google Analytics 4 reports and metadata for the user's connected GA4 properties. Use action="list_tools" first to discover available actions and their parameters. Then use action="execute" with the specific tool_name and arguments. When to use: - Website / app traffic, sessions, users, page views, bounce rate, engagement - Conversions, conversion events, key events, goal completions - Audience demographics, geography, device breakdown - Traffic sources (organic, paid, referral, social, direct) - Comparing ad spend (from google_ads / meta_ads) to actual site outcomes - "How is my website performing?", "show GA4 conversions", "what's my bounce rate" If the user hasn't connected Google Analytics, this tool returns a friendly message asking them to open Settings → Connections to authorize the connection. Example — list actions: action: "list_tools" Example — run a report: action: "execute" tool_name: "google_analytics-run-report" arguments: {"propertyId": "493035312", "dateRanges": [{"startDate": "7daysAgo", "endDate": "today"}], "metrics": [{"name": "sessions"}, {"name": "totalUsers"}]}
help_user_upload
ChatGPTShow user instructions for uploading images to postimages.org for Performance Max campaigns. ⚠️ CALL THIS FIRST when user wants to create a PMax campaign! YOUR ROLE: Image Upload Guide WHEN TO USE: - User says "create PMax campaign" or similar - Before asking for image uploads - Anytime user needs help uploading images WHAT THIS DOES: - Returns clear, step-by-step instructions - Tells user to upload to postimages.org - Explains how to get Direct links (not share pages) - Shows example URL format DO NOT: - Ask user to upload via ChatGPT's paperclip (won't work with size limits!) - Request base64 data (too large!) - Skip this step (user needs clear guidance) AFTER THIS: - User uploads to postimages.org - User pastes Direct links in chat - You call validate_and_prepare_assets with those URLs Execution Time: <1 second (just returns text) Authentication: Not required
infer_business_profile
ChatGPTAutomatically infer business profile from campaign data using AI analysis. ⚠️ IMPORTANT: This tool ANALYZES data but may SAVE a profile if confidence is high. 🎯 What This Tool Does (Performance Agent - Phase 1 Feature 5): - Analyzes campaign names, keywords, and ad copy - Uses Claude AI to classify business type - Infers business vertical, size, goals, and audience - Returns confidence level (high, medium, low) - Auto-saves if confidence is HIGH, asks confirmation for LOW Inference Process: 1. Collects campaign names and keywords from Google Ads 2. Analyzes patterns (B2B vs B2C, product vs service) 3. Uses AI to classify business vertical 4. Estimates business size from ad spend 5. Identifies primary goals from campaign types Confidence Levels: - HIGH (≥0.8): Auto-saves profile, high certainty - MEDIUM (0.5-0.8): Saves profile, reasonable certainty - LOW (<0.5): Returns suggestion, asks user to confirm Parameters: - force_save: Set to true to save even low-confidence profiles - customer_id: Optional (uses connected account if omitted) Returns: - Inferred business profile (vertical, size, goal, audience) - Confidence level and reasoning - Whether profile was saved or needs confirmation - Suggested confirmation prompt for low-confidence results Use this tool when: - User doesn't have a business profile set - User asks "analyze my business" - You need business context but none exists - After user connects a new Google Ads account Example Flow: 1. Call get_business_profile - returns no profile 2. Call infer_business_profile - analyzes campaigns 3. If HIGH confidence: Profile saved automatically 4. If LOW confidence: Ask user to confirm with suggested prompt Execution time: 3-8 seconds (AI analysis + optional save)
link_merchant_center
ChatGPTLink a Merchant Center account to this Google Ads account. This is the prerequisite for Shopping campaigns — the product feed lives in Merchant Center, and the link lets Google Ads serve those products. If the same Google login administers both accounts the link is created directly; otherwise Google creates a pending invitation that must be accepted on the Merchant Center side. Required: merchant_center_id (the numeric ID shown in Merchant Center).
linkedin_ads
ChatGPTAccess all LinkedIn Ads campaign management tools. Use action="list_tools" first to see available operations and their parameters. Then use action="execute" with the specific tool_name and arguments. Available capabilities: - Campaign Performance: Analyze metrics, engagement, audience insights, wasted spend, anomaly detection - Campaign Creation: Image, video, carousel, text ad campaigns with asset discovery - Campaign Management: Update settings, pause/resume, clone, batch update, budget/schedule/targeting changes - Creative Management: Add/update/pause/resume/delete creatives (image, text, video, carousel) - Multi-Campaign Composition: Add campaigns to existing groups (different audiences), add creatives to campaigns (A/B testing) - Targeting: Search targeting options, research business for targeting, 19 targeting facets - Conversions: List, associate, manage conversion tracking - Campaign Groups: List and update campaign groups - AI Features: Generate ad creatives, explain objectives, research business targeting ⚠️ Side effects & confirmation: Write operations change a live LinkedIn Ads account. New campaigns are created PAUSED and must be explicitly confirmed by the user before launch. Budget, schedule, targeting, and status changes (pause/resume) take effect immediately and can disrupt ad delivery. Deleting a creative is irreversible. When to use this tool: - "How are my LinkedIn campaigns performing?" - "Create a new LinkedIn sponsored content campaign" - "Show me my LinkedIn ad engagement metrics" - "What targeting options are available on LinkedIn?" - "Pause my underperforming LinkedIn campaigns" Raw data mode (performance tools only): If the user asks for "raw data", "raw metrics", "just the numbers", "no recommendations", or "no commentary" — pass raw_data: true inside arguments when calling any performance tool (get_linkedin_campaign_performance, get_linkedin_engagement_metrics, get_linkedin_audience_insights, analyze_linkedin_wasted_spend, optimize_linkedin_budget, explain_linkedin_anomaly, analyze_linkedin_creative_performance). You receive a JSON code block of metrics only: spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, engagement rate, lead form completion rate by campaign/creative/date. Severity labels, suggested bids, suggested budgets, industry benchmarks, and optimization recommendations are stripped. Default is false (full formatted analysis). Example — list tools: action: "list_tools" Example — get performance: action: "execute" tool_name: "get_linkedin_campaign_performance" arguments: {"lookback_days": 30} Example — raw performance (user asked for raw data): action: "execute" tool_name: "get_linkedin_campaign_performance" arguments: {"lookback_days": 30, "raw_data": true}
list_campaigns
ChatGPTList all Google Ads campaigns for the connected account. ⚠️ CRITICAL: Call this tool BEFORE creating new campaigns to ask the user: "Would you like to create a new campaign or update an existing one?" This tool retrieves READ-ONLY data. Safe to call multiple times. Returns: - List of all campaigns with IDs, names, status, type, budget - 30-day performance metrics for each campaign (impressions, clicks, cost, conversions) - Total campaign count Parameters: - status_filter: ENABLED, PAUSED, or ALL (optional, default: ALL) - campaign_type: SEARCH, PERFORMANCE_MAX (or PMAX), DISPLAY, SHOPPING, VIDEO, DEMAND_GEN, APP, or ALL (optional, default: ALL) - customer_id: Optional (uses connected account if omitted) Execution time: 2-5 seconds (direct Google Ads API call) Campaign Management Guidelines: BEFORE Starting Any Campaign Work: 1. ALWAYS use list_campaigns first 2. Ask user: "Would you like to create a new campaign or update an existing one?" 3. If updating, use get_campaign_structure to see full details User Intent Mapping: | User Says | Agent Action | |-----------|--------------| | "Create a campaign for X" | List existing first, then ask create vs update | | "Change the budget" | Get structure, then use update tools | | "Add more keywords" | Get structure, then add keywords | | "Update my ads" | Get structure, then update ad content | | "Pause the campaign" | Use pause_campaign tool | Use this tool to: - View all existing campaigns before creating new ones - Find campaign IDs for update operations - Get a quick overview of account structure - Identify active vs paused campaigns
list_connected_accounts
ChatGPTList all connected ad accounts across platforms. Returns account IDs, names, and platforms for all active accounts. Use this at the start of every conversation to know which accounts are available. CRITICAL for multi-account users (agencies): - Always call this first to discover available accounts - Use the returned account IDs when calling any platform tool - If user mentions a business name, match it to an account from this list Returns for each account: - platform: google_ads, meta_ads, tiktok_ads, linkedin_ads - account_id: Platform account ID (pass to tools as customer_id/ad_account_id/advertiser_id/account_id) - account_name: Display name - account_tier: primary, secondary, or active - status: connected, needs_reauth Zero API calls — reads directly from database.
list_conversion_actions
ChatGPTList conversion actions for the connected Google Ads account with full per-action metadata. This tool retrieves READ-ONLY data. Safe to call multiple times. Returns for each conversion action: - id, name, resource_name - category (PURCHASE, SUBMIT_LEAD_FORM, SIGNUP, ADD_TO_CART, BEGIN_CHECKOUT, BOOK_APPOINTMENT, etc.) - status (ENABLED, REMOVED, HIDDEN) - type (WEBPAGE, UPLOAD_CLICKS, GOOGLE_ANALYTICS_4, FIREBASE_, etc.) - counting_type (ONE_PER_CLICK or MANY_PER_CLICK) - primary_for_goal (true if this action is primary for its category goal) - include_in_conversions_metric (true if it counts in Smart Bidding "Conversions") - click_through_lookback_window_days, view_through_lookback_window_days - value_settings: default_value, default_currency_code, always_use_default_value - attribution_model (GOOGLE_ADS_LAST_CLICK, DATA_DRIVEN, etc.) Parameters: - customer_id: Optional Google Ads customer ID (uses primary if omitted) - status_filter: 'ENABLED' (default — matches Google Ads UI active list), 'all' (include HIDDEN), or 'primary' (only primary_for_goal=true) - include_removed: false by default (matches Google Ads UI). Set true to include status=REMOVED for full audit. Execution time: 1-3 seconds (single GAQL query, cached 1 hour in Redis) Use this tool when: - User asks for conversion setup, conversion action list, or conversion tracking audit beyond a health-score summary - User wants per-action category, counting mode, or value settings to reason about ROAS / TARGET_ROAS bidding - User wants to see secondary or non-primary actions that audit_conversion_tracking truncates - Before any per-conversion-action analysis (downstream tools may need the action IDs) Tip:* For accounts with many actions (100+), status_filter='primary' returns just the goal-primary actions used by Smart Bidding — usually the most relevant subset.
list_google_languages
ChatGPTList Google Ads language constants. Returns the catalog of valid language resource names for target_languages in campaign creation tools. WHEN TO USE: Call this BEFORE campaign creation whenever the user requests a language that isn't obviously ISO-2 (e.g., user says "Brazilian Portuguese", "Swiss German", "Simplified Chinese"). Returns the correct languageConstants/<id> + the ISO code Google expects. Campaign creation tools accept ISO codes (e.g., 'en', 'pt-BR'), numeric IDs (1000), or full resource names (languageConstants/1000) — but the catalog here is authoritative. INPUT: optional search substring (searches both name and code), optional only_targetable (default true — excludes non-targetable legacy codes). Execution time: instant after first call. Redis-cached 24 hours.
list_labels
ChatGPTList the account's labels (for organizing and reporting on campaigns). Returns each label's id, name, and description. Use the id with add_campaign_label to tag a campaign, or with create_label to make a new one first.
list_meta_catalogs
ChatGPTUser wants to browse product catalogs for catalog / dynamic product ads (DPA / Advantage+ Catalog), or before creating a catalog campaign. Returns all product catalogs attached to the business behind the ad account (id, name, product_count, vertical). Workflow: 1. Call this to discover catalogs 2. Pass a catalog ID to list_meta_product_sets / list_meta_products / create_meta_product_set When to use: - "Show my product catalogs", "list my Shopify catalog" - Before creating a catalog / dynamic product / Advantage+ Catalog ad
list_meta_custom_audiences
ChatGPTUser wants to browse, list, or select Custom Audiences for targeting — DB lists, lookalike audiences, remarketing segments, website visitors, engagement audiences. Returns all Custom Audiences for the ad account with ID, name, type (subtype), approximate size, and delivery status. Workflow: 1. Call this tool to discover available custom audiences 2. Use audience IDs with campaign creation tools via custom_audiences parameter 3. Optionally use excluded_custom_audiences to exclude specific audiences When to use: - Before creating campaigns that need custom audience targeting - When user asks "which audiences do I have?" or "show me my lookalike audiences" - When setting up remarketing or DB-list campaigns
list_meta_instagram_accounts
ChatGPTUser wants to run ads on Instagram, asks about Instagram accounts, or you need to find the instagram_account_id before campaign creation. Returns Instagram accounts that are: 1. Authorized for ads on the ad account (from Business Manager) 2. Linked to Facebook Pages (from Page settings) Workflow: 1. Call this tool to discover available Instagram accounts 2. Use the Instagram account ID with campaign creation tools via instagram_account_id parameter When to use: - Before any campaign creation to enable Instagram placements - When user asks "which Instagram accounts can I use?" - When an Instagram association fails and user needs to find the right account
list_meta_lead_forms
ChatGPTUser wants to see their Meta lead generation forms, list lead forms, or find a lead form ID. Lists all lead generation forms for a Facebook Page associated with the ad account. When to use this tool: - "Show me my Meta lead forms" - "List my Facebook lead generation forms" - "What lead forms do I have?" - "Find my lead form ID" - "Show lead forms for my page" Returns per form: - Form name, status (ACTIVE/ARCHIVED), leads count - Creation date - Form questions (field names and types) - Form ID (needed for get_meta_lead_form_submissions and campaign creation with lead_form_id) Parameters: - page_id: Facebook Page ID (optional — auto-resolved from ad account if not provided) - ad_account_id: Required for multi-account users. Get from list_connected_accounts - limit: Maximum forms to return (default: 50) Note: Lead forms belong to Facebook Pages, not ad accounts. If you don't have the page_id, just omit it and the tool will auto-resolve from the ad account's promotable pages. Permission: Requires 'leads_retrieval' scope. If the user gets a permission error, they need to disconnect and reconnect their Meta account to grant the updated permissions. Execution time: 2-5 seconds Data source: Meta Marketing API (live)
list_meta_pages
ChatGPTUser wants to know which Facebook Page an ad will run from, or a create/add tool reported the account has 2+ Pages and you need to pick one. Returns every Facebook Page that can run ads on the ad account (id + name + any linked Instagram account). Workflow: 1. Call this tool to discover the account's promotable Pages. 2. Pass the chosen page's id to any Meta create/add tool via the facebook_page_id parameter. When to use: - When a create/add tool returns needs_page_disambiguation (the account has 2+ Pages and Meta has no default). - When the user asks "which Facebook Page will this run from?" or wants a specific Page. - Before creating a campaign on an account you know has multiple Pages, to choose deliberately rather than let it ask.
list_meta_pixels
ChatGPTUser wants conversion tracking, asks about Meta Pixels, or before creating OUTCOME_SALES campaigns. Returns all Meta Pixels for the ad account with their status and last fired time. Workflow: 1. Call this tool to discover available pixels 2. Use the pixel ID with campaign creation tools via pixel_id parameter 3. Optionally specify pixel_event_name (default: PURCHASE) When to use: - Before creating OUTCOME_SALES campaigns (pixel_id is required for conversion tracking) - When user asks "which pixels do I have?" - When setting up conversion tracking for campaigns
list_meta_product_sets
ChatGPTUser wants to see the product sets (groupings) inside a catalog, to choose which products a catalog ad should advertise. Returns product sets (id, name, product_count) for a catalog. The default 'All Products' set always exists. When to use: - "What product sets do I have?", "show the groups in my catalog" - After list_meta_catalogs, before creating a catalog ad
list_meta_products
ChatGPTUser wants to inspect the individual products in a catalog or product set (to confirm what will be advertised). Returns products (SKU/retailer_id, name, price, availability). Optionally scoped to a product set. When to use: - "What products are in my catalog?", "show items in the Footwear set" - To verify products before running a catalog ad
list_meta_promotable_apps
ChatGPTUser wants to run a Meta app-install / app-promotion campaign, or asks which mobile apps they can advertise. Returns the apps this ad account is allowed to promote, each with its numeric Facebook App ID and the App Store / Google Play URLs Meta already holds. ALWAYS call this BEFORE creating an OUTCOME_APP_PROMOTION campaign. The app_id Meta requires is the numeric FACEBOOK App ID — NOT an iOS bundle ID (com.example.app) or Android package name. Customers routinely guess it wrong and the campaign fails. Workflow: 1. Call this tool to discover promotable apps 2. Pass the returned app_id + matching app_store_url to a campaign creation tool with objective OUTCOME_APP_PROMOTION 3. OS targeting is derived from the store URL automatically — Meta rejects an ad set whose OS targeting disagrees with the promoted app When to use: - Before ANY app campaign creation (app_id + app_store_url are both required) - When the user asks "which apps can I advertise?" - When an app campaign failed with a promoted-object, app-setup, or "Mobile Targeting Mismatch" error Apps that have no App Store / Google Play listing are returned separately with an explanation — Meta cannot run an app campaign for a web-only or canvas app.
list_negative_keyword_lists
ChatGPTList the account's SHARED negative keyword lists. ⚠️ READ-ONLY. Safe to call repeatedly. A shared negative keyword list (Google "negative keyword list" / SharedSet) is a reusable set of negative keywords you can attach to many campaigns at once — unlike add_negative_keywords which adds negatives to ONE campaign only. This lists each list with its keyword count and how many campaigns it's attached to. Use when: "show my negative keyword lists", "what shared negative lists do I have?", before adding to or attaching a list.
meta_ads
ChatGPTAccess all Meta Ads (Facebook/Instagram) campaign management tools. Use action="list_tools" first to see available operations and their parameters. Then use action="execute" with the specific tool_name and arguments. Available capabilities: - Campaign Performance: Analyze metrics, audience insights, wasted spend, creative fatigue, anomaly detection - Campaign Creation: Image, video, carousel campaigns with asset discovery and validation - Campaign Management: Update settings, pause/resume, duplicate campaigns - Ad Management: Create/update ads, ad sets, DCO ads - Targeting: Search and browse targeting options, audience analysis - Placements: Optimize ad placements across Facebook, Instagram, Audience Network - Lead Forms: List forms, get submissions - Creatives: View ad creatives, detect creative fatigue ⚠️ Side effects & confirmation: Write operations change a live Meta (Facebook/Instagram) account. New campaigns are created PAUSED and must be explicitly confirmed by the user before launch. Budget and status changes (pause/resume) take effect immediately and can disrupt ad delivery. Lead-form tools retrieve personal contact data submitted by users. When to use this tool: - "How are my Meta/Facebook campaigns performing?" - "Create a new Facebook image ad campaign" - "Show me my Instagram ad performance" - "What audiences should I target on Meta?" - "Pause my underperforming Meta campaigns" Raw data mode (performance tools only): If the user asks for "raw data", "raw metrics", "just the numbers", "no recommendations", or "no commentary" — pass raw_data: true inside arguments when calling any performance tool (get_meta_campaign_performance, analyze_meta_ad_performance, get_meta_adset_performance, analyze_meta_wasted_spend, optimize_meta_budget, get_meta_audience_insights, detect_meta_creative_fatigue, optimize_meta_placements, explain_meta_anomaly, analyze_meta_audiences, get_meta_ad_creatives). You receive a JSON code block of metrics only: spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, ROAS, frequency, reach by campaign/ad/date. Severity labels, suggested bids, suggested budgets, industry benchmarks, and optimization recommendations are stripped. Default is false (full formatted analysis). Example — list tools: action: "list_tools" Example — get performance: action: "execute" tool_name: "get_meta_campaign_performance" arguments: {"lookback_days": 30} Example — raw performance (user asked for raw data): action: "execute" tool_name: "get_meta_campaign_performance" arguments: {"lookback_days": 30, "raw_data": true}
monitoring_and_reporting
ChatGPTAccess monitoring, scheduled reporting, and research tools. Use action="list_tools" first to see available operations and their parameters. Then use action="execute" with the specific tool_name and arguments. Available capabilities: - Scheduled Briefs: Set up daily/weekly performance reports delivered by email - Campaign Monitors: Create 24/7 alerts for metric thresholds (ROAS, CPA, spend, CTR) - Research Jobs: Launch async AI-powered research (competitor analysis, keyword research, market landscape) - Report Generation: Generate on-demand performance reports across all ad platforms - Task Management: List, manage, and review scheduled tasks, monitors, and pending actions ⚠️ Side effects & confirmation: Creating briefs, monitors, and reports schedules recurring jobs that send email notifications. Monitors and signal actions can recommend campaign changes and — when the user approves them — apply changes such as pausing campaigns or adjusting budgets, which disrupt live ad delivery. Deleting a monitor is irreversible. When to use this tool: - "Set up a daily performance brief" - "Alert me when ROAS drops below 2x" - "Research my competitors' ad strategies" - "Show me my scheduled tasks" - "Generate a report for last week" Example — list tools: action: "list_tools" Example — create a monitor: action: "execute" tool_name: "create_monitor" arguments: {"platform": "google_ads", "metric": "roas", "operator": "less_than", "threshold": 2.0}
optimize_budget_allocation
ChatGPTOptimize budget allocation across campaigns using linear programming to maximize conversions. ⚠️ IMPORTANT: This tool retrieves READ-ONLY optimization recommendations. Safe to call multiple times. Does NOT automatically change budgets. 🎯 What This Tool Does (Performance Agent - Phase 1): - Uses linear programming to optimize budget distribution - Maximizes total conversions while respecting constraints - Provides current vs optimized allocation comparison - Categorizes campaigns into actions: PAUSE/SCALE/REDUCE/MAINTAIN - Shows expected conversion lift from optimization - Generates specific recommendations with budget amounts Returns detailed optimization plan: - Current allocation (what you have now) - Optimized allocation (what you should have) - Expected conversion lift (absolute and percentage) - Campaign-by-campaign actions with reasoning - Budget change amounts and percentages - Specific implementation recommendations Optimization Algorithm: Uses scipy linear programming with constraints: 1. Sum of budgets = total_budget (you don't overspend) 2. Only campaigns with ROAS >= target get significant budget 3. Min budget per campaign >= min_daily_budget (or $0 to pause) 4. Max change per campaign <= ±max_change_percentage (avoid drastic shifts) Target ROAS Resolution (3-tier priority): 1. User override (if target_roas parameter provided) 2. Account goals table (user-set or API-pulled) 3. 90-day historical average ROAS 4. Default to 1.0x (breakeven) if no data Configuration Parameters: - total_budget: Total monthly budget to allocate (REQUIRED) - lookback_days: 7, 30, 60, 90, or 120 days (default: 30) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. - target_roas: Optional override (e.g., 3.0 for 3.0x) - max_change_percentage: 0.0-1.0 (default: 0.5 = ±50%) 0.3 = Conservative (±30% change, minimal disruption) 0.5 = Balanced (±50% change, standard optimization) 0.7 = Aggressive (±70% change, fast scaling) - min_daily_budget: Minimum $ per campaign (default: $5.00, or $0.00 to allow pausing) - customer_id: Optional (uses connected account if omitted) Execution time: 1-5 seconds (depends on campaign count) Data source: campaign_daily_metrics table (updated nightly) Use this tool when:* - User wants to optimize budget allocation - User asks "how should I allocate my budget?" - User wants to maximize conversions with current spend - User wants data-driven budget recommendations - After running wasted spend analysis (natural next step)
pause_campaign
ChatGPTQuickly pause a running campaign. Pausing a campaign stops all ads from showing immediately. This is REVERSIBLE using resume_campaign. Parameters: - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - customer_id: Optional (uses connected account if omitted) Execution time: 1-2 seconds Returns: - Campaign name - Before status (e.g., ENABLED) - After status (PAUSED) - Confirmation message When to use: - User says "pause the campaign", "stop the ads", "turn it off" - User wants to temporarily stop spending - User needs to make changes before ads continue Example: User: "Pause my summer sale campaign" Agent: Uses pause_campaign with the campaign_id
remove_asset_group_listing_filter
ChatGPTRemove a listing-filter node (and its whole subtree) from a retail-PMax asset group. Get the filter_id from get_asset_group_listing_filters. Removing a subdivision removes everything under it. Remove the root to return the asset group to promoting ALL feed products. Required: asset_group_id, filter_id.
remove_callouts
ChatGPTRemove callout extensions from a campaign. Unlinks callouts from THIS campaign. The underlying Asset stays in your account and can be re-linked elsewhere. Why this matters: - Old callouts containing words like "Doctor Reviewed" / "Medical" / "Clinical" can flag a campaign for policy issues - Stale promotional callouts (e.g. "Summer Sale 2024") look bad to users - Must remove old callouts before fresh ones take their place Parameters: - campaign_id: Campaign whose callouts to remove (REQUIRED) - asset_ids: Optional list of asset IDs (or full resource_names) to remove specifically. Get IDs from list_campaign_extensions. If omitted, ALL callouts on this campaign are removed. - customer_id: Optional (uses connected account if omitted) Workflow: 1. Call list_campaign_extensions(campaign_id) to see what's currently linked 2. Identify which callouts to remove by their asset_id or text 3. Call this tool with those asset_ids (or omit to clear ALL) 4. Use add_callout_extensions to add fresh ones if needed Example: User: "Remove all my callouts and add new ones" Agent: 1. Confirms: "I'll remove all 4 current callouts and let you add new ones. Proceed?" 2. Calls remove_callouts(campaign_id) — clears all 3. Then add_callout_extensions with new list
remove_campaign
ChatGPTPermanently remove (delete) a campaign — sets its status to REMOVED. ⚠️ This is PERMANENT and CANNOT be undone (a removed campaign cannot be re-enabled — use pause_campaign if you only want to stop it temporarily). All of the campaign's ad groups and ads are removed with it. Required: campaign_id (from list_campaigns). When to use: the user explicitly wants to delete / get rid of / permanently remove a campaign. For "stop"/"turn off"/"pause", use pause_campaign instead.
remove_campaign_label
ChatGPTDetach a label from a campaign (removes the tag; the label itself is not deleted). Get the label_id from get_campaign_labels. Required: campaign_id + label_id.
remove_display_ad
ChatGPTRemove (soft-delete) a Responsive Display Ad. Sets the AdGroupAd status=REMOVED. The ad stops serving but historical reporting is preserved. Cannot be undone via the API. Parameters: ad_group_id (REQUIRED), ad_id (REQUIRED) Execution time: 2-4 seconds.
remove_display_ad_group
ChatGPTRemove (soft-delete) a Display ad group. Google's API does not support hard deletion — this sets status=REMOVED, which stops serving but preserves historical data for reporting. Cannot be undone via the API. Parameters: ad_group_id (REQUIRED) Execution time: 2-4 seconds.
remove_display_criteria
ChatGPTRemove one or more AdGroupCriteria from a Display ad group by resource name. Works for ANY criterion type — placements, topics, audiences, display keywords, demographic exclusions. How to get resource names: use any of the get_display_* tools — each entry has ad_group_id and criterion_id. Construct the resource name as: customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id} Example: `` criterion_resource_names: [ "customers/5835090207/adGroupCriteria/197350763433~123456789" ] `` Execution time: 2-5 seconds (destructive — cannot be undone).
remove_product_group
ChatGPTRemove a product-group node from a Shopping ad group's tree (and its subtree). Get the criterion_id from get_product_groups. Removing a subdivision removes everything under it. Required: ad_group_id, criterion_id.
remove_sitelinks
ChatGPTRemove sitelink extensions from a campaign. Unlinks sitelinks from THIS campaign. The underlying Asset stays in your account and can be re-linked elsewhere. Why this matters: - Old policy-violating sitelinks keep serving until removed - Stale URLs / outdated promotional copy must be removed before adding new ones - A campaign can only show 8 sitelinks max — must remove older ones to make room Parameters: - campaign_id: Campaign whose sitelinks to remove (REQUIRED) - asset_ids: Optional list of asset IDs (or full resource_names) to remove specifically. Get IDs from list_campaign_extensions. If omitted, ALL sitelinks on this campaign are removed. - customer_id: Optional (uses connected account if omitted) Workflow: 1. Call list_campaign_extensions(campaign_id) to see what's currently linked 2. Identify which sitelinks to remove by their asset_id or text 3. Call this tool with those asset_ids (or omit to clear ALL) 4. Use add_sitelinks to add fresh ones if needed Example: User: "Remove the old sitelinks from my Krav Maga campaign — they have outdated promo copy" Agent: 1. list_campaign_extensions → shows 4 sitelinks with their asset_ids 2. Confirms: "I'll remove sitelinks 'Free Trial' and 'Summer Sale 2024'. Proceed?" 3. Calls remove_sitelinks(campaign_id, asset_ids=['12345', '67890'])
remove_structured_snippets
ChatGPTRemove structured snippet extensions from a campaign. Unlinks structured snippets from THIS campaign. The underlying Asset stays in your account and can be re-linked elsewhere. Why this matters: - Stale snippet headers/values (e.g. last season's "Styles" or discontinued "Brands") look bad to users - Must remove old snippets before fresh ones take their place - The sibling of add_structured_snippets — completes the add/remove pair (like remove_sitelinks / remove_callouts) Parameters: - campaign_id: Campaign whose structured snippets to remove (REQUIRED) - asset_ids: Optional list of asset IDs (or full resource_names) to remove specifically. Get IDs from list_campaign_extensions. If omitted, ALL structured snippets on this campaign are removed. - customer_id: Optional (uses connected account if omitted) Workflow: 1. Call list_campaign_extensions(campaign_id) to see what's currently linked 2. Identify which snippets to remove by their asset_id 3. Call this tool with those asset_ids (or omit to clear ALL) 4. Use add_structured_snippets to add fresh ones if needed Example: User: "Remove the old structured snippets from my campaign" Agent: 1. list_campaign_extensions → shows current structured snippets with asset_ids 2. Confirms: "I'll remove all structured snippets. Proceed?" 3. Calls remove_structured_snippets(campaign_id)
research_keywords
ChatGPTResearch high-intent keywords using Google Keyword Planner API. ⚠️ IMPORTANT: This is a READ-ONLY tool. Safe to call multiple times. 🎯 What This Tool Does: - Researches keywords via Google Keyword Planner API - Returns keywords with real CPC data, search volume, and competition metrics - Groups keywords by commercial intent (HIGH/MEDIUM/LOW based on dynamic CPC thresholds) - Selects top 15-20 keywords optimized for conversions - Provides budget recommendations based on actual keyword costs When to Use: - BEFORE creating a Google Search campaign - When you need data-driven keyword insights - To understand keyword costs and search volume - To get budget recommendations Parameters: - business_description (required): What the business sells/offers - website_url (optional): Business website for better keyword suggestions - target_location (optional): Geographic target (default: "United States") - language (optional): 'de' / 'German' / '1001' — defaults to the language the account's campaigns target (auto-detected), falling back to English. For non-English seeds, location AND language should match (e.g. German seeds → target_location "Germany" + language auto/de). - seed_keywords (optional): 5-10 seed keywords (will auto-extract if not provided) - customer_id (optional): Google Ads account ID Returns: - Keyword table with dynamic CPC thresholds (adapts to any industry) - HIGH/MEDIUM/LOW intent grouping - Budget recommendations (Conservative/Moderate/Aggressive) - Top 15-20 recommended keywords for campaign Execution time: 3-8 seconds (calls live Google Ads API) 📊 Example Usage: 1. User: "I want to create a campaign for my plumbing business" 2. YOU call: research_keywords with business_description="Emergency plumbing services" 3. Tool returns: Keyword table with 100+ keywords, 20 recommended, budget suggestions 4. YOU show user: The keyword table and ask if they want modifications 5. User approves or requests changes 6. YOU call: create_search_campaign with approved keywords 💡 Dynamic Thresholds: This tool automatically adapts CPC thresholds to any industry: - Plumbing: HIGH ≥$6, MEDIUM $3-6, LOW <$3 - Legal: HIGH ≥$95, MEDIUM $45-95, LOW <$45 - E-commerce: HIGH ≥$2, MEDIUM $0.50-2, LOW <$0.50 All keywords returned will use BROAD match (Google's 2025 recommendation with Smart Bidding).
resolve_google_locations
ChatGPTResolve free-text location queries (country, state/province, city, district, postal code) into Google's exact geoTargetConstants/<id> resource names. WHEN TO USE: Call this tool BEFORE create_display_campaign, create_search_campaign, create_pmax_campaign, or create_demandgen_campaign whenever the user requests targeting by location. This gets you the precise geoTargetConstants/<id> values the Google Ads API accepts — eliminating ambiguity (e.g., "London" could be London UK, Londonderry, or London Ontario). INPUT: JSON array of free-text queries, optional locale + country_code filter. OUTPUT: For each query, up to N candidate geoTargetConstants with canonical_name, target_type (Country/State/City/District/etc.), country_code, reach estimate. The AI client picks the right ID and passes it to the campaign-creation tool. WORKFLOW EXAMPLE: 1. User says "target London and California" 2. Call resolve_google_locations with queries: ["London","California"] 3. Disambiguate with the user if multiple candidates exist (e.g., London UK vs London Ontario) 4. Pass chosen resource names (e.g., ["geoTargetConstants/1006886","geoTargetConstants/21137"]) as target_locations to the campaign-creation tool. Display campaign creation accepts BOTH formats (free-text OR resource names / bare IDs) but the API is most reliable with pre-resolved IDs. Execution time: 1-3 seconds. Redis-cached 5 minutes.
resume_campaign
ChatGPTResume a paused campaign. Resuming a campaign makes ads start showing again. Only works on PAUSED campaigns (not REMOVED). Parameters: - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - customer_id: Optional (uses connected account if omitted) Execution time: 1-2 seconds Returns: - Campaign name - Before status (e.g., PAUSED) - After status (ENABLED) - Confirmation message When to use: - User says "resume", "turn it back on", "start it again" - User wants to re-enable a paused campaign - User finished making changes and wants ads to run Example: User: "Turn my campaign back on" Agent: Uses resume_campaign with the campaign_id
save_business_profile
ChatGPTSave or update the user's business profile with provided details. ⚠️ IMPORTANT: This tool WRITES data. Use when user confirms their business profile. 🎯 What This Tool Does (Performance Agent - Phase 1 Feature 5): - Saves user's business profile to database - Updates existing profile if one exists - Sets profile source as 'user_confirmed' or 'user_mcp' - Enables personalized recommendations going forward Required Parameters: - business_vertical: retail, services, technology, healthcare, finance, education, travel, food_beverage, automotive, real_estate - business_size: small (<$50K/month), medium ($50K-$500K/month), large (>$500K/month) - primary_goal: leads, sales, awareness, traffic, engagement, app_installs Optional Parameters: - target_audience: Free-text description (e.g., "B2B enterprise clients") - geographic_focus: local, regional, national, international - seasonality: none, holiday_heavy, summer_peak, winter_peak, q4_heavy, back_to_school - customer_id: Optional (uses connected account if omitted) Use this tool when: - User provides their business details - User confirms an inferred profile - User wants to update their business profile - After asking user clarifying questions about their business Example Usage: User: "I run a small local plumbing business targeting homeowners" → Call save_business_profile with: - business_vertical: "services" - business_size: "small" - primary_goal: "leads" - target_audience: "homeowners" - geographic_focus: "local" Execution time: 1-2 seconds (database write)
search_meta_targeting
ChatGPTUser wants to find targeting options for their Meta (Facebook/Instagram) ad campaigns. This tool searches the Meta Marketing API to find targeting options including interests, behaviors, demographics, locations, and more. Returns: - List of targeting options with IDs, names, and audience sizes - Category/path information for interests and behaviors - Location details including country, region for geo-targeting When to use this tool: - "Find interests related to fitness" - "What targeting options are available for travel?" - "Search for locations in California" - "Find behaviors for online shoppers" - "What demographics can I target?" - "Find job titles for marketing professionals" - "Search for schools like Harvard" Search Types Available: - interest: Topics and activities (e.g., 'fitness', 'cooking', 'travel') - behavior: User behaviors (e.g., 'frequent travelers', 'online shoppers') - demographic: Demographics (e.g., 'new parents', 'college educated') - life_event: Life events (e.g., 'recently moved', 'newly engaged') - location: Geo-targeting (e.g., 'New York', 'California', '90210') - locale: Language targeting (e.g., 'Spanish', 'French') - employer: Employer targeting (e.g., 'Google', 'Microsoft') - job_title: Job title targeting (e.g., 'Software Engineer') - school: Education school targeting (e.g., 'Harvard', 'Stanford') - major: Education major targeting (e.g., 'Computer Science') Parameters: - search_type: Type of targeting to search (required) - query: Search query string (required) - limit: Maximum results (1-100, default: 50) - locale: Locale for results (default: en_US) - location_types: For location search - filter by types (country, region, city, zip) - country_code: For location search - filter by country (e.g., 'US') - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds Data source: Meta Marketing API Targeting Search
search_tools
ChatGPTFind the right Adspirer tool(s) for a task by describing what you want to do in natural language. Returns the best-matching tool names with a one-line summary — then call get_tool_schema with a name to get its exact parameters before calling it. Use this instead of guessing tool names. Optionally filter by platform (google-ads, meta-ads, tiktok-ads, linkedin-ads, amazon-ads, chatgpt-ads).
select_google_campaign_type
ChatGPTUSE THIS TOOL FIRST WHEN: User wants to create a Google Ads campaign but hasn't specified the campaign type. IMPORTANT: Call BEFORE any keyword research, asset discovery, or campaign creation when the user says things like: - "Create a Google Ads campaign" - "I want to run Google Ads" - "Set up a Google advertising campaign" - "Help me create ads on Google" - "Create a campaign" - "Run ads" This tool guides the user to select their campaign TYPE, then returns a step-by-step workflow with which tools to call next. Campaign Types Available: 1. search — Text ads in Google Search results (best for high-intent keywords, lead gen, local services) 2. pmax — Performance Max across all Google channels (best for ecommerce, brand awareness, multi-channel reach) 3. youtube — Video ads on YouTube (best for video content, brand storytelling, product demos) 4. demandgen — Demand Gen across YouTube + Gmail + Discover + Display (best for cross-channel mid-funnel) 5. display — Responsive Display Ads on the Google Display Network (GDN) — banner placements on millions of websites, apps, and YouTube display slots. Smart Display (smart_display=true) is a Google-managed variant within this type. Returns: step-by-step workflow, requirements, and a natural follow-up question for the chosen type. Do NOT use this tool if: - User specifically asks for "search campaign" or "text ads" → go directly to research_keywords then create_search_campaign - User specifically asks for "PMax" or "Performance Max" → go directly to discover_existing_assets then create_pmax_campaign - User specifically asks for "YouTube campaign" or "video campaign" → go directly to validate_video then create_youtube_campaign - User specifically asks for "Demand Gen" → go directly to create_demandgen_campaign - User specifically asks for "Display campaign", "banner ads", or "GDN" → go directly to create_display_campaign - User is asking about performance/analytics → use get_campaign_performance - User is asking about existing campaigns → use list_campaigns Parameters: - campaign_type: 'search' | 'pmax' | 'youtube' | 'demandgen' | 'display' Execution time: Instant (no API call)
start_here
ChatGPTShow the user where to start and what to try next with Adspirer — a visual 'first wins' guide personalized to their connected platforms, real account data, and what they've already done. Call this when: - A user has just connected Adspirer (first session, few or no tool calls yet) - The user asks "what can you do?", "where do I start?", "what should I try?", or anything about Adspirer's capabilities - The user seems unsure what to do next Free — never counts against the user's quota. Renders an interactive getting-started card; the text fallback lists the same steps.
switch_primary_account
ChatGPTActivate ad accounts for a platform. Two modes: 1. account_id (singular) — ADDS this account to the active set. Other already-active accounts stay active. Safe to call multiple times to activate accounts one by one. 2. account_ids (plural, list) — REPLACES the full active set with this exact list. Any account NOT in the list becomes inactive. Use this only when the user explicitly wants to set a specific group of accounts as the complete active set (e.g., "only use accounts A, B, C"). Use this tool when: - User wants to activate a different ad account (use account_id — singular) - User wants to activate multiple specific accounts (use account_ids — plural) - User says "also use my other account" (use account_id — additive) - User says "only use accounts X, Y" (use account_ids — replace) Get account IDs from list_connected_accounts. IMPORTANT: Returns updated connections list after activation.
tiktok_ads
ChatGPTAccess all TikTok Ads campaign management tools. Required first step: call this tool with action: "list_tools" (no other fields). Then call again with action: "execute", a specific tool_name from that list, and arguments. Calling action: "execute" without tool_name is INVALID and will return an error — do not retry the same broken call (issue #297 Bug G). Available capabilities: - Campaign Performance: Analyze metrics, wasted spend, budget optimization, creative fatigue, audience and geo insights, anomaly detection - Asset Discovery: Find existing TikTok images and videos to reuse - Asset Validation: Validate and prepare images/videos for TikTok ad specs - Campaign Creation: Create image-based and video-based TikTok ad campaigns, plus ad groups, ads, and carousel cards - Campaign Management: List campaigns/ad groups/ads, update settings and budgets, pause/resume, and delete campaigns/ad groups/ads - Targeting: Search TikTok targeting options ⚠️ Side effects & confirmation: Write operations change a live TikTok Ads account. New campaigns are created PAUSED and must be explicitly confirmed by the user before launch. Budget and status changes (pause/resume) take effect immediately and can disrupt ad delivery. Deleting a campaign, ad group, or ad is irreversible. When to use this tool: - "Create a new TikTok ad campaign" - "Show me my existing TikTok assets" - "Create a TikTok video campaign" - "Validate my images for TikTok ads" - "How are my TikTok campaigns performing?" Raw data mode (performance tools only): If the user asks for "raw data", "raw metrics", "just the numbers", "no recommendations", or "no commentary" — pass raw_data: true inside arguments when calling any performance tool (get_tiktok_campaign_performance, get_tiktok_ad_performance, analyze_tiktok_wasted_spend, optimize_tiktok_budget, detect_tiktok_creative_fatigue, explain_tiktok_anomaly, get_tiktok_audience_insights, analyze_tiktok_geo_performance). You receive a JSON code block of metrics only: spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, ROAS, hook rate, video completion rate, engagement rate by campaign/ad/date. Severity labels, suggested bids, suggested budgets, industry benchmarks, and optimization recommendations are stripped. Default is false (full formatted analysis). Example — list tools: action: "list_tools" Example — create campaign: action: "execute" tool_name: "create_tiktok_campaign" arguments: {"campaign_name": "Summer Sale", "objective": "CONVERSIONS"} Example — raw performance (user asked for raw data): action: "execute" tool_name: "get_tiktok_campaign_performance" arguments: {"lookback_days": 30, "raw_data": true}
unlink_merchant_center
ChatGPTRemove a Merchant Center link from this Google Ads account. Detaches the Merchant Center account; Shopping campaigns relying on it will stop serving. The Merchant Center account itself is not deleted. Get the merchant_center_id from get_merchant_center_links. Required: merchant_center_id.
update_bid_strategy
ChatGPTChange campaign bidding strategy. Available Strategies: - MAXIMIZE_CLICKS: Get as many clicks as possible within budget (optional cpc_bid_ceiling = max CPC cap) - MAXIMIZE_CONVERSIONS: Get as many conversions as possible - TARGET_CPA: Set a target cost per acquisition (requires target_cpa) - TARGET_ROAS: Set a target return on ad spend (requires target_roas) - TARGET_IMPRESSION_SHARE: Bid to appear for a target share of auctions at a chosen page position (requires impression_share_location + impression_share_target_percent) Parameters: - campaign_id: The campaign ID (REQUIRED) - strategy: one of the strategies above (REQUIRED) - target_cpa: Required if strategy is TARGET_CPA. In dollars, e.g., 25.00 for $25 CPA - target_roas: Required if strategy is TARGET_ROAS. Multiplier, e.g., 4.0 for 400% ROAS - impression_share_location: Required if strategy is TARGET_IMPRESSION_SHARE. ABSOLUTE_TOP_OF_PAGE, TOP_OF_PAGE, or ANYWHERE_ON_PAGE - impression_share_target_percent: Required if strategy is TARGET_IMPRESSION_SHARE. 1-100, e.g., 80 for 80% - cpc_bid_ceiling: Max CPC cap. Used with MAXIMIZE_CLICKS or TARGET_IMPRESSION_SHARE. In the ACCOUNT'S currency (not cents, not USD; for 8.00 send 8). Optional — omit to keep an existing ceiling; STRONGLY recommended on TARGET_IMPRESSION_SHARE. Not accepted on other strategies - customer_id: Optional (uses connected account if omitted) IMPORTANT: - TARGET_CPA requires conversion tracking to be set up - TARGET_ROAS requires conversion value tracking - TARGET_IMPRESSION_SHARE is for visibility goals (Search/Display); set cpc_bid_ceiling so bids don't run away chasing the target - This changes the bidding on a LIVE campaign immediately — review the values (especially the CPC ceiling and target %) before moving on - The response shows the ceiling READ BACK from Google ("Max CPC ceiling: …"); if it says "not set", the cap did not save — do not tell the user it did. list_campaigns / get_campaign_structure also report the ceiling - Changing strategy may take 1-2 weeks to stabilize performance - Confirm with user before changing Execution time: 2-4 seconds Examples: User: "I want to target $30 CPA" Agent: Uses update_bid_strategy with strategy=TARGET_CPA, target_cpa=30.00 User: "Target absolute top of page, 80% impression share, max CPC $4" Agent: Uses update_bid_strategy with strategy=TARGET_IMPRESSION_SHARE, impression_share_location=ABSOLUTE_TOP_OF_PAGE, impression_share_target_percent=80, cpc_bid_ceiling=4.00 User: "Maximize clicks but never pay more than CA$8 a click" Agent: Uses update_bid_strategy with strategy=MAXIMIZE_CLICKS, cpc_bid_ceiling=8 (account currency is CAD, so 8 means CA$8.00)
update_campaign
ChatGPTUpdate an existing campaign's settings. Can update: - name: Campaign name - status: ENABLED or PAUSED - budget_amount: Daily budget in dollars - target_search_network: Search Partners toggle (Search campaigns) - target_content_network: Display Network expansion (Search campaigns) - language_codes: Replace language targeting (e.g. ["en"] for English-only). As of Sept 2026 this no longer applies to SEARCH campaigns (Google matches on ad language); still honored for Performance Max. A safe no-op on Search — nothing changes and you get a note explaining why. - locations_to_add: Append locations to geo targeting (free text or geoTargetConstants/<id>) - locations_to_remove: Remove locations by criterion resource name (get from get_campaign_targeting) - audience_targeting_mode: OBSERVATION vs TARGETING for audience signals - ai_max_enabled: Google AI Max toggle on Search campaigns IMPORTANT: - Confirm with user BEFORE making changes - Use list_campaigns first to get campaign_id - At least one update field is required - For locations_to_remove, you MUST call get_campaign_targeting first to obtain the criterion resource names — free-text location names will not work for removal. Parameters: - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - name: New campaign name (optional) - status: ENABLED or PAUSED (optional) - budget_amount: Daily budget in dollars, e.g., 50.00 for $50/day (optional) - target_search_network / target_content_network: bools (optional) - language_codes: list[str] (optional, REPLACES current set) - locations_to_add / locations_to_remove: list[str] (optional) - audience_targeting_mode: OBSERVATION | TARGETING (optional) - ai_max_enabled: bool (optional) - customer_id: Optional (uses connected account if omitted) Execution time: 2-6 seconds depending on number of targeting changes Example: User: "Increase the budget to $100/day and target English-only" Agent: 1. Uses list_campaigns to find the campaign 2. Confirms: "I'll update 'Summer Sale' budget to $100/day and set language to English-only. Proceed?" 3. Uses update_campaign(campaign_id=..., budget_amount=100.00, language_codes=["en"])
update_campaign_dates
ChatGPTSet a campaign's start and/or end date. Works on ANY campaign type (Search, PMax, Demand Gen, Display). Dates are 'YYYY-MM-DD'. Pass either or both. Setting an end_date stops the campaign after that day; omit end_date to leave it open-ended. Use get_campaign_dates to see current values first. Required: campaign_id + at least one of start_date / end_date.
update_campaign_frequency_caps
ChatGPTSet a campaign's frequency caps — limit how often a user sees the ads. Works on ANY campaign type. This REPLACES the full set of caps (send the complete desired list; pass [] to remove all caps). Each cap: {level: CAMPAIGN|AD_GROUP|AD_GROUP_AD, event_type: IMPRESSION|VIDEO_VIEW, time_unit: DAY|WEEK|MONTH, time_length: 1-365, cap: >=1}. Use get_campaign_frequency_caps first. Example — cap at 3 impressions per user per day: [{"level":"CAMPAIGN","event_type":"IMPRESSION","time_unit":"DAY","time_length":1,"cap":3}] Required: campaign_id + frequency_caps (list).
update_display_ad_creative
ChatGPTEdit any combination of CREATIVE fields on a Responsive Display Ad. Complements update_ad_content (which handles headlines / descriptions / long_headline / final_urls). This tool handles EVERYTHING ELSE on the RDA. Text fields: - business_name (max 25) - main_color / accent_color (hex e.g. '#FFAABB') - allow_flexible_color (bool) - price_prefix (max 10) - promo_text (max 20) - call_to_action (enum label like SHOP_NOW, LEARN_MORE, or free-form ≤30 chars) - format_setting (ALL_FORMATS | NATIVE | NON_NATIVE) Image + video fields (REPLACE the entire list when provided — you may supply both URL objects to upload AND existing asset resource names to reuse; they're merged): - marketing_images: landscape 1.91:1 URLs to upload - square_marketing_images: square 1:1 URLs - logo_images: landscape 4:1 logos - square_logo_images: square 1:1 logos - youtube_video_ids: list of YouTube IDs - existing_*_images: reuse existing asset resource names (from discover_existing_assets) Workflow tip — to add images WITHOUT replacing: first call get_campaign_structure or discover_existing_assets to get the current resource names, then pass them as existing_*_images AND your new ones as marketing_images. The service merges them. At least one field must be provided. Any omitted field is not touched. Execution time: 4-10 seconds (includes image uploads if any).
update_display_ad_group
ChatGPTUpdate one or more editable settings on a Display ad group in a single API call. At least one of the following must be provided. Any field omitted is not touched. Fields: - name: New ad group name (string) - status: ENABLED | PAUSED | REMOVED (REMOVED is a soft-delete — use remove_display_ad_group for clarity) - cpc_bid: Max CPC in account currency (MANUAL_CPC campaigns) - cpm_bid: Max viewable CPM in account currency (MANUAL_CPM campaigns) - ad_rotation_mode: OPTIMIZE (Google picks best ad) | ROTATE_FOREVER (even rotation) - optimized_targeting_enabled: Let Google expand targeting beyond your chosen audiences Note: exclude_demographic_expansion is Search-only and not editable on Display. Execution time: 2-4 seconds.
update_display_campaign_schedule
ChatGPTUpdate a Display campaign's start_date and/or end_date. Pass either or both dates as 'YYYY-MM-DD' (or compact 'YYYYMMDD'). You must provide at least one. Notes: - Google does NOT support un-setting start/end dates via the API. To effectively run "forever", set end_date to a far-future date (e.g., 2099-12-31). - Updating start_date after the campaign has already started is a no-op. Execution time: 2-4 seconds.
update_display_demographics
ChatGPTUpdate demographic targeting on a Display ad group via the exclude-the-inverse pattern. This tool adds NEGATIVE criteria for every demographic value NOT in your target list. It does NOT remove prior negative criteria — use remove_display_criteria if you want to clear old exclusions first. Input keys (all optional — only groups you pass are modified): - age_ranges: subset of AGE_RANGE_18_24, AGE_RANGE_25_34, AGE_RANGE_35_44, AGE_RANGE_45_54, AGE_RANGE_55_64, AGE_RANGE_65_UP, AGE_RANGE_UNDETERMINED - genders: subset of MALE, FEMALE, UNDETERMINED - parental_statuses: subset of PARENT, NOT_A_PARENT, UNDETERMINED - income_ranges: subset of INCOME_RANGE_0_50, INCOME_RANGE_50_60, INCOME_RANGE_60_70, INCOME_RANGE_70_80, INCOME_RANGE_80_90, INCOME_RANGE_90_UP, INCOME_RANGE_UNDETERMINED Example — target women aged 25-44 only: `` demographics: { "age_ranges": ["AGE_RANGE_25_34","AGE_RANGE_35_44"], "genders": ["FEMALE"] } `` Execution time: 2-5 seconds.
update_display_frequency_caps
ChatGPTREPLACE all frequency caps on a Display campaign. Google requires sending the full desired set each time — partial updates are not supported. Pass [] to remove ALL caps. Each entry: - level: CAMPAIGN | AD_GROUP | AD_GROUP_AD - event_type: IMPRESSION | VIDEO_VIEW - time_unit: DAY | WEEK | MONTH - time_length: 1-365 (number of time_unit periods) - cap: ≥ 1 (max events per user in that window) Examples: - 3 impressions/day: [{level:CAMPAIGN, event_type:IMPRESSION, time_unit:DAY, time_length:1, cap:3}] - 10 impressions/week + 2/day: two entries in the list - Clear all caps: [] Execution time: 2-5 seconds.
update_location_targeting
ChatGPTChange a campaign's location-targeting MODE without recreating the campaign. This is the "Presence vs Presence-or-Interest" toggle. It controls who sees ads inside the campaign's existing location list — it does NOT change the location list itself (use targeting tools for that). Modes: - PRESENCE (recommended for performance): People physically in or regularly in the targeted locations - PRESENCE_OR_INTEREST (Google's default): People in OR interested in the locations (broader; can waste budget on out-of-area users) - SEARCH_INTEREST: People searching for the location (Search campaigns only) When to use: - Customer says "my ads are showing to people not in my target area" → switch to PRESENCE - Local-only business (medical, restaurants, services) → PRESENCE - Brand-awareness or interest-based reach → keep PRESENCE_OR_INTEREST Channel-type rules (auto-enforced): - Display: rejects negative=PRESENCE_OR_INTEREST. Tool auto-defaults negative to PRESENCE if omitted. - Display: rejects positive=SEARCH_INTEREST. - Search/PMax: all combinations supported. Parameters: - campaign_id: Campaign to update (REQUIRED) - positive_geo_target_type: PRESENCE, PRESENCE_OR_INTEREST, or SEARCH_INTEREST (REQUIRED) - negative_geo_target_type: PRESENCE or PRESENCE_OR_INTEREST (OPTIONAL — leave existing untouched if omitted, except Display where we force PRESENCE) Example: User: "My Display campaign is showing to people not in my city, fix it." Agent: 1. Confirms: "I'll switch the location targeting to 'People physically in your locations' (PRESENCE). Proceed?" 2. Calls update_location_targeting(campaign_id, positive_geo_target_type='PRESENCE')
update_meta_catalog_ad
ChatGPTUser wants to edit/change an existing catalog AD — rename, pause/activate, swap to another creative, or change the copy/headline/description/CTA/landing/product-set (Meta rebuilds the creative since creatives are immutable). Only the fields you pass change.
update_meta_catalog_ad_set
ChatGPTUser wants to edit/change an existing catalog AD SET — deep control: budget, bid amount/strategy, optimization goal, full targeting (geo/age/gender/interests/behaviors/custom audiences/placements), schedule/dayparting, frequency caps, attribution, destination. PLUS catalog-specific: swap the product set, change the conversion event, or change the RETARGETING window/events (rebuilds the product audience). Only the fields you pass change.
update_meta_catalog_campaign
ChatGPTUser wants to edit/change an existing Advantage+ Catalog CAMPAIGN — rename, pause/activate/archive, change budget (CBO), spend cap, bid strategy, schedule, special ad categories, or swap the catalog. Only the fields you pass are changed.
update_product_group
ChatGPTChange the max CPC bid on a biddable product-group (UNIT) node. Get the criterion_id from get_product_groups. Only biddable UNIT leaves have a bid (SUBDIVISION branches and excluded nodes do not). Required: ad_group_id, criterion_id, bid_micros.
validate_catalog_readiness
ChatGPTUser wants to create Advantage+ Catalog / Dynamic Product Ads, or asks "is my catalog ready for ads?". Run this PRE-FLIGHT before setting up a catalog campaign. Aggregates the real signals that decide whether dynamic product ads will actually deliver: - Catalog exists and has products - Product set (if given) is non-empty - Sampled products have images (catalog ads render the product image — no image = no render) - Feed health (last-upload errors), best-effort - If a pixel_id is given: classifies RETARGETING readiness (needs ViewContent/AddToCart) vs PROSPECTING-only Returns an overall verdict (ready / ready_with_warnings / not_ready), explicit blockers, warnings, and a recommended audience strategy. Always prefer this before catalog campaign creation so we never launch a dead retargeting campaign. When to use: - "Create a catalog ad", "set up dynamic product ads", "advantage+ catalog" - "Is my product catalog ready to advertise?"
validate_video
ChatGPTValidate video for ad campaigns (unified tool for all platforms). ⚠️ IMPORTANT: This is a READ-ONLY validation tool. Safe to call multiple times. 🎯 What This Tool Does: - Validates videos for Google Ads PMAX or TikTok campaigns - For PMAX: Validates YouTube video (privacy, duration, embeddable) - For TikTok: Validates public video URL is accessible - Returns metadata (title, duration, privacy, thumbnail) DOES NOT upload videos - user must already have video uploaded: - PMAX: Video must be on YouTube (public or unlisted) - TikTok: Video must be on public hosting (Google Drive, Vimeo, etc.) Parameters: - video_url_or_id (required): YouTube URL/ID (PMAX) or public video URL (TikTok) - platform (required): 'pmax' or 'tiktok' For PMAX: Accepts YouTube formats: - Full URL: https://youtube.com/watch?v=dQw4w9WgXcQ - Short URL: https://youtu.be/dQw4w9WgXcQ - Shorts: https://youtube.com/shorts/dQw4w9WgXcQ - Direct ID: dQw4w9WgXcQ (11 characters) Validates: - Video exists and is accessible - Privacy is Public or Unlisted (NOT Private) - Embeddable is enabled - Duration ≥10 seconds (PMAX requirement) Returns: - Video title - Duration - Privacy status - Thumbnail URL - Video ID For TikTok: Accepts public video file URLs: - Google Drive: https://drive.google.com/file/d/ABC123/view - Vimeo: https://vimeo.com/video/123456 - Dropbox: https://dropbox.com/s/abc/video.mp4 - Any publicly accessible video URL Validates: - URL is accessible (HTTP 200) - Content-Type is video/ (when available) Returns: - URL validation status - Content-Type - File size (if available) Execution Time: 1-3 seconds (YouTube Data API call or HTTP request) When to Use: - BEFORE creating a campaign with videos - To verify video meets platform requirements - To get video metadata (title, duration) Example Usage: ``` User: "I want to use this YouTube video in my PMAX campaign: dQw4w9WgXcQ" YOU: [Call validate_video with video_url_or_id="dQw4w9WgXcQ", platform="pmax"] Response: Video validated, title="Product Demo", duration=45s, ready for use ``` ``` User: "Can I use this video for TikTok ads: https://drive.google.com/file/d/ABC/view" YOU: [Call validate_video with video_url_or_id="https://drive...", platform="tiktok"] Response: URL validated, accessible, ready for campaign ``` Error Handling:* - Private videos: Clear error asking user to change privacy to Public/Unlisted - Short videos (<10s for PMAX): Error with duration requirement - Invalid URLs: Error with accessibility details - Not embeddable: Error asking user to enable embedding