Camberstack
Connect AI to Google Ads (plus optional Search Console and GA4) to read account data, research keywords, propose and apply approved changes, and manage campaigns, conversions, analytics, billing, and account access.
List Google Ads accounts, review spend/clicks/conversions per campaign, and run arbitrary read-only GAQL queries.
Research keywords with Keyword Planner ideas and exact keyword metrics/bids.
Analyze Search Console sites: summaries, performance, trends, opportunities, URL indexing, sitemaps, and paid/organic overlap.
Analyze GA4 properties: landing pages, custom reports, setup, key events, and Google Ads links.
Propose Google Ads changes such as negative keywords, pause/enable entities, budgets, bids, bid strategies, targeting, sitelinks, URL suffixes, and conversion actions.
Build paused campaigns: Search, Display, Demand Gen/YouTube, and Performance Max, including ad groups, ads, keywords, assets, and targeting.
Dry-run proposals, apply after explicit approval, undo applied changes, discard proposals, and review change history.
Manage plan limits/account switching, billing/upgrade links, and disconnect stored Google access.
Search Console is read-only; risky changes are flagged before approval; every applied change is logged and reversible where supported.
Provides tools for interacting with Google Ads accounts, including listing accessible accounts, reviewing spend and conversions, finding wasted spend, running read-only GAQL queries, and proposing or applying reversible changes such as adding negative keywords, pausing/enabling keywords or ad groups, and setting campaign daily budgets.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Camberstackfind wasted spend in my Google Ads account and propose fixes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Camberstack: a Google Ads MCP server
Connect Google Ads (and, optionally, Search Console) to Claude, ChatGPT, Cursor or any MCP client. Your AI reads the account with read-only tools and can propose changes, from negative keywords to whole Search, Performance Max, Display and YouTube campaigns. Nothing changes in the account until you approve a specific proposal, and every applied change can be undone in one call, on every plan. Risky changes (turning a campaign on, more than doubling a budget or bid, switching bid strategy) are flagged in the proposal before you approve. A demo account lets anyone try every tool first.
Hosted: https://camberstack.io/mcp (Free: every tool and unlimited changes on 1 Google Ads account at a time, with one switch a month; from November 15, Free covers one Google service at a time: Google Ads, Search Console or Google Analytics. Plus $7/mo: all three together on 1 account; Pro $15/mo: all three on up to 5 accounts; Agency $49/mo: up to 25).
Setup guides, with screenshots and troubleshooting: Connect Google Ads to Claude · Connect Google Ads to ChatGPT · every tool · Cursor, VS Code and others
Tools
tool | writes? | what it does |
| no | every account the login reaches, including client accounts under a manager (MCC) |
| no | spend, conversions, cost per conversion per campaign |
| no | Keyword Planner ideas from seed keywords and/or a URL: monthly searches, competition, top-of-page bid range; marks ideas the account already targets or blocks |
| no | Keyword Planner numbers for an exact list, with the last 12 months of searches |
| no | any read-only GAQL |
| no | the websites (Search Console properties) the login can read |
| no | site-wide clicks, impressions, CTR and position for a window vs. the window before it |
| no | organic clicks, impressions, CTR and position by query, page, country, device or date; text or RE2 regex filters |
| no | a window vs. the one before it, per query and per page: rising, falling, new, lost, and rising searches losing position |
| no | queries on positions 4-20 with projected click gain, top-5 queries with weak CTR, question-shaped queries |
| no | URL Inspection for up to 20 pages: indexed or why not, last crawl, canonical chosen vs declared, structured-data errors |
| no | submitted sitemaps: last downloaded, URL count, errors and warnings |
| no | joins an Ads account's search terms with a site's organic queries: searches paid for that already rank near the top, and page-2+ searches with no ad |
| no | the Google Analytics 4 properties the login can read; if Analytics isn't granted yet, a personal link that adds it |
| no | a property's web streams (measurement IDs), key events and Google Ads links |
| no | like |
| no | sessions, users, engagement rate, key events and key event rate per landing page, optionally for one channel (e.g. Paid Search) |
| no | any GA4 Data API report by dimension and metric names, with a contains filter |
| no | resolves changes against the live account, dry-runs them with Google ( |
| yes | applies a stored proposal (the user's own, un-applied, still matching the account; if the account moved, returns an updated proposal to approve instead); records each change's inverse |
| no | builds the reversing proposal for an applied one |
| plan only | spends the plan's one account switch per 30 days on an account, after the user agrees; changes nothing in Google Ads |
| no | plan, Google Ads accounts in use (last 30 days) vs. the plan's limit, and a personal upgrade or manage-billing link |
| no | marks an open proposal discarded so it can't be applied |
| no | every proposal, with what was applied, what failed and what was undone |
| no | revokes Camberstack's Google access and deletes the stored credentials (the user confirms) |
The Search Console tools take either days or exact start_date/end_date, and fresh: true to include the last 2-3
days Google is still filling in. Requesting indexing and submitting sitemaps aren't available: Camberstack only holds
the read-only scope.
The Google Analytics tools need analytics.readonly and analytics.edit (Google-verified sensitive scopes). Sign-in
asks for them alongside Ads and Search Console; a connection made before they were added gets a personal
/connect/analytics link on its first Analytics call, which adds both to the same Google account. The Cloud project
needs the Google Analytics Data API and Admin API enabled.
What a proposal can do:
Control: add negative keywords; pause or enable a campaign, ad group, keyword or ad; set a campaign's daily budget (never a shared budget) or its end date.
Build, always created paused (building and spending are two separate approvals):
a Search campaign: ad groups, keywords, responsive search ads, targeting, negatives, sitelinks;
a Performance Max campaign: asset groups of text, images and YouTube videos, with the business name and logo on the campaign as Google's brand guidelines require (no shopping feed);
a Display campaign: responsive display ads;
a Demand Gen campaign with YouTube video ads, the API's only way onto YouTube (it refuses to create Video campaigns:
MUTATE_NOT_ALLOWED, v23).
Images are existing image assets or https URLs, which are downloaded SSRF-safe (
src/fetch-safe.ts) and uploaded. A proposal can also add an ad group, keywords, an ad or sitelinks to an existing campaign.Tune: keyword and ad group bids, bid strategy, location and language targeting, presence-only location mode, final URL suffix, and a campaign's EU political advertising declaration (Google refuses every change to an account while any campaign lacks one).
Measure: create or remove a conversion action, set its counting, import a GA4 key event, scope a campaign to one conversion goal.
Risky changes carry a ⚠ line in the proposal summary: enabling a campaign, more than doubling a budget or a
bid, switching bid strategy, removing the last location, a new primary conversion action, removing a conversion
action. Undo removes only what Camberstack itself created. The one deletion a user can propose is
remove_conversion_action, and Google can't restore it, so it carries a ⚠ and no undo (a GA4 import is the exception:
undo imports it again). (Undoing a GA4 import removes the action, since Google can't hide it again; importing again
restores it.) Search Console is read-only.
Related MCP server: Google Ads MCP
How auth works
Camberstack is an OAuth 2.1 authorization server for MCP clients (dynamic client registration,
PKCE). Its /authorize sends the user to Google for openid email plus adwords (Google Ads), webmasters.readonly
(Search Console) and analytics.readonly + analytics.edit (Google Analytics). Any one is enough to connect ("à la carte"), Google Ads included: a tool that needs a missing one returns a personal
/connect/<google-ads|search-console|analytics> link that adds just that service to the same Google account. The Google refresh
token is stored AES-256-GCM encrypted and never leaves the server. The MCP client gets
Camberstack's own tokens, which are stored only as SHA-256 hashes.
Two MCP SDKs, on purpose: /mcp is served by SDK v2 (@modelcontextprotocol/server + /node), which
answers both 2026-07-28 clients (server/discover) and 2025-era ones (initialize, kept on a
JSON-response transport). The authorization server (mcpAuthRouter, requireBearerAuth) stays on
@modelcontextprotocol/sdk 1.x, because v2 ships only the resource-server half. Don't drop 1.x
until v2 (or a companion package) has /authorize, /token and /register.
Run it
npm ci && npm test
ENCRYPTION_KEY=$(openssl rand -hex 32) \
GOOGLE_CLIENT_ID=… GOOGLE_CLIENT_SECRET=… GOOGLE_ADS_DEVELOPER_TOKEN=… \
BASE_URL=https://your.host npm run devenv | |
| 32 bytes, hex or base64. Losing it only forces users to reconnect; leaking it exposes stored Google tokens |
| OAuth client from a dedicated Google Cloud project with Google Ads API access. Redirect URI: |
| sent when set |
| public origin, the OAuth issuer (default |
| SQLite location (default |
| Google Ads accounts each plan covers at a time, counted as distinct accounts used in the last 30 days plus one switch per 30 days, manager and demo accounts excluded (defaults 1 / 5) / emails treated as Pro |
| Free covers one Google service at a time (Ads, Search Console or GA4: the most recently used, over 30 days); paid plans cover all three. |
| Pro subscription via Stripe Checkout; unset = no upgrade links |
| the Agency plan's price (its own product) / accounts it covers (default 25); unset price = no Agency offered. Which plan a user is on follows their subscription's price, so a Pro ↔ Agency switch in Stripe's billing portal (which must list both prices) moves it within the hour |
The hosted HTTP server is npm run start:http (the Docker image runs node dist/server.js).
npm start is a stdio mode that needs no env, database or Google login: it lists every tool for
directory inspectors (Glama runs mcp-proxy -- pnpm run start), and any tool call answers with
the hosted URL to connect to. pnpm-workspace.yaml turns off native builds for pnpm installs, so
stdio mode installs anywhere; production installs with npm.
scripts/try-account.ts runs the read tools against a real account from an existing refresh
token, skipping OAuth. Use it for dogfooding.
License
MIT
Available Tools
26 toolsaccount_overviewAccount overviewBRead-onlyInspect
Spend, clicks, conversions and cost per conversion per campaign over a window.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending yesterday | |
| customer_id | Yes | Google Ads customer ID, with or without dashes (from list_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds almost nothing beyond that: it does not mention aggregation semantics, rate limits, auth scopes, or what happens when the window exceeds available history.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence listing the metrics and their grouping, with no filler or redundancy. It is appropriately sized for a simple two-parameter reporting tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description partially compensates by naming the returned metrics and their grouping. However, it omits whether additional metrics exist, whether the response can be broken down by day, and any pagination or size caveats an agent would need.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters are well documented in the schema, including the 'ending yesterday' nuance for days. The description's phrase 'over a window' only loosely gestures at the days parameter, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the concrete outputs (spend, clicks, conversions, cost per conversion) and the granularity (per campaign) over a window, so an agent knows this is a reporting/aggregation read. It does not differentiate itself from siblings such as run_gaql or search_console_summary, which could plausibly return overlapping data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of when to prefer this over run_gaql, and no prerequisites stated in the description itself. The only routing hint (customer_id from list_accounts) lives in the schema, not the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analytics_landing_pagesGoogle Analytics landing pagesARead-onlyInspect
Where visitors land and whether it works: sessions, users, engagement rate, key events (GA4's conversions) and key event rate per landing page, most sessions first. Pass channel to see one source, e.g. "Paid Search" for Google Ads traffic or "Organic Search". Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending yesterday | |
| limit | No | Most landing pages to return | |
| channel | No | Only sessions whose default channel group contains this, e.g. Paid Search, Organic Search, Direct | |
| end_date | No | Exact last day, YYYY-MM-DD | |
| start_date | No | Exact first day, YYYY-MM-DD. Pass with end_date to use exact dates instead of days | |
| property_id | Yes | GA4 property id, digits only (from analytics_properties) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so "Changes nothing" largely restates structured data. The description does add the default result ordering (most sessions first) and clarifies that GA4 key events are the conversion metric, which is modest added value beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Metrics are front-loaded and the two trailing sentences are short and purposeful. It is dense but wastes little; the "Google Ads traffic" example earns its place by disambiguating channel values.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the burden of describing returns — and it does list the returned metrics and ordering. It stops short of describing pagination or how the day/date-range defaults interact, but the schema covers those parameters adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter (days, limit, channel, start/end date, property_id) is already documented in the schema. The description echoes the channel filter with examples but adds no new syntax or constraint beyond what the schema supplies, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the specific resource (landing pages) and enumerates the exact metric set returned (sessions, users, engagement rate, key events, key event rate), plus the sort order. That is enough for an agent to distinguish it from analytics_report or the search_console_* family.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Pass channel to see one source" gives a concrete usage cue with examples, but there is no guidance on when to prefer this over siblings like analytics_report or paid_organic_overlap, and no exclusions. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analytics_propertiesList Google Analytics propertiesARead-onlyInspect
Lists the Google Analytics 4 properties this Google login can read. Use a property_id from here in the other Google Analytics tools. If Google Analytics isn't part of the connection yet, says so and returns grant_url, a personal link the user opens to add it.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true). The description adds genuinely new behavior: when GA is not part of the connection, the tool reports that and returns a grant_url the user must open to authorize. That fallback/remediation path is not derivable from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core action, then downstream usage, then the failure-mode behavior. Every sentence carries distinct information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description carries the explanation burden well: it covers what is listed, how to use the result, and the not-connected fallback including the grant_url. It does not describe the shape of a returned property record (e.g., id vs display name), which would close the remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema places no burden on the description. It appropriately mentions property_id as the output value to carry into downstream tools rather than as an input, which is context the schema cannot express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope: 'Lists the Google Analytics 4 properties this Google login can read.' The scope qualifier (properties readable by this login) is more precise than the title alone, and it hints at its role relative to other GA tools, though it never names a specific sibling to differentiate against.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use a property_id from here in the other Google Analytics tools' tells the agent this is the entry point for GA workflows, which is actionable routing guidance. It stops short of naming which sibling to use next (e.g., analytics_report vs analytics_setup) or when the tool is not needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analytics_reportRun a Google Analytics reportARead-onlyInspect
Any GA4 report: dimensions and metrics by their GA4 API names, highest first. Common dimensions: date, landingPage, pagePath, sessionDefaultChannelGroup, sessionSourceMedium, sessionCampaignName, sessionGoogleAdsCampaignName, deviceCategory, country, eventName. Common metrics: sessions, totalUsers, engagedSessions, engagementRate, keyEvents, sessionKeyEventRate, screenPageViews, purchaseRevenue. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending yesterday | |
| limit | No | Most rows to return | |
| filter | No | Only rows whose dimension contains this text (case-insensitive) | |
| metrics | Yes | GA4 metric names | |
| end_date | No | Exact last day, YYYY-MM-DD | |
| order_by | No | A requested metric (highest first) or dimension (A to Z, dates oldest first); defaults to the first metric | |
| dimensions | No | GA4 dimension names; none gives totals | |
| start_date | No | Exact first day, YYYY-MM-DD. Pass with end_date to use exact dates instead of days | |
| property_id | Yes | GA4 property id, digits only (from analytics_properties) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true and destructiveHint=false, and the description reinforces this with 'Changes nothing'. It adds useful behavioral detail beyond the annotations: results are returned highest-first and accept raw GA4 API names. It does not mention pagination or rate limits, but with annotations carrying the safety profile a 4 is fair.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and sort behavior are front-loaded in one sentence, followed by two compact lists of valid values and a closing safety note. Nothing is redundant with the schema and every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with a nested filter object and no output schema, the description covers intent, valid field vocabulary, and default ordering. Date-window and limit semantics are left entirely to the schema, and the shape of returned rows is only implied by 'highest first', which is a minor remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, which sets a baseline of 3, but the description goes further by enumerating common dimension and metric names — valuable because the schema provides no enums (0) and says only 'GA4 metric names'. This materially reduces the risk of an agent inventing invalid field names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a clear verb and resource ('Any GA4 report') and specifies the payload (dimensions and metrics by GA4 API names, sorted highest first). It implicitly separates itself from sibling preset reports like analytics_landing_pages by claiming 'any' report, though it never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Any GA4 report' hints at the use case — arbitrary dimension/metric combinations — and 'Changes nothing' rules it out as a mutation. But there is no explicit statement of when to prefer this over analytics_landing_pages or run_gaql, so the routing decision is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analytics_setupGoogle Analytics setupARead-onlyInspect
How a GA4 property is set up: its web streams with their measurement IDs (what the site's tag must use), which events are key events (GA4's conversions), and which Google Ads accounts it's linked to. Check this before proposing setup changes. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| property_id | Yes | GA4 property id, digits only (from analytics_properties) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false; the description adds value by confirming 'Changes nothing' and by describing the shape of what is returned (streams, measurement IDs, key events, ad links), including the actionable note that the measurement ID is what the site's tag must use. It doesn't cover freshness, pagination, or limits, but it goes beyond the annotations' safety profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences plus a two-word reassurance; the return contents lead and the read-only caveat closes. No sentence is filler and nothing is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read with no output schema, the description adequately conveys what comes back and that nothing is mutated. It could say slightly more about scope (per-property vs. account-wide) or response freshness, but an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single property_id parameter is fully documented in the schema, including its digits-only pattern and its provenance from analytics_properties. The description adds no further parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific resource (a GA4 property's setup) and enumerates the exact contents returned: web streams with measurement IDs, key events, and linked Google Ads accounts. This distinguishes it cleanly from the sibling analytics_properties (which lists properties) and analytics_report (which returns metrics).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States a clear trigger: 'Check this before proposing setup changes,' which implicitly routes the agent away from propose_analytics_changes and toward inspection first. It stops short of naming the alternative tool or stating exclusions, so it is clear context rather than full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
apply_changesApply an approved proposalADestructiveInspect
Applies a proposal from propose_changes to the account. Only call this after the user has explicitly approved that proposal. All or nothing: every change is checked with Google first, and if one still fails the ones before it are rolled back. Each change is logged and can be reversed with undo_changes. If the account changed since the proposal, nothing is applied and the result (status "needs approval") is a new proposal with the updated summary: show it to the user and apply it only after they approve.
| Name | Required | Description | Default |
|---|---|---|---|
| proposal_id | Yes | The proposal_id a propose tool returned |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, idempotentHint=false, readOnlyHint=false, but the description adds substantial context beyond them: all-or-nothing semantics, server-side validation with Google, rollback of preceding changes on failure, per-change logging, reversibility via undo_changes, and the stale-proposal 'needs approval' outcome. This is exactly the behavioral disclosure a mutation tool needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the action and the approval precondition, then layers atomicity, reversibility, and the stale-proposal branch. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description names the salient return condition (status 'needs approval' yielding a fresh proposal) and the failure behavior, so an agent knows what to expect and what to do with the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter with 100% schema description coverage, so the schema already carries the burden and baseline is 3. The description adds the provenance of the value (a proposal produced by propose_changes) but no format or sourcing detail beyond that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Applies a proposal from propose_changes to the account') and names the sibling tool that produces its input. An agent can distinguish it from propose_changes, discard_proposal, and undo_changes immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit precondition ('Only call this after the user has explicitly approved that proposal') and describes the conditional branch when the account has changed since the proposal — show the new proposal to the user and apply only after approval. It also names undo_changes as the reversal path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
billingPlan and billingARead-onlyInspect
Shows the user's Camberstack plan: the Google Ads accounts used in the last 30 days against the number the plan covers (Free 1, Plus 1, Pro 5, Agency 25), and on Free which Google service it covers. Returns personal links to upgrade (Free to Plus or Pro, Plus to Pro, Pro to Agency) or to change card and cancel (paid plans). This is the Camberstack subscription only, not a Google Ads account's own billing, invoices or ad spend.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds genuinely useful context: it discloses the exact return content (personal upgrade/change-card/cancel links) and clarifies the subscription-vs-ad-spend boundary. It doesn't mention auth or rate-limit behavior, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the resource and its contents, then the scope boundary. Every clause conveys actionable detail (tiers, links, exclusions) with no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the job of explaining return values, and it does: it lists what is shown and the personal links returned. Combined with the read-only annotations, an agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4, and there are no parameter semantics for the description to compensate for. Nothing is missing on this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Shows the user's Camberstack plan') and details exactly what is surfaced: accounts used vs plan limit, the plan tiers (Free 1, Plus 1, Pro 5, Agency 25), and the Free-service coverage. This distinguishes it clearly from every sibling tool, none of which handle billing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides an explicit exclusion ('This is the Camberstack subscription only, not a Google Ads account's own billing, invoices or ad spend'), which routes the agent away from misusing it. There is no named alternative to use instead, so it lacks the sibling-comparison required for a 5, but the negative scoping is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
change_historyChange historyBRead-onlyInspect
Every proposal made through Camberstack, with what was applied, what failed, and what was undone.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most proposals to return, newest first | |
| customer_id | No | Google Ads customer ID, with or without dashes (from list_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so safety is covered. The description adds genuine value beyond that by disclosing the composition of the returned records (applied vs. failed vs. undone proposals), which matters because no output schema exists. It does not discuss volume, pagination, or retention windows.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler, and the resource is stated first. The word 'Every' slightly overstates the result set given the schema's default limit of 20 and maximum of 100, a minor imprecision in an otherwise efficient sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining returns; it does so at a high level (applied/failed/undone) but says nothing about record structure, pagination, or how far back history goes. Both parameters are optional, and annotations cover the safety profile, so the gaps are moderate rather than severe.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: limit is documented as 'most proposals to return, newest first' with default and bounds, and customer_id notes the dashed/undashed format and points to list_accounts. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (every proposal made through Camberstack) and enumerates the record contents (applied, failed, undone), so the agent knows this is a historical/audit listing rather than an action. It does not explicitly name the sibling tools it contrasts with (propose_changes, apply_changes, undo_changes), but the 'history' framing makes the distinction inferable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no statement of prerequisites, and no reference to alternative tools such as run_gaql or account_overview for related lookups. The agent must infer from the resource name alone that this is a read-only audit call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
discard_proposalDiscard a proposalADestructiveInspect
Marks an open proposal as discarded so it can never be applied; this can't be reversed (propose again instead). Changes nothing in the Google Ads account.
| Name | Required | Description | Default |
|---|---|---|---|
| proposal_id | Yes | The proposal_id a propose tool returned |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, but the description adds the crucial context the annotation cannot: the action is irreversible, and it 'changes nothing in the Google Ads account' (i.e. no account mutation, only proposal state). That materially sharpens how the agent interprets the destructive hint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One tight sentence with the destructive/irreversible fact front-loaded, followed by the remedy and the account-impact clarification. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-param, no-output-schema tool, the definition covers irreversibility, account impact, and the re-propose path. The remaining gap is that it never contrasts with undo_changes, which is the sibling an agent is most likely to weigh against it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter with 100% schema coverage, and the schema already explains it is 'the proposal_id a propose tool returned'. The description adds no formatting, sourcing, or validation detail beyond that, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (marks as discarded) on a specific resource (an open proposal) and defines the terminal consequence ('can never be applied'). The agent can distinguish this from apply_changes, propose_changes and undo_changes without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the precondition ('an open proposal') and an explicit recovery path ('propose again instead'), which tells the agent what to do after discarding. It does not, however, say when to prefer this over undo_changes, the closest sibling in the list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disconnectDisconnect Google AdsADestructiveInspect
Revokes Camberstack's Google access and deletes the stored credentials. The user must confirm.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true; ask the user first |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false and openWorldHint=true, so the danger class is known. The description adds genuine value beyond that by naming exactly what is destroyed (stored credentials and Google access) and flagging the mandatory user confirmation, though it omits reversibility/re-auth consequences.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the destructive action and its consequence front-loaded before the confirmation requirement. Nothing is wasted or buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool whose annotations and schema already carry the safety profile and parameter contract, the description covers the essentials: what is revoked, what is deleted, and the confirmation gate. Only the post-disconnect state (irreversibility, need to re-authorize) is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single `confirm` parameter is already documented as const true with 'Must be true; ask the user first'. The description's 'The user must confirm' restates rather than extends the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Revokes Camberstack's Google access and deletes the stored credentials'), making the action unambiguous. It is clearly distinguishable from every sibling, all of which are read/analysis/change-proposal tools rather than credential lifecycle tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies when to use it via the precondition 'The user must confirm', which tells the agent a prerequisite step. However, it does not explicitly frame the situation (e.g., 'use when the user wants to unlink or re-authenticate their Google account') or state any when-not conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
keyword_ideasKeyword ideas (Keyword Planner)ARead-onlyInspect
Google Keyword Planner ideas from seed keywords and/or a landing-page URL: average monthly searches, competition and the top-of-page bid range in the account's currency, biggest first. Ideas the account already targets, or already blocks as negatives, are marked in_account. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | A page to pull ideas from, such as the ad's landing page | |
| limit | No | Most ideas to return | |
| keywords | No | Up to 20 seed keywords | |
| customer_id | Yes | Google Ads customer ID, with or without dashes (from list_accounts) | |
| language_id | No | Google language ID. 1000 English, 1003 Spanish, 1002 French, 1001 German, 1014 Portuguese | 1000 |
| location_ids | No | Google geo target IDs. 2840 United States, 2826 United Kingdom, 2124 Canada, 2036 Australia, 2356 India. For a state, city or other country, look the ID up with run_gaql: SELECT geo_target_constant.id, geo_target_constant.canonical_name FROM geo_target_constant WHERE geo_target_constant.name = 'Denver' | |
| min_searches | No | Drop ideas below this many average monthly searches |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered; 'Changes nothing.' is a harmless restatement rather than new information. The description does add genuine behavioral detail beyond annotations, though: results are sorted biggest-first, entries the account already targets or blocks are flagged in_account, and bid ranges are rendered in the account's currency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence with the resource and return fields front-loaded, no filler. It is slightly overloaded with listing output fields that the agent could infer, but every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates the return fields, sorting, in_account flagging, and currency, and annotations carry the safety profile. Minor gaps remain (empty-result behavior, whether ideas are capped by 'limit' default 50 vs max 200), but these are covered in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with rich per-parameter descriptions (language IDs, geo IDs, seeds limit of 20, min_searches), so baseline 3 applies. The description only adds that seeds and URL are combinable ('and/or') and that monetary values use account currency; it adds nothing about limit, min_searches, or location_ids beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Google Keyword Planner ideas from seed keywords and/or a landing-page URL', and enumerates the returned fields (average monthly searches, competition, top-of-page bid range). An agent can tell this generates keyword ideas rather than looking up metrics, though it never names the closest sibling (keyword_metrics) to draw the boundary explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'From seed keywords and/or a landing-page URL' implies the two entry modes, which is useful usage context. However, there is no explicit when-to-use/when-not or a named alternative such as keyword_metrics for cases where the agent already has a keyword list and only wants metrics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
keyword_metricsKeyword volume and bids (Keyword Planner)ARead-onlyInspect
Google Keyword Planner numbers for an exact list of keywords: average monthly searches, the last 12 months, competition and the top-of-page bid range in the account's currency. Use it to size keywords before adding them or to check a trend. Up to 100 keywords come back as one object each; over 100, as a compact table (columns, months, rows). Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | Keywords to look up, up to 500 | |
| customer_id | Yes | Google Ads customer ID, with or without dashes (from list_accounts) | |
| language_id | No | Google language ID. 1000 English, 1003 Spanish, 1002 French, 1001 German, 1014 Portuguese | 1000 |
| location_ids | No | Google geo target IDs. 2840 United States, 2826 United Kingdom, 2124 Canada, 2036 Australia, 2356 India. For a state, city or other country, look the ID up with run_gaql: SELECT geo_target_constant.id, geo_target_constant.canonical_name FROM geo_target_constant WHERE geo_target_constant.name = 'Denver' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses a genuinely non-obvious behavior the schema cannot: result shape switches from one object per keyword at ≤100 keywords to a compact table (columns/months/rows) above 100. Also notes values are in the account's currency and that 'changes nothing' (redundant with readOnlyHint, but harmless). Does not mention rate limits or partial-failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: capabilities first, then usage, then the response-shape caveat and safety note. No filler, and the most surprising fact (the 100-keyword format switch) is preserved rather than buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining returns and does so concretely, including both response shapes. Annotations cover the safety profile and the schema covers every parameter's meaning, so an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics the schema lacks: the 100-keyword threshold that changes the response representation, despite the schema allowing up to 500. Doesn't elaborate on language_id/location_ids behavior, which the schema already handles well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a concrete resource (Google Keyword Planner data) and enumerates the exact metrics returned: average monthly searches, 12-month window, competition, top-of-page bid range. The phrase 'an exact list of keywords' implicitly separates it from the sibling keyword_ideas (ideation) without needing the agent to open either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit use cases — 'size keywords before adding them' and 'check a trend' — which tells the agent where this fits in a workflow. It stops short of naming alternatives or exclusions (e.g. 'for discovery use keyword_ideas instead'), so the routing is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsList Google Ads accountsARead-onlyInspect
Lists every Google Ads account this login can reach, including client accounts under a manager (MCC). Start here. spentLast30Days says whether an account had ad spend in the last 30 days (show it when the user picks one). When the user's plan is at its limit, each account also says whether the plan covers it (plan_status: active, switch or locked).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a safe read-only, non-destructive open-world operation. The description adds useful behavioral context beyond annotations: it explains MCC account inclusion and documents the meaning of spentLast30Days and plan_status, which matters because there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action ('Lists every Google Ads account...'), followed by usage and return-field guidance. Every sentence serves a purpose, and there is no redundant restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter list tool with rich read-only annotations but no output schema, the description supplies the key returned-field semantics an agent needs. It does not enumerate the full account object shape, but it covers enough to call and interpret the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero input parameters, so the schema baseline is 4. The description does not need to explain parameters and correctly focuses on return-value semantics instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: it lists every Google Ads account the login can reach, including MCC client accounts. It also distinguishes this tool's role by saying 'Start here,' which differentiates it from downstream siblings like switch_account or run_gaql.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when to use the tool ('Start here') and when to surface certain returned fields ('show it when the user picks one'). It does not name explicit exclusions or alternatives, but the starting-point guidance is strong enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paid_organic_overlapPaid vs organic overlapARead-onlyInspect
Joins a Google Ads account's search terms with a website's Search Console queries over the same days. Returns paid_and_ranking (searches you pay for where the site already ranks near the top organically, with ad spend) and organic_gaps (searches the site shows up for on page 2 or lower with no ad or keyword). Changes nothing; follow up with propose_changes.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending 3 days ago | |
| limit | No | Most rows in each list | |
| site_url | Yes | Search Console property exactly as search_console_sites lists it, e.g. sc-domain:example.com or https://www.example.com/ | |
| customer_id | Yes | Google Ads customer ID, with or without dashes (from list_accounts) | |
| max_position | No | paid_and_ranking: average organic position at or better than this | |
| min_impressions | No | organic_gaps: only queries with at least this many impressions |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this with 'Changes nothing.' It goes beyond the safety profile by explaining what the two output lists represent (paid_and_ranking vs organic_gaps) and their inclusion criteria, which is genuine behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the join operation and immediately followed by the return-list definitions. Efficient with no filler, though the parenthetical definitions of the two lists add some length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description correctly carries the burden of explaining the return values, which it does via the two named lists. The absence of pagination or volume guidance is a minor gap given the limit parameter's own schema documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all six parameters are already documented, including max_position and min_impressions. The description alludes to these semantics ('near the top organically', 'shows up for on page 2 or lower') but adds no syntax or format guidance beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Uses a specific verb (joins) plus both named resources (Google Ads search terms, Search Console queries) and enumerates the two returned lists with definitions. An agent can distinguish this cross-source overlap tool from single-source siblings like search_console_opportunities or keyword_metrics without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the operation changes nothing and points to propose_changes as the follow-up, which is useful routing, but it never says when to choose this over the adjacent search_console_opportunities or keyword_ideas tools. Usage is implied rather than explicitly scoped with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
propose_analytics_changesPropose Google Analytics changes (applies nothing)AIdempotentInspect
Checks Google Analytics setup changes against the live property and stores them as a proposal with a plain-English summary; nothing is changed. Show the summary to the user and apply only after they approve, with apply_changes (undo_changes reverses it). Supported: create_ga4_property (a property plus a web stream; the applied result gives the measurement ID and the tag the site needs), mark_key_event / unmark_key_event (GA4's conversions), set_key_event_counting (also recounts a Google Ads import of it), link_google_ads / unlink_google_ads. Point out any ⚠ line before they approve.
| Name | Required | Description | Default |
|---|---|---|---|
| changes | Yes | Changes to propose; several can go in one proposal |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the generic profile (readOnlyHint=false, destructiveHint=false, idempotentHint=true, openWorldHint=true); the description adds the crucial non-generic fact that despite writing a proposal nothing is applied, plus per-change side effects (an Ads import follows a recount; linking requires admin on both sides). That is well beyond what the annotations convey and is internally consistent with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and the safety guarantee, then the approval workflow, then the supported type catalogue. Dense semicolon-chained clauses make the middle sentence heavy, but every clause carries operational meaning and none is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and a single parameter, the description covers the approval loop, reversibility and change catalogue thoroughly. The one gap is what a proposal returns (an id or handle to pass to apply_changes/discard_proposal), which the agent must infer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the sole parameter's oneOf variants are already fully documented in the schema, including const types, required fields and even the Ads-import caveat. The description enumerates the same change types and their outcomes, so it largely restates structured data rather than adding format or constraint detail (e.g., the 20-item cap and batching are schema-only).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — checks Google Analytics setup changes against the live property and stores a proposal — and explicitly says nothing is applied. It also names its counterpart apply_changes, so an agent can distinguish this from the sibling propose_changes (non-GA) and from apply_changes at a glance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit workflow: show the summary to the user, apply only after approval with apply_changes, and undo_changes reverses it. It even instructs the agent to point out ⚠ lines before approval, so the conditions for use and follow-up are fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
propose_changesPropose Google Ads changes (applies nothing)AIdempotentInspect
Checks a set of changes against the live account and dry-runs them with Google, then stores them as a proposal and returns a plain-English summary. Nothing is changed. Show the summary to the user and apply only after they approve. Supported: add_negative_keywords, pause_campaign, enable_campaign, pause_keyword, enable_keyword, pause_ad_group, enable_ad_group, set_daily_budget, set_end_date, and building: create_campaign (Search), create_display_campaign, create_demand_gen_campaign (YouTube), create_performance_max_campaign, all created paused; add_ad_group, add_keywords, add_responsive_search_ad, add_sitelinks, set_conversion_goal; and tuning: set_keyword_bid, set_ad_group_bid, pause_ad, enable_ad (to replace an ad: add the new one and pause the old in one proposal), add_campaign_targeting, remove_campaign_targeting, set_location_mode, set_bidding_strategy, set_shared_bid_strategy, create_shared_bid_strategy, set_url_suffix, set_eu_political_advertising (Google refuses every change to an account until each campaign has declared this), create_conversion_action, set_conversion_counting, import_ga4_key_event, remove_conversion_action. Point out any ⚠ line in the summary to the user before they approve. At most 50 changes per proposal, counting each keyword in add_keywords and add_negative_keywords as one (a create_campaign or add_ad_group counts as one however much it holds); for more, split them into several proposals up front and show the user all the summaries together.
| Name | Required | Description | Default |
|---|---|---|---|
| changes | Yes | Changes to propose; several can go in one proposal, up to 50 (each keyword counts as one) | |
| customer_id | Yes | Google Ads customer ID, with or without dashes (from list_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses the dry-run against the live account, the fact that a proposal record is stored, the 50-change cap with per-keyword counting, and the account-wide EU political advertising declaration blocker with its error code. The 'Nothing is changed' line also reconciles readOnlyHint=false with the user's expectation that no live ads are mutated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first two sentences are tight and front-loaded with the critical 'nothing is changed / approve first' behaviour. The middle sentence, however, is a ~200-word comma-spliced catalogue of operation names ('and building:...', 'and tuning:...') that duplicates the schema and is hard to scan, diluting an otherwise well-structured definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly explains the return value as a plain-English summary with ⚠ lines, and it covers the approval flow and batch limit. The remaining gap is the absence of any mention of the proposal identifier or the follow-up tools (apply_changes, discard_proposal) an agent needs to complete the loop.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the oneOf already enumerates every change type with per-variant descriptions, so the description's long op list mostly restates structured data. The added value is limited to the counting rule for the 50-item cap, and even that is echoed in the changes parameter's schema description. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb chain (checks, dry-runs with Google, stores as a proposal, returns a summary) against a specific resource (Google Ads account changes), and explicitly distinguishes itself from the write path with 'Nothing is changed.' An agent can tell this apart from apply_changes without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational guidance: show the summary to the user, apply only after approval, surface any ⚠ line, and split anything over 50 changes into several proposals shown together. It never names the sibling tools (apply_changes, discard_proposal) that carry out those next steps, so routing to them is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_gaqlRun a read-only GAQL queryARead-onlyInspect
Runs any read-only Google Ads Query Language SELECT for questions the other tools don't cover. Returns up to 500 rows. Google rejects queries that break these rules: selecting or segmenting by segments.date needs a finite range in WHERE (segments.date DURING LAST_30_DAYS, or BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'); click_view needs a single day (segments.date = 'YYYY-MM-DD'); every field used in WHERE or ORDER BY must also be in SELECT. Maximize clicks is target_spend in the API: campaign.target_spend.cpc_bid_ceiling_micros (there is no campaign.maximize_clicks). Unsure of a field's name or whether it fits this FROM? Look it up first with a query that has no FROM, which reads Google's field catalog instead of the account (any customer_id): SELECT name, category, selectable WHERE name LIKE '%search_term%', or SELECT attribute_resources, metrics, segments WHERE name = 'campaign' for what can be used FROM campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | A GAQL SELECT statement | |
| customer_id | Yes | Google Ads customer ID, with or without dashes (from list_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, and openWorldHint, so the safety profile is covered. The description adds real behavioral value beyond that: a 500-row result cap and the server-side rejection rules (date segmentation, click_view, WHERE/ORDER BY fields must appear in SELECT). It leaves error/pagination behavior unspecified, so 4 rather than 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence is substantive domain knowledge, and the core purpose is front-loaded in the first clause. It could be tightened slightly (the rule list runs on inline), but there is no filler to cut.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, yet the description covers the return cap (500 rows) and supplies the query-validity rules an agent needs to avoid server-side rejection, plus the field-catalog trick and the maximize-clicks/target_spend mapping. Nothing essential for a correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by clarifying that for the catalog lookup any customer_id works, and by framing the query parameter's expected shape as a GAQL SELECT with enumerated semantic rules rather than just a string type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (run a read-only GAQL SELECT) and constrains scope to 'questions the other tools don't cover', which distinguishes it from the many sibling report tools. An agent can identify the intended use without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear routing rule (fallback for questions other tools don't cover) and even describes a second usage mode: use a FROM-less query to inspect Google's field catalog before committing to a real query. It does not name specific sibling tools to prefer or spell out hard exclusions, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_console_inspect_urlsInspect URLs in Google's indexARead-onlyInspect
Google's index record for each page: indexed or not and the reason (for example "Discovered - currently not indexed"), last crawl, robots.txt and fetch result, the canonical Google chose against the one the page declares, and structured-data items with their errors. Use it when a page gets no impressions, or seems to have dropped, before assuming a ranking problem. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | Full page URLs inside the property, up to 20 per call (Google allows 2,000 a day per site) | |
| site_url | Yes | Search Console property exactly as search_console_sites lists it, e.g. sc-domain:example.com or https://www.example.com/ |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so 'Changes nothing' mostly restates the safety profile. The description's real added value is disclosing what the call actually returns (index verdict and reason, crawl data, canonical mismatch, structured-data errors), which matters since no output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the resource and its payload, then the usage condition, then the side-effect note. Zero wasted sentences, though the dense field list is packed into one long clause and 'Changes nothing' is largely redundant with the readOnlyHint annotation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining returns and does so thoroughly; usage context and safety are also covered. Parameter limits live in the schema, so the definition is nearly complete for a two-parameter read-only inspection tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: 'urls' documents the 20-per-call and 2,000/day limits, and 'site_url' documents the exact property format. The description adds nothing about either parameter, so the schema does all the work and the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (inspect URLs) and a specific resource (Google's index record per page), then enumerates the exact fields returned: index status and reason, last crawl, robots.txt/fetch result, Google-chosen canonical vs declared canonical, structured-data items. That level of specificity clearly separates it from search_console_performance or search_console_summary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit triggering condition: use it when a page gets no impressions or seems to have dropped, and explicitly before assuming a ranking problem. It does not name a sibling tool as the alternative (e.g. search_console_performance) or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_console_opportunitiesSearch Console opportunitiesARead-onlyInspect
Finds where more organic clicks are within reach: queries on positions 4-20 with the clicks a realistic climb would add, top-5 queries with an unusually low click-through rate (a title or description to fix), and question-shaped queries. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending 3 days ago (yesterday with fresh) | |
| fresh | No | Include the last 2-3 days, which Google is still filling in (they read low). Use to check something from the last few days | |
| limit | No | Most rows in each list | |
| end_date | No | Exact last day, YYYY-MM-DD | |
| site_url | Yes | Search Console property exactly as search_console_sites lists it, e.g. sc-domain:example.com or https://www.example.com/ | |
| start_date | No | Exact first day, YYYY-MM-DD. Pass with end_date to use exact dates instead of days | |
| exclude_query_regex | No | Leave out queries matching this RE2 regex, typically the brand name, e.g. (?i)acme|ac me |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so "Changes nothing" mostly restates what the structured data provides. The description does add behavioral value by disclosing what the analysis surfaces (three distinct opportunity classes), but omits pagination, ordering, or how the three lists are returned. With annotations carrying the safety profile, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence with no filler; the opportunity categories are front-loaded and each clause carries information. The clause-packed enumeration is slightly heavy to parse but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and seven parameters, the description responsibly explains what the tool returns (three opportunity categories), which is the key unknown. It stops short of describing result ordering or grouping, but for a read-only analysis tool whose annotations and schema are otherwise complete, coverage is solid.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all seven parameters (days, fresh, limit, end_date, start_date, site_url, exclude_query_regex) are already documented in the schema. The description adds no parameter-level meaning beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("Finds") and enumerates three concrete outputs: position 4-20 queries with realistic click gains, top-5 queries with low CTR, and question-shaped queries. This is far more specific than a generic 'search console data' tool. However, it never names a sibling (e.g. search_console_performance or search_console_summary), so an agent must infer the boundary from the output description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Finds where more organic clicks are within reach" implies the use case (diagnosing growth opportunities) but there is no explicit when-to-use framing, no when-not, and no named alternative such as search_console_performance for raw metrics. Usage is only implied by the output categories.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_console_performanceSearch Console performanceARead-onlyInspect
Organic Google Search clicks, impressions, CTR and average position for a website, grouped by query, page, country, device or date, most clicks first. Search Console's last 2-3 days are incomplete, so the window ends 3 days ago unless fresh is set. Group by query and page together to see whether several pages compete for the same search; by page and date to see when a page's impressions or position changed. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending 3 days ago (yesterday with fresh) | |
| fresh | No | Include the last 2-3 days, which Google is still filling in (they read low). Use to check something from the last few days | |
| limit | No | Most rows to return | |
| end_date | No | Exact last day, YYYY-MM-DD | |
| site_url | Yes | Search Console property exactly as search_console_sites lists it, e.g. sc-domain:example.com or https://www.example.com/ | |
| dimensions | No | What to group by | |
| page_regex | No | Only pages whose URL matches this RE2 regex | |
| start_date | No | Exact first day, YYYY-MM-DD. Pass with end_date to use exact dates instead of days | |
| query_regex | No | Only queries matching this RE2 regex | |
| page_contains | No | Only pages whose URL contains this text | |
| query_contains | No | Only queries containing this text | |
| exclude_query_regex | No | Leave out queries matching this RE2 regex, typically the brand name, e.g. (?i)acme|ac me |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint:false and openWorldHint. Beyond that, the description adds genuinely useful behavioral context: results are sorted 'most clicks first', and Search Console's last 2-3 days are incomplete so the window ends 3 days ago unless fresh is set. It does not mention rate limits or auth, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense, front-loaded sentences: returned metrics first, then the freshness caveat, then practical grouping tips. Every clause carries information; the closing 'Changes nothing' is minor restatement of the annotation but reads as a quick safety confirmation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter tool with full schema coverage and no output schema, the description covers the important non-obvious bits: freshness incompleteness, sort order, grouping intent, and read-only nature. It could still say more about pagination/result shape, but an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description earns a bump by adding grouping semantics the schema lacks - explaining what combining dimensions reveals - and by reinforcing the window/fresh tradeoff, giving meaning beyond the raw field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: it returns organic Google Search clicks, impressions, CTR and average position and names the grouping dimensions. This distinguishes it from siblings like search_console_summary or search_console_trend by its per-dimension grouping, though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete usage guidance for combining dimensions ('query and page together to see whether several pages compete'; 'page and date to see when a page's impressions or position changed'). However it never states when to prefer this tool over search_console_summary/trend/opportunities, so there are no exclusions or named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_console_sitemapsSearch Console sitemapsARead-onlyInspect
The sitemaps submitted for a website: when Google last downloaded each one, how many URLs it lists, and its error and warning counts. Changes nothing: submitting a sitemap is done in Search Console.
| Name | Required | Description | Default |
|---|---|---|---|
| site_url | Yes | Search Console property exactly as search_console_sites lists it, e.g. sc-domain:example.com or https://www.example.com/ |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description still adds value by reinforcing the read-only nature ('changes nothing') and by disclosing the shape of the returned data (last download, URL count, error and warning counts), which matters since there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with zero filler; the resource and returned fields come first, and the scope caveat follows. Nothing needs trimming.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read tool with no output schema, the description covers the resource, the returned fields, and the read-only scope, which is most of what an agent needs. It could note that results cover all submitted sitemaps for the property (no pagination/filter params exist), but the gaps are minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; site_url is already documented with exact format examples (sc-domain:example.com) and a pointer to search_console_sites for the canonical value. The description's 'for a website' adds no syntax or format information beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the specific resource (sitemaps submitted for a website) and enumerates the data returned: last download time, URL count, and error/warning counts. It also draws a boundary against the write path ('submitting a sitemap is done in Search Console'), though it does not explicitly distinguish itself from the other read siblings like search_console_sites or search_console_performance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Changes nothing: submitting a sitemap is done in Search Console' gives an implicit when-not (do not use this to submit), but there is no explicit statement of when to reach for this tool over the other Search Console read tools. Usage is inferable from the purpose but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_console_sitesList Search Console sitesARead-onlyInspect
Lists the websites (Search Console properties) this Google login can read. Use a site_url from here in the other Search Console tools.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety and external-call profile is covered by structured data. The description adds the auth-scoping caveat (results are limited to this login's readable properties), which is useful for interpreting an empty result, but says nothing about pagination, latency, or live-call behavior. With annotations carrying the main burden, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler; the purpose comes first and the actionable next step second. Nothing could be removed without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter listing tool with no output schema, the description conveys what comes back conceptually (websites/properties) and names the field an agent will need downstream (site_url). It leaves return shape and pagination unspecified, but that is a minor gap against the low complexity of the call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4 per the rubric. The description's mention of site_url is an output reference rather than an input constraint, and adds no parameter meaning because there are no parameters to disambiguate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (lists Search Console properties) and adds a meaningful scope qualifier: only the sites this Google login can read. An agent can immediately tell this is the discovery/enumeration call for the Search Console family.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent downstream — 'Use a site_url from here in the other Search Console tools' — which is exactly the workflow context needed for a zero-argument lookup tool. It stops short of stating when not to call it, but no sibling competes for this job, so exclusions are unnecessary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_console_summarySearch Console summaryARead-onlyInspect
A website's total organic Google Search clicks, impressions, CTR and average position over a window, next to the same number of days before it, with the change. Site-wide totals, more complete than adding up per-query rows. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending 3 days ago (yesterday with fresh) | |
| fresh | No | Include the last 2-3 days, which Google is still filling in (they read low). Use to check something from the last few days | |
| end_date | No | Exact last day, YYYY-MM-DD | |
| site_url | Yes | Search Console property exactly as search_console_sites lists it, e.g. sc-domain:example.com or https://www.example.com/ | |
| start_date | No | Exact first day, YYYY-MM-DD. Pass with end_date to use exact dates instead of days |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so 'Changes nothing' largely restates the structured data. The description does add genuine behavioral context beyond annotations: the result is computed as a comparison against the same number of preceding days, and site-wide totals aren't derivable by summing per-query rows.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences that front-load the metrics and the comparison, with no filler. The dash-free compressed style is dense but every clause carries information about what is returned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so: it names the four metrics and the change versus the prior window. Read-only safety is covered by annotations, and the parameter space is covered by the schema, so nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents days, fresh, start_date, end_date and site_url, including formats and the 3-day lag. The description's 'over a window' adds only a vague gesture at the time parameters and no meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: total organic Search clicks, impressions, CTR and average position for a site over a window, plus prior-period comparison. The phrase 'Site-wide totals, more complete than adding up per-query rows' implicitly distinguishes it from the per-query performance tool, though it never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied – reach for this when you want site-wide totals and a period-over-period change rather than per-query detail. There is no explicit when-to-use/when-not statement and no alternative tool is named, so the agent must infer the routing against search_console_performance and search_console_trend.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_console_trendSearch Console trendARead-onlyInspect
Compares a window with the same number of days right before it, query by query and page by page: rising, falling, new and lost queries, rising searches the site is losing position on, and rising and falling pages. Totals are the site's true totals. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending 3 days ago (yesterday with fresh) | |
| fresh | No | Include the last 2-3 days, which Google is still filling in (they read low). Use to check something from the last few days | |
| limit | No | Most rows in each list | |
| end_date | No | Exact last day, YYYY-MM-DD | |
| site_url | Yes | Search Console property exactly as search_console_sites lists it, e.g. sc-domain:example.com or https://www.example.com/ | |
| start_date | No | Exact first day, YYYY-MM-DD. Pass with end_date to use exact dates instead of days | |
| min_impressions | No | Skip queries and pages under this many impressions in both windows | |
| exclude_query_regex | No | Leave out queries matching this RE2 regex, typically the brand name, e.g. (?i)acme|ac me |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint and destructiveHint, so 'Changes nothing' is largely redundant and safety is covered. The one genuinely additive behavioral note is 'Totals are the site's true totals', which warns that per-row sums may not reconcile with reported totals — a real trap in this data. No mention of rate limits, auth scope, or result-size behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler; the core action and comparison basis are front-loaded before the enumeration of output categories. The dense enumerated list in sentence one is justified because it tells the agent exactly what rows it will get back, though the trailing 'Changes nothing' is redundant against the readOnlyHint annotation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an eight-parameter tool with no output schema, the description carries the burden of describing returns and does so by naming the result categories, and the fully-covered schema handles invocation details. It is only slightly short of complete: how 'rising' is defined/thresholded and when to prefer this over search_console_performance are left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all eight parameters (days, fresh, limit, end_date, site_url, start_date, min_impressions, exclude_query_regex) are already documented in the schema, including the 3-day look-back lag and regex intent. The description adds no parameter-level detail beyond what the schema supplies, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and scope: it compares a window against the equally-sized window immediately before it, and enumerates the exact output categories (rising, falling, new and lost queries, losing-position searches, rising/falling pages). This is clearly distinguishable from search_console_performance or search_console_summary by its delta framing, though it never names a sibling to sharpen the contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The comparison framing implies the use case (period-over-period movement analysis), so an agent can infer when this beats the sibling summary/performance tools. However, it contains no explicit when-to-use, when-not, or 'use X instead' guidance across the eight sibling search_console_* tools, leaving the choice to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
switch_accountSwitch the plan's active accountADestructiveIdempotentInspect
Spends the plan's one account switch per 30 days on customer_id: it becomes an active account, and the least recently used active account locks until the date the "Account switch:" notice gave, switching back included. Call it only after another tool answered "Account switch:" for this account and the user agreed, or answered "Account choice:" and the user picked this account (a first pick spends no switch). Changes nothing in Google Ads; a no-op for an account that is already active.
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | Yes | Google Ads customer ID, with or without dashes (from list_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond annotations: it explains the 30-day switch budget, which account gets locked and until when, that switching back also counts, that Google Ads is unchanged, and that already-active accounts are a no-op. These details directly clarify the destructive and idempotent annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the key cost and effect, then states the gating conditions, then clarifies that no Google Ads change occurs. Every sentence carries necessary behavioral or usage information without filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-output-schema mutation tool with one parameter, the description covers the essential side effects, preconditions, edge cases, and no-op behavior. An agent has enough information to decide when and how to invoke it safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single customer_id parameter is already documented with format details and its source (list_accounts). The description does not add parameter-specific meaning beyond using customer_id as the target.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact action: spending the plan's 30-day account switch on customer_id, making it active, and locking the least recently used active account. This is specific and distinguishable from sibling tools like list_accounts or account_overview.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to call: only after another tool returned 'Account switch:' and the user agreed, or 'Account choice:' and the user picked this account. It also clarifies that a first pick spends no switch and that already-active accounts are a no-op.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undo_changesPropose reversing an applied proposalAInspect
Builds a new proposal that would reverse an applied one (removes the negatives it added, restores statuses and budgets). Changes nothing by itself: like any proposal, it must be approved and then applied with apply_changes.
| Name | Required | Description | Default |
|---|---|---|---|
| proposal_id | Yes | The id of an applied proposal, from change_history or apply_changes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The name 'undo_changes' implies immediate reversal, and the description corrects that misconception head-on: 'Changes nothing by itself: like any proposal, it must be approved and then applied with apply_changes.' It also discloses the concrete semantics of the reversal. This is context annotations cannot supply on their own.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, and the most important fact (it only builds a proposal) is placed immediately after the one-line purpose. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet an agent has everything needed: what the tool produces, that it is inert until approved and applied, and the required follow-up call. Nothing material is omitted for a single-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter and schema description coverage is 100%; the schema already tells the agent the id comes from change_history or apply_changes. The description adds no additional parameter meaning, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Builds a new proposal that would reverse an applied one') and enumerates the effects (removes negatives, restores statuses and budgets). This clearly separates it from propose_changes, apply_changes, and discard_proposal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Makes clear it targets an *applied* proposal and names the required follow-up path (approve, then apply_changes), which is exactly the routing an agent needs. It stops short of an explicit exclusion (e.g. use discard_proposal for a pending, un-applied proposal), so it's clear context rather than full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.20.0- Changed
propose_analytics_changes1 field changed- changed
Input schema / properties / changes / items / oneOfPrevious value: -[ - { - "description": "Create a GA4 property with a web data stream for the site; the result gives the measurement ID and the tag to add to every page", - "properties": { - "account_id": { - "description": "Google Analytics account id (from analytics_properties' accounts)", - "pattern": "^\\d+$", - "type": "string" - }, - "currency": { - "default": "USD", - "description": "Currency for revenue, ISO 4217", - "pattern": "^[A-Z]{3}$", - "type": "string" - }, - "name": { - "description": "Property name, usually the business or site", - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "time_zone": { - "description": "IANA time zone reports use, e.g. America/New_York", - "maxLength": 64, - "minLength": 3, - "type": "string" - }, - "type": { - "const": "create_ga4_property", - "type": "string" - }, - "website_url": { - "description": "The site's address, e.g. https://www.example.com", - "format": "uri", - "type": "string" - } - }, - "required": [ - "type", - "account_id", - "name", - "website_url", - "time_zone" - ], - "type": "object" - }, - { - "description": "Mark an event as a key event (GA4's conversion), so it is counted and can be imported into Google Ads", - "properties": { - "counting": { - "default": "ONCE_PER_EVENT", - "description": "ONCE_PER_EVENT counts every time; ONCE_PER_SESSION counts one per visit (leads)", - "enum": [ - "ONCE_PER_EVENT", - "ONCE_PER_SESSION" - ], - "type": "string" - }, - "event_name": { - "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends", - "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", - "type": "string" - }, - "property_id": { - "description": "GA4 property id (from analytics_properties)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "mark_key_event", - "type": "string" - } - }, - "required": [ - "type", - "property_id", - "event_name" - ], - "type": "object" - }, - { - "description": "Stop counting an event as a key event", - "properties": { - "event_name": { - "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends", - "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", - "type": "string" - }, - "property_id": { - "description": "GA4 property id (from analytics_properties)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "unmark_key_event", - "type": "string" - } - }, - "required": [ - "type", - "property_id", - "event_name" - ], - "type": "object" - }, - { - "description": "Link a GA4 property to a Google Ads account, so Ads can import its key events and GA4 shows ad clicks and cost (the user must be an admin of both)", - "properties": { - "customer_id": { - "description": "Google Ads customer ID, with or without dashes", - "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$", - "type": "string" - }, - "property_id": { - "description": "GA4 property id (from analytics_properties)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "link_google_ads", - "type": "string" - } - }, - "required": [ - "type", - "property_id", - "customer_id" - ], - "type": "object" - }, - { - "description": "Remove the link between a GA4 property and a Google Ads account", - "properties": { - "customer_id": { - "description": "Google Ads customer ID, with or without dashes", - "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$", - "type": "string" - }, - "property_id": { - "description": "GA4 property id (from analytics_properties)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "unlink_google_ads", - "type": "string" - } - }, - "required": [ - "type", - "property_id", - "customer_id" - ], - "type": "object" - } -]New value: +[ + { + "description": "Create a GA4 property with a web data stream for the site; the result gives the measurement ID and the tag to add to every page", + "properties": { + "account_id": { + "description": "Google Analytics account id (from analytics_properties' accounts)", + "pattern": "^\\d+$", + "type": "string" + }, + "currency": { + "default": "USD", + "description": "Currency for revenue, ISO 4217", + "pattern": "^[A-Z]{3}$", + "type": "string" + }, + "name": { + "description": "Property name, usually the business or site", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "time_zone": { + "description": "IANA time zone reports use, e.g. America/New_York", + "maxLength": 64, + "minLength": 3, + "type": "string" + }, + "type": { + "const": "create_ga4_property", + "type": "string" + }, + "website_url": { + "description": "The site's address, e.g. https://www.example.com", + "format": "uri", + "type": "string" + } + }, + "required": [ + "type", + "account_id", + "name", + "website_url", + "time_zone" + ], + "type": "object" + }, + { + "description": "Mark an event as a key event (GA4's conversion), so it is counted and can be imported into Google Ads", + "properties": { + "counting": { + "default": "ONCE_PER_EVENT", + "description": "ONCE_PER_EVENT counts every time; ONCE_PER_SESSION counts one per visit (leads)", + "enum": [ + "ONCE_PER_EVENT", + "ONCE_PER_SESSION" + ], + "type": "string" + }, + "event_name": { + "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends", + "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", + "type": "string" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "mark_key_event", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "event_name" + ], + "type": "object" + }, + { + "description": "Stop counting an event as a key event", + "properties": { + "event_name": { + "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends", + "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", + "type": "string" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "unmark_key_event", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "event_name" + ], + "type": "object" + }, + { + "description": "Recount an existing key event; a Google Ads action imported from it follows (ONCE_PER_SESSION is Ads' one per click)", + "properties": { + "counting": { + "description": "ONCE_PER_EVENT: every time; ONCE_PER_SESSION: one per visit", + "enum": [ + "ONCE_PER_EVENT", + "ONCE_PER_SESSION" + ], + "type": "string" + }, + "event_name": { + "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends", + "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", + "type": "string" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "set_key_event_counting", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "event_name", + "counting" + ], + "type": "object" + }, + { + "description": "Link a GA4 property to a Google Ads account, so Ads can import its key events and GA4 shows ad clicks and cost (the user must be an admin of both)", + "properties": { + "customer_id": { + "description": "Google Ads customer ID, with or without dashes", + "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$", + "type": "string" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "link_google_ads", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "customer_id" + ], + "type": "object" + }, + { + "description": "Remove the link between a GA4 property and a Google Ads account", + "properties": { + "customer_id": { + "description": "Google Ads customer ID, with or without dashes", + "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$", + "type": "string" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "unlink_google_ads", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "customer_id" + ], + "type": "object" + } +]
- Changed
propose_changes1 field changed- changed
Input schema / properties / changes / items / oneOfPrevious value: -[ - { - "description": "Block searches containing these words in one campaign", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE blocks any search containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "description": "The search words to block, e.g. \"free\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_negative_keywords", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "keywords" - ], - "type": "object" - }, - { - "description": "Pause one keyword", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_keyword", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused keyword", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_keyword", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id" - ], - "type": "object" - }, - { - "description": "Pause a whole campaign (stops all its spend)", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_campaign", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Turn a paused campaign back on. It starts spending again; the summary says how much", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_campaign", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Pause one ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id" - ], - "type": "object" - }, - { - "description": "Change a campaign's daily budget (not shared budgets)", - "properties": { - "amount": { - "description": "New average daily budget in the account's currency, e.g. 10 for $10.00/day (not micros)", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "set_daily_budget", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "amount" - ], - "type": "object" - }, - { - "description": "Set the last day a campaign runs, so it stops spending on its own", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "end_date": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "const": "none", - "type": "string" - } - ], - "description": "Last day the campaign runs, YYYY-MM-DD in the account's time zone (it stops after 23:59:59 that day), or \"none\" to remove the end date" - }, - "type": { - "const": "set_end_date", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "end_date" - ], - "type": "object" - }, - { - "description": "Build a new Search campaign with its ad groups, keywords, ads, targeting, negatives and sitelinks, in one step. It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "keywords", - "ads" - ], - "type": "object" - }, - "maxItems": 10, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MANUAL_CPC", - "description": "MANUAL_CPC uses the ad group and keyword max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English, 1003 Spanish", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States, 2826 United Kingdom, 2124 Canada (look others up in geo_target_constant)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "negative_keywords": { - "default": [], - "description": "Searches to block across the campaign", - "items": { - "properties": { - "match_type": { - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 200, - "type": "array" - }, - "presence_only": { - "default": true, - "description": "Show ads only to people IN the locations (true), not merely interested in them", - "type": "boolean" - }, - "search_partners": { - "default": false, - "description": "Also show on Google's search partner sites", - "type": "boolean" - }, - "sitelinks": { - "default": [], - "items": { - "properties": { - "description1": { - "description": "At most 35 characters; give both descriptions or neither", - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "description2": { - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "text": { - "description": "Link text, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "url": { - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - } - }, - "required": [ - "text", - "url" - ], - "type": "object" - }, - "maxItems": 8, - "type": "array" - }, - "type": { - "const": "create_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Display campaign (image ads across Google's Display Network of sites and apps) with ad groups and responsive display ads. Google's optimized targeting finds the audience. It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A responsive display ad: Google assembles ads from these headlines, descriptions and images", - "properties": { - "business_name": { - "description": "The advertiser's name, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "descriptions": { - "description": "1 to 5 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "1 to 5 short headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "logo_images": { - "default": [], - "description": "0 to 5 landscape logos, 4:1 (e.g. 1200×300, at least 512×128)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 0, - "type": "array" - }, - "long_headline": { - "description": "One long headline, at most 90 characters", - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "marketing_images": { - "description": "1 to 15 landscape images, 1.91:1 (e.g. 1200×628, at least 600×314)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 1, - "type": "array" - }, - "square_logo_images": { - "default": [], - "description": "0 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 0, - "type": "array" - }, - "square_marketing_images": { - "description": "1 to 15 square images, 1:1 (e.g. 1200×1200, at least 300×300)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "headlines", - "long_headline", - "descriptions", - "business_name", - "final_url", - "marketing_images", - "square_marketing_images" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "ads" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CLICKS", - "description": "MANUAL_CPC uses the ad groups' max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "presence_only": { - "default": true, - "description": "Show ads only to people IN the locations (true), not merely interested in them", - "type": "boolean" - }, - "type": { - "const": "create_display_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Demand Gen campaign with YouTube video ads, which is how to advertise on YouTube through the API (Google doesn't allow creating Video campaigns there). It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A Demand Gen video ad: runs on YouTube (in-stream, in-feed and Shorts), Discover and Gmail", - "properties": { - "business_name": { - "description": "The advertiser's name, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "descriptions": { - "description": "1 to 5 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "1 to 5 headlines, each at most 40 characters", - "items": { - "maxLength": 40, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "logo_image": { - "description": "A square 1:1 logo (e.g. 1200×1200, at least 128×128): an https URL, or an image asset id from the account", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "long_headlines": { - "description": "1 to 5 long headlines, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "videos": { - "description": "1 to 5 YouTube videos", - "items": { - "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "videos", - "headlines", - "long_headlines", - "descriptions", - "business_name", - "logo_image", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States (Demand Gen targets locations per ad group, not per campaign)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "ads" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CONVERSIONS", - "description": "Demand Gen bids automatically: MAXIMIZE_CONVERSIONS (needs conversion tracking) or MAXIMIZE_CLICKS", - "enum": [ - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CLICKS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "create_demand_gen_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Performance Max campaign: one budget, Google places ads across Search, YouTube, Display, Discover, Gmail and Maps from the asset groups' text, images and videos. No shopping feed (non-retail). It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "asset_groups": { - "items": { - "description": "An asset group: the headlines, descriptions, images and videos Google combines into ads on every channel", - "properties": { - "descriptions": { - "description": "2 to 5 descriptions, each at most 90 characters; Google recommends one of 60 or fewer", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page (Google may also send people to other pages on the same site)", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "long_headlines": { - "description": "1 to 5 long headlines, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "marketing_images": { - "description": "1 to 20 landscape images, 1.91:1 (e.g. 1200×628)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "portrait_marketing_images": { - "default": [], - "description": "0 to 20 portrait images, 4:5 (e.g. 960×1200)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 0, - "type": "array" - }, - "square_marketing_images": { - "description": "1 to 20 square images, 1:1 (e.g. 1200×1200)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "videos": { - "default": [], - "description": "0 to 5 YouTube videos; without one, Google may auto-generate a video from the images", - "items": { - "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "type": "array" - } - }, - "required": [ - "name", - "final_url", - "headlines", - "long_headlines", - "descriptions", - "marketing_images", - "square_marketing_images" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CONVERSIONS", - "description": "Performance Max bids for conversions only: MAXIMIZE_CONVERSIONS, or MAXIMIZE_CONVERSION_VALUE when conversions carry values", - "enum": [ - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CONVERSION_VALUE" - ], - "type": "string" - }, - "business_name": { - "description": "The advertiser's name, at most 25 characters (linked to the campaign, per Google's brand guidelines)", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "logo_images": { - "description": "1 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128), linked to the campaign", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "target_cpa": { - "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "create_performance_max_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "business_name", - "logo_images", - "asset_groups" - ], - "type": "object" - }, - { - "description": "Add an ad group, with its keywords and ads, to an existing Search campaign", - "properties": { - "ad_group": { - "properties": { - "ads": { - "items": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "keywords", - "ads" - ], - "type": "object" - }, - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "add_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "ad_group" - ], - "type": "object" - }, - { - "description": "Add keywords to an existing ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_keywords", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "keywords" - ], - "type": "object" - }, - { - "description": "Add a responsive search ad to an existing ad group", - "properties": { - "ad": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "add_responsive_search_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad" - ], - "type": "object" - }, - { - "description": "Add sitelinks to a campaign", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "sitelinks": { - "items": { - "properties": { - "description1": { - "description": "At most 35 characters; give both descriptions or neither", - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "description2": { - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "text": { - "description": "Link text, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "url": { - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - } - }, - "required": [ - "text", - "url" - ], - "type": "object" - }, - "maxItems": 8, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_sitelinks", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "sitelinks" - ], - "type": "object" - }, - { - "description": "Make a campaign count and bid on ONE conversion category only (e.g. SIGNUP), so another product's or step's conversions don't steer it", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "category": { - "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", - "pattern": "^[A-Z_]+$", - "type": "string" - }, - "type": { - "const": "set_conversion_goal", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "category" - ], - "type": "object" - }, - { - "description": "Change one keyword's max CPC (manual CPC campaigns)", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc": { - "anyOf": [ - { - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - { - "type": "null" - } - ], - "description": "New max cost per click for this keyword, or null to clear it so the keyword uses the ad group's bid" - }, - "type": { - "const": "set_keyword_bid", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id", - "max_cpc" - ], - "type": "object" - }, - { - "description": "Change an ad group's default max CPC, which its keywords use unless they have their own", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc": { - "description": "New default max cost per click for the ad group", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_ad_group_bid", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "max_cpc" - ], - "type": "object" - }, - { - "description": "Pause one ad", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "ad_id": { - "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused ad", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "ad_id": { - "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad_id" - ], - "type": "object" - }, - { - "description": "Add locations and/or languages a campaign targets", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "language_ids": { - "default": [], - "description": "Language ids to add, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "type": "array" - }, - "location_ids": { - "default": [], - "description": "Geo target ids to add, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "type": { - "const": "add_campaign_targeting", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Stop targeting some of a campaign's locations and/or languages", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "language_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "type": "array" - }, - "location_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "type": { - "const": "remove_campaign_targeting", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Choose whether a campaign shows to people in its locations only, or also to people interested in them", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "presence_only": { - "description": "true: only people IN the locations; false: also people interested in them", - "type": "boolean" - }, - "type": { - "const": "set_location_mode", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "presence_only" - ], - "type": "object" - }, - { - "description": "Switch ONE campaign's bid strategy. A campaign on a shared (portfolio) strategy moves off it onto its own; the other campaigns on the shared strategy keep it. To change the shared strategy for every campaign on it, use set_shared_bid_strategy. If the user didn't say which they mean, ask. Google re-learns after a switch, so performance can wobble for a week or two", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "strategy": { - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "target_cpa": { - "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_bidding_strategy", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "strategy" - ], - "type": "object" - }, - { - "description": "Change a shared (portfolio) bid strategy's targets. This changes EVERY campaign on it, which the proposal lists. Its type can't be changed; to move one campaign to another strategy, use set_bidding_strategy", - "properties": { - "bidding_strategy_id": { - "description": "Shared (portfolio) strategy id: bidding_strategy.id from run_gaql, or the id at the end of campaign.bidding_strategy", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc_ceiling": { - "description": "The most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_cpa": { - "description": "Target cost per conversion (TARGET_CPA and MAXIMIZE_CONVERSIONS strategies)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_roas": { - "description": "Target return on ad spend as a ratio, e.g. 4 = 400% (TARGET_ROAS and MAXIMIZE_CONVERSION_VALUE)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_shared_bid_strategy", - "type": "string" - } - }, - "required": [ - "type", - "bidding_strategy_id" - ], - "type": "object" - }, - { - "description": "Create a shared (portfolio) bid strategy, optionally moving campaigns onto it. Undo moves those campaigns back and removes it", - "properties": { - "campaign_ids": { - "default": [], - "description": "Campaigns to move onto it in the same step (each leaves its current strategy)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "The most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Name for the shared strategy; must not match an existing one", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "strategy": { - "enum": [ - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CONVERSION_VALUE", - "TARGET_CPA", - "TARGET_ROAS" - ], - "type": "string" - }, - "target_cpa": { - "description": "Target cost per conversion: required for TARGET_CPA, optional for MAXIMIZE_CONVERSIONS", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_roas": { - "description": "Target return on ad spend as a ratio, e.g. 4 = 400%: required for TARGET_ROAS, optional for MAXIMIZE_CONVERSION_VALUE", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "create_shared_bid_strategy", - "type": "string" - } - }, - "required": [ - "type", - "name", - "strategy" - ], - "type": "object" - }, - { - "description": "Set or clear a campaign's final URL suffix (tracking parameters on every ad click)", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "suffix": { - "description": "Query string Google appends to every landing page in the campaign, e.g. \"utm_source=google&utm_medium=cpc&utm_term={keyword}\", or \"none\" to clear it", - "maxLength": 1000, - "type": "string" - }, - "type": { - "const": "set_url_suffix", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "suffix" - ], - "type": "object" - }, - { - "description": "Declare whether a campaign contains EU political advertising. While any campaign lacks this declaration, Google refuses every change to the account (EU_POLITICAL_ADVERTISING_DECLARATION_REQUIRED); find those campaigns with campaign.missing_eu_political_advertising_declaration = TRUE. It is the advertiser's own legal statement: ask the user, never assume the answer", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "contains_eu_political_advertising": { - "description": "The user's answer: true only if the campaign carries political ads under EU rules (about an election, a referendum, or a law or regulation, shown in the EU)", - "type": "boolean" - }, - "type": { - "const": "set_eu_political_advertising", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "contains_eu_political_advertising" - ], - "type": "object" - }, - { - "description": "Create a conversion action to measure sign-ups, leads or purchases", - "properties": { - "category": { - "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", - "pattern": "^[A-Z_]+$", - "type": "string" - }, - "counting": { - "default": "ONE_PER_CLICK", - "description": "ONE_PER_CLICK for sign-ups and leads; MANY_PER_CLICK for purchases", - "enum": [ - "ONE_PER_CLICK", - "MANY_PER_CLICK" - ], - "type": "string" - }, - "default_value": { - "description": "Value per conversion when none is sent", - "maximum": 1000000, - "minimum": 0, - "type": "number" - }, - "name": { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "primary": { - "default": true, - "description": "Primary actions count in Conversions and can steer bidding", - "type": "boolean" - }, - "source": { - "default": "UPLOAD_CLICKS", - "description": "UPLOAD_CLICKS: your server uploads ad click ids (no Google tag). WEBPAGE: Google gives you a tag to put on the page", - "enum": [ - "UPLOAD_CLICKS", - "WEBPAGE" - ], - "type": "string" - }, - "type": { - "const": "create_conversion_action", - "type": "string" - } - }, - "required": [ - "type", - "name", - "category" - ], - "type": "object" - }, - { - "description": "Set how many conversions one ad click can produce for a conversion action", - "properties": { - "conversion_action_id": { - "description": "conversion_action.id from run_gaql", - "pattern": "^\\d+$", - "type": "string" - }, - "counting": { - "enum": [ - "ONE_PER_CLICK", - "MANY_PER_CLICK" - ], - "type": "string" - }, - "type": { - "const": "set_conversion_counting", - "type": "string" - } - }, - "required": [ - "type", - "conversion_action_id", - "counting" - ], - "type": "object" - }, - { - "description": "Import a GA4 key event into Google Ads as a conversion action, so campaigns can count and bid on it. The GA4 property must be linked to this account", - "properties": { - "event_name": { - "description": "The GA4 key event, e.g. generate_lead, purchase, sign_up", - "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", - "type": "string" - }, - "primary": { - "default": true, - "description": "Primary actions count in Conversions and can steer bidding", - "type": "boolean" - }, - "property_id": { - "description": "GA4 property id (from analytics_properties)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "import_ga4_key_event", - "type": "string" - } - }, - "required": [ - "type", - "property_id", - "event_name" - ], - "type": "object" - } -]New value: +[ + { + "description": "Block searches containing these words in one campaign", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE blocks any search containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "description": "The search words to block, e.g. \"free\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_negative_keywords", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Pause one keyword", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused keyword", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Pause a whole campaign (stops all its spend)", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Turn a paused campaign back on. It starts spending again; the summary says how much", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Pause one ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Change a campaign's daily budget (not shared budgets)", + "properties": { + "amount": { + "description": "New average daily budget in the account's currency, e.g. 10 for $10.00/day (not micros)", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "set_daily_budget", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "amount" + ], + "type": "object" + }, + { + "description": "Set the last day a campaign runs, so it stops spending on its own", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "end_date": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "const": "none", + "type": "string" + } + ], + "description": "Last day the campaign runs, YYYY-MM-DD in the account's time zone (it stops after 23:59:59 that day), or \"none\" to remove the end date" + }, + "type": { + "const": "set_end_date", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "end_date" + ], + "type": "object" + }, + { + "description": "Build a new Search campaign with its ad groups, keywords, ads, targeting, negatives and sitelinks, in one step. It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "keywords", + "ads" + ], + "type": "object" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MANUAL_CPC", + "description": "MANUAL_CPC uses the ad group and keyword max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English, 1003 Spanish", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States, 2826 United Kingdom, 2124 Canada (look others up in geo_target_constant)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "negative_keywords": { + "default": [], + "description": "Searches to block across the campaign", + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 200, + "type": "array" + }, + "presence_only": { + "default": true, + "description": "Show ads only to people IN the locations (true), not merely interested in them", + "type": "boolean" + }, + "search_partners": { + "default": false, + "description": "Also show on Google's search partner sites", + "type": "boolean" + }, + "sitelinks": { + "default": [], + "items": { + "properties": { + "description1": { + "description": "At most 35 characters; give both descriptions or neither", + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "description2": { + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "text": { + "description": "Link text, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + } + }, + "required": [ + "text", + "url" + ], + "type": "object" + }, + "maxItems": 8, + "type": "array" + }, + "type": { + "const": "create_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Display campaign (image ads across Google's Display Network of sites and apps) with ad groups and responsive display ads. Google's optimized targeting finds the audience. It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A responsive display ad: Google assembles ads from these headlines, descriptions and images", + "properties": { + "business_name": { + "description": "The advertiser's name, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "descriptions": { + "description": "1 to 5 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "1 to 5 short headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "logo_images": { + "default": [], + "description": "0 to 5 landscape logos, 4:1 (e.g. 1200×300, at least 512×128)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "long_headline": { + "description": "One long headline, at most 90 characters", + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "marketing_images": { + "description": "1 to 15 landscape images, 1.91:1 (e.g. 1200×628, at least 600×314)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 1, + "type": "array" + }, + "square_logo_images": { + "default": [], + "description": "0 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "square_marketing_images": { + "description": "1 to 15 square images, 1:1 (e.g. 1200×1200, at least 300×300)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "headlines", + "long_headline", + "descriptions", + "business_name", + "final_url", + "marketing_images", + "square_marketing_images" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "ads" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CLICKS", + "description": "MANUAL_CPC uses the ad groups' max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "presence_only": { + "default": true, + "description": "Show ads only to people IN the locations (true), not merely interested in them", + "type": "boolean" + }, + "type": { + "const": "create_display_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Demand Gen campaign with YouTube video ads, which is how to advertise on YouTube through the API (Google doesn't allow creating Video campaigns there). It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A Demand Gen video ad: runs on YouTube (in-stream, in-feed and Shorts), Discover and Gmail", + "properties": { + "business_name": { + "description": "The advertiser's name, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "descriptions": { + "description": "1 to 5 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "1 to 5 headlines, each at most 40 characters", + "items": { + "maxLength": 40, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "logo_image": { + "description": "A square 1:1 logo (e.g. 1200×1200, at least 128×128): an https URL, or an image asset id from the account", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "long_headlines": { + "description": "1 to 5 long headlines, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "videos": { + "description": "1 to 5 YouTube videos", + "items": { + "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "videos", + "headlines", + "long_headlines", + "descriptions", + "business_name", + "logo_image", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States (Demand Gen targets locations per ad group, not per campaign)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "ads" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CONVERSIONS", + "description": "Demand Gen bids automatically: MAXIMIZE_CONVERSIONS (needs conversion tracking) or MAXIMIZE_CLICKS", + "enum": [ + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CLICKS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "create_demand_gen_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Performance Max campaign: one budget, Google places ads across Search, YouTube, Display, Discover, Gmail and Maps from the asset groups' text, images and videos. No shopping feed (non-retail). It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "asset_groups": { + "items": { + "description": "An asset group: the headlines, descriptions, images and videos Google combines into ads on every channel", + "properties": { + "descriptions": { + "description": "2 to 5 descriptions, each at most 90 characters; Google recommends one of 60 or fewer", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page (Google may also send people to other pages on the same site)", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "long_headlines": { + "description": "1 to 5 long headlines, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "marketing_images": { + "description": "1 to 20 landscape images, 1.91:1 (e.g. 1200×628)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "portrait_marketing_images": { + "default": [], + "description": "0 to 20 portrait images, 4:5 (e.g. 960×1200)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 0, + "type": "array" + }, + "square_marketing_images": { + "description": "1 to 20 square images, 1:1 (e.g. 1200×1200)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "videos": { + "default": [], + "description": "0 to 5 YouTube videos; without one, Google may auto-generate a video from the images", + "items": { + "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "type": "array" + } + }, + "required": [ + "name", + "final_url", + "headlines", + "long_headlines", + "descriptions", + "marketing_images", + "square_marketing_images" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CONVERSIONS", + "description": "Performance Max bids for conversions only: MAXIMIZE_CONVERSIONS, or MAXIMIZE_CONVERSION_VALUE when conversions carry values", + "enum": [ + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CONVERSION_VALUE" + ], + "type": "string" + }, + "business_name": { + "description": "The advertiser's name, at most 25 characters (linked to the campaign, per Google's brand guidelines)", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "logo_images": { + "description": "1 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128), linked to the campaign", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "target_cpa": { + "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "create_performance_max_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "business_name", + "logo_images", + "asset_groups" + ], + "type": "object" + }, + { + "description": "Add an ad group, with its keywords and ads, to an existing Search campaign", + "properties": { + "ad_group": { + "properties": { + "ads": { + "items": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "keywords", + "ads" + ], + "type": "object" + }, + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "add_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "ad_group" + ], + "type": "object" + }, + { + "description": "Add keywords to an existing ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_keywords", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Add a responsive search ad to an existing ad group", + "properties": { + "ad": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "add_responsive_search_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad" + ], + "type": "object" + }, + { + "description": "Add sitelinks to a campaign", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "sitelinks": { + "items": { + "properties": { + "description1": { + "description": "At most 35 characters; give both descriptions or neither", + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "description2": { + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "text": { + "description": "Link text, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + } + }, + "required": [ + "text", + "url" + ], + "type": "object" + }, + "maxItems": 8, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_sitelinks", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "sitelinks" + ], + "type": "object" + }, + { + "description": "Make a campaign count and bid on ONE conversion category only (e.g. SIGNUP), so another product's or step's conversions don't steer it", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "category": { + "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", + "pattern": "^[A-Z_]+$", + "type": "string" + }, + "type": { + "const": "set_conversion_goal", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "category" + ], + "type": "object" + }, + { + "description": "Change one keyword's max CPC (manual CPC campaigns)", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc": { + "anyOf": [ + { + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + { + "type": "null" + } + ], + "description": "New max cost per click for this keyword, or null to clear it so the keyword uses the ad group's bid" + }, + "type": { + "const": "set_keyword_bid", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id", + "max_cpc" + ], + "type": "object" + }, + { + "description": "Change an ad group's default max CPC, which its keywords use unless they have their own", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc": { + "description": "New default max cost per click for the ad group", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_ad_group_bid", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "max_cpc" + ], + "type": "object" + }, + { + "description": "Pause one ad", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused ad", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Add locations and/or languages a campaign targets", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "language_ids": { + "default": [], + "description": "Language ids to add, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "location_ids": { + "default": [], + "description": "Geo target ids to add, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "type": { + "const": "add_campaign_targeting", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Stop targeting some of a campaign's locations and/or languages", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "language_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "location_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "type": { + "const": "remove_campaign_targeting", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Choose whether a campaign shows to people in its locations only, or also to people interested in them", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "presence_only": { + "description": "true: only people IN the locations; false: also people interested in them", + "type": "boolean" + }, + "type": { + "const": "set_location_mode", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "presence_only" + ], + "type": "object" + }, + { + "description": "Switch ONE campaign's bid strategy. A campaign on a shared (portfolio) strategy moves off it onto its own; the other campaigns on the shared strategy keep it. To change the shared strategy for every campaign on it, use set_shared_bid_strategy. If the user didn't say which they mean, ask. Google re-learns after a switch, so performance can wobble for a week or two", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "strategy": { + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "target_cpa": { + "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_bidding_strategy", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "strategy" + ], + "type": "object" + }, + { + "description": "Change a shared (portfolio) bid strategy's targets. This changes EVERY campaign on it, which the proposal lists. Its type can't be changed; to move one campaign to another strategy, use set_bidding_strategy", + "properties": { + "bidding_strategy_id": { + "description": "Shared (portfolio) strategy id: bidding_strategy.id from run_gaql, or the id at the end of campaign.bidding_strategy", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc_ceiling": { + "description": "The most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_cpa": { + "description": "Target cost per conversion (TARGET_CPA and MAXIMIZE_CONVERSIONS strategies)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_roas": { + "description": "Target return on ad spend as a ratio, e.g. 4 = 400% (TARGET_ROAS and MAXIMIZE_CONVERSION_VALUE)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_shared_bid_strategy", + "type": "string" + } + }, + "required": [ + "type", + "bidding_strategy_id" + ], + "type": "object" + }, + { + "description": "Create a shared (portfolio) bid strategy, optionally moving campaigns onto it. Undo moves those campaigns back and removes it", + "properties": { + "campaign_ids": { + "default": [], + "description": "Campaigns to move onto it in the same step (each leaves its current strategy)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "The most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Name for the shared strategy; must not match an existing one", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "strategy": { + "enum": [ + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CONVERSION_VALUE", + "TARGET_CPA", + "TARGET_ROAS" + ], + "type": "string" + }, + "target_cpa": { + "description": "Target cost per conversion: required for TARGET_CPA, optional for MAXIMIZE_CONVERSIONS", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_roas": { + "description": "Target return on ad spend as a ratio, e.g. 4 = 400%: required for TARGET_ROAS, optional for MAXIMIZE_CONVERSION_VALUE", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "create_shared_bid_strategy", + "type": "string" + } + }, + "required": [ + "type", + "name", + "strategy" + ], + "type": "object" + }, + { + "description": "Set or clear a campaign's final URL suffix (tracking parameters on every ad click)", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "suffix": { + "description": "Query string Google appends to every landing page in the campaign, e.g. \"utm_source=google&utm_medium=cpc&utm_term={keyword}\", or \"none\" to clear it", + "maxLength": 1000, + "type": "string" + }, + "type": { + "const": "set_url_suffix", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "suffix" + ], + "type": "object" + }, + { + "description": "Declare whether a campaign contains EU political advertising. While any campaign lacks this declaration, Google refuses every change to the account (EU_POLITICAL_ADVERTISING_DECLARATION_REQUIRED); find those campaigns with campaign.missing_eu_political_advertising_declaration = TRUE. It is the advertiser's own legal statement: ask the user, never assume the answer", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "contains_eu_political_advertising": { + "description": "The user's answer: true only if the campaign carries political ads under EU rules (about an election, a referendum, or a law or regulation, shown in the EU)", + "type": "boolean" + }, + "type": { + "const": "set_eu_political_advertising", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "contains_eu_political_advertising" + ], + "type": "object" + }, + { + "description": "Create a conversion action to measure sign-ups, leads or purchases", + "properties": { + "call_min_seconds": { + "description": "AD_CALL and WEBSITE_CALL only: how long a call must last to count (default 60)", + "maximum": 10000, + "minimum": 0, + "type": "integer" + }, + "category": { + "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", + "pattern": "^[A-Z_]+$", + "type": "string" + }, + "counting": { + "default": "ONE_PER_CLICK", + "description": "ONE_PER_CLICK for sign-ups and leads; MANY_PER_CLICK for purchases", + "enum": [ + "ONE_PER_CLICK", + "MANY_PER_CLICK" + ], + "type": "string" + }, + "default_value": { + "description": "Value per conversion when none is sent", + "maximum": 1000000, + "minimum": 0, + "type": "number" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "primary": { + "default": true, + "description": "Primary actions count in Conversions and can steer bidding", + "type": "boolean" + }, + "source": { + "default": "UPLOAD_CLICKS", + "description": "UPLOAD_CLICKS: your server uploads ad click ids (no Google tag). WEBPAGE: Google gives you a tag to put on the page. AD_CALL: calls from the phone number in ads (call assets). WEBSITE_CALL: calls to a Google forwarding number on the site (needs Google's tag)", + "enum": [ + "UPLOAD_CLICKS", + "WEBPAGE", + "AD_CALL", + "WEBSITE_CALL" + ], + "type": "string" + }, + "type": { + "const": "create_conversion_action", + "type": "string" + } + }, + "required": [ + "type", + "name", + "category" + ], + "type": "object" + }, + { + "description": "Set how many conversions one ad click can produce for a conversion action", + "properties": { + "conversion_action_id": { + "description": "conversion_action.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + }, + "counting": { + "enum": [ + "ONE_PER_CLICK", + "MANY_PER_CLICK" + ], + "type": "string" + }, + "type": { + "const": "set_conversion_counting", + "type": "string" + } + }, + "required": [ + "type", + "conversion_action_id", + "counting" + ], + "type": "object" + }, + { + "description": "Import a GA4 key event into Google Ads as a conversion action, so campaigns can count and bid on it. The GA4 property must be linked to this account", + "properties": { + "event_name": { + "description": "The GA4 key event, e.g. generate_lead, purchase, sign_up", + "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", + "type": "string" + }, + "primary": { + "default": true, + "description": "Primary actions count in Conversions and can steer bidding", + "type": "boolean" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "import_ga4_key_event", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "event_name" + ], + "type": "object" + }, + { + "description": "Remove a conversion action. Permanent unless a GA4 import: say so before they approve", + "properties": { + "conversion_action_id": { + "description": "conversion_action.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "remove_conversion_action", + "type": "string" + } + }, + "required": [ + "type", + "conversion_action_id" + ], + "type": "object" + } +]
1 tool update
v0.19.0- Changed
analytics_report1 field changed- changed
Input schema / properties / order_by / descriptionPrevious value: -"Metric to sort by, highest first; defaults to the first metric"New value: +"A requested metric (highest first) or dimension (A to Z, dates oldest first); defaults to the first metric"
1 tool update
v0.18.0- Changed
propose_changes1 field changed- changed
Input schema / properties / changes / items / oneOfPrevious value: -[ - { - "description": "Block searches containing these words in one campaign", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE blocks any search containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "description": "The search words to block, e.g. \"free\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_negative_keywords", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "keywords" - ], - "type": "object" - }, - { - "description": "Pause one keyword", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_keyword", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused keyword", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_keyword", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id" - ], - "type": "object" - }, - { - "description": "Pause a whole campaign (stops all its spend)", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_campaign", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Turn a paused campaign back on. It starts spending again; the summary says how much", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_campaign", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Pause one ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id" - ], - "type": "object" - }, - { - "description": "Change a campaign's daily budget (not shared budgets)", - "properties": { - "amount": { - "description": "New average daily budget in the account's currency, e.g. 10 for $10.00/day (not micros)", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "set_daily_budget", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "amount" - ], - "type": "object" - }, - { - "description": "Set the last day a campaign runs, so it stops spending on its own", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "end_date": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "const": "none", - "type": "string" - } - ], - "description": "Last day the campaign runs, YYYY-MM-DD in the account's time zone (it stops after 23:59:59 that day), or \"none\" to remove the end date" - }, - "type": { - "const": "set_end_date", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "end_date" - ], - "type": "object" - }, - { - "description": "Build a new Search campaign with its ad groups, keywords, ads, targeting, negatives and sitelinks, in one step. It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "keywords", - "ads" - ], - "type": "object" - }, - "maxItems": 10, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MANUAL_CPC", - "description": "MANUAL_CPC uses the ad group and keyword max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English, 1003 Spanish", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States, 2826 United Kingdom, 2124 Canada (look others up in geo_target_constant)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "negative_keywords": { - "default": [], - "description": "Searches to block across the campaign", - "items": { - "properties": { - "match_type": { - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 200, - "type": "array" - }, - "presence_only": { - "default": true, - "description": "Show ads only to people IN the locations (true), not merely interested in them", - "type": "boolean" - }, - "search_partners": { - "default": false, - "description": "Also show on Google's search partner sites", - "type": "boolean" - }, - "sitelinks": { - "default": [], - "items": { - "properties": { - "description1": { - "description": "At most 35 characters; give both descriptions or neither", - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "description2": { - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "text": { - "description": "Link text, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "url": { - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - } - }, - "required": [ - "text", - "url" - ], - "type": "object" - }, - "maxItems": 8, - "type": "array" - }, - "type": { - "const": "create_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Display campaign (image ads across Google's Display Network of sites and apps) with ad groups and responsive display ads. Google's optimized targeting finds the audience. It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A responsive display ad: Google assembles ads from these headlines, descriptions and images", - "properties": { - "business_name": { - "description": "The advertiser's name, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "descriptions": { - "description": "1 to 5 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "1 to 5 short headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "logo_images": { - "default": [], - "description": "0 to 5 landscape logos, 4:1 (e.g. 1200×300, at least 512×128)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 0, - "type": "array" - }, - "long_headline": { - "description": "One long headline, at most 90 characters", - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "marketing_images": { - "description": "1 to 15 landscape images, 1.91:1 (e.g. 1200×628, at least 600×314)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 1, - "type": "array" - }, - "square_logo_images": { - "default": [], - "description": "0 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 0, - "type": "array" - }, - "square_marketing_images": { - "description": "1 to 15 square images, 1:1 (e.g. 1200×1200, at least 300×300)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "headlines", - "long_headline", - "descriptions", - "business_name", - "final_url", - "marketing_images", - "square_marketing_images" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "ads" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CLICKS", - "description": "MANUAL_CPC uses the ad groups' max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "presence_only": { - "default": true, - "description": "Show ads only to people IN the locations (true), not merely interested in them", - "type": "boolean" - }, - "type": { - "const": "create_display_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Demand Gen campaign with YouTube video ads, which is how to advertise on YouTube through the API (Google doesn't allow creating Video campaigns there). It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A Demand Gen video ad: runs on YouTube (in-stream, in-feed and Shorts), Discover and Gmail", - "properties": { - "business_name": { - "description": "The advertiser's name, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "descriptions": { - "description": "1 to 5 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "1 to 5 headlines, each at most 40 characters", - "items": { - "maxLength": 40, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "logo_image": { - "description": "A square 1:1 logo (e.g. 1200×1200, at least 128×128): an https URL, or an image asset id from the account", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "long_headlines": { - "description": "1 to 5 long headlines, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "videos": { - "description": "1 to 5 YouTube videos", - "items": { - "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "videos", - "headlines", - "long_headlines", - "descriptions", - "business_name", - "logo_image", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States (Demand Gen targets locations per ad group, not per campaign)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "ads" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CONVERSIONS", - "description": "Demand Gen bids automatically: MAXIMIZE_CONVERSIONS (needs conversion tracking) or MAXIMIZE_CLICKS", - "enum": [ - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CLICKS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "create_demand_gen_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Performance Max campaign: one budget, Google places ads across Search, YouTube, Display, Discover, Gmail and Maps from the asset groups' text, images and videos. No shopping feed (non-retail). It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "asset_groups": { - "items": { - "description": "An asset group: the headlines, descriptions, images and videos Google combines into ads on every channel", - "properties": { - "descriptions": { - "description": "2 to 5 descriptions, each at most 90 characters; Google recommends one of 60 or fewer", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page (Google may also send people to other pages on the same site)", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "long_headlines": { - "description": "1 to 5 long headlines, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "marketing_images": { - "description": "1 to 20 landscape images, 1.91:1 (e.g. 1200×628)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "portrait_marketing_images": { - "default": [], - "description": "0 to 20 portrait images, 4:5 (e.g. 960×1200)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 0, - "type": "array" - }, - "square_marketing_images": { - "description": "1 to 20 square images, 1:1 (e.g. 1200×1200)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "videos": { - "default": [], - "description": "0 to 5 YouTube videos; without one, Google may auto-generate a video from the images", - "items": { - "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "type": "array" - } - }, - "required": [ - "name", - "final_url", - "headlines", - "long_headlines", - "descriptions", - "marketing_images", - "square_marketing_images" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CONVERSIONS", - "description": "Performance Max bids for conversions only: MAXIMIZE_CONVERSIONS, or MAXIMIZE_CONVERSION_VALUE when conversions carry values", - "enum": [ - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CONVERSION_VALUE" - ], - "type": "string" - }, - "business_name": { - "description": "The advertiser's name, at most 25 characters (linked to the campaign, per Google's brand guidelines)", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "logo_images": { - "description": "1 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128), linked to the campaign", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "target_cpa": { - "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "create_performance_max_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "business_name", - "logo_images", - "asset_groups" - ], - "type": "object" - }, - { - "description": "Add an ad group, with its keywords and ads, to an existing Search campaign", - "properties": { - "ad_group": { - "properties": { - "ads": { - "items": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "keywords", - "ads" - ], - "type": "object" - }, - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "add_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "ad_group" - ], - "type": "object" - }, - { - "description": "Add keywords to an existing ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_keywords", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "keywords" - ], - "type": "object" - }, - { - "description": "Add a responsive search ad to an existing ad group", - "properties": { - "ad": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "add_responsive_search_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad" - ], - "type": "object" - }, - { - "description": "Add sitelinks to a campaign", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "sitelinks": { - "items": { - "properties": { - "description1": { - "description": "At most 35 characters; give both descriptions or neither", - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "description2": { - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "text": { - "description": "Link text, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "url": { - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - } - }, - "required": [ - "text", - "url" - ], - "type": "object" - }, - "maxItems": 8, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_sitelinks", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "sitelinks" - ], - "type": "object" - }, - { - "description": "Make a campaign count and bid on ONE conversion category only (e.g. SIGNUP), so another product's or step's conversions don't steer it", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "category": { - "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", - "pattern": "^[A-Z_]+$", - "type": "string" - }, - "type": { - "const": "set_conversion_goal", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "category" - ], - "type": "object" - }, - { - "description": "Change one keyword's max CPC (manual CPC campaigns)", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc": { - "anyOf": [ - { - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - { - "type": "null" - } - ], - "description": "New max cost per click for this keyword, or null to clear it so the keyword uses the ad group's bid" - }, - "type": { - "const": "set_keyword_bid", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id", - "max_cpc" - ], - "type": "object" - }, - { - "description": "Change an ad group's default max CPC, which its keywords use unless they have their own", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc": { - "description": "New default max cost per click for the ad group", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_ad_group_bid", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "max_cpc" - ], - "type": "object" - }, - { - "description": "Pause one ad", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "ad_id": { - "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused ad", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "ad_id": { - "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad_id" - ], - "type": "object" - }, - { - "description": "Add locations and/or languages a campaign targets", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "language_ids": { - "default": [], - "description": "Language ids to add, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "type": "array" - }, - "location_ids": { - "default": [], - "description": "Geo target ids to add, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "type": { - "const": "add_campaign_targeting", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Stop targeting some of a campaign's locations and/or languages", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "language_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "type": "array" - }, - "location_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "type": { - "const": "remove_campaign_targeting", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Choose whether a campaign shows to people in its locations only, or also to people interested in them", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "presence_only": { - "description": "true: only people IN the locations; false: also people interested in them", - "type": "boolean" - }, - "type": { - "const": "set_location_mode", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "presence_only" - ], - "type": "object" - }, - { - "description": "Switch ONE campaign's bid strategy. A campaign on a shared (portfolio) strategy moves off it onto its own; the other campaigns on the shared strategy keep it. To change the shared strategy for every campaign on it, use set_shared_bid_strategy. If the user didn't say which they mean, ask. Google re-learns after a switch, so performance can wobble for a week or two", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "strategy": { - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "target_cpa": { - "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_bidding_strategy", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "strategy" - ], - "type": "object" - }, - { - "description": "Change a shared (portfolio) bid strategy's targets. This changes EVERY campaign on it, which the proposal lists. Its type can't be changed; to move one campaign to another strategy, use set_bidding_strategy", - "properties": { - "bidding_strategy_id": { - "description": "Shared (portfolio) strategy id: bidding_strategy.id from run_gaql, or the id at the end of campaign.bidding_strategy", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc_ceiling": { - "description": "The most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_cpa": { - "description": "Target cost per conversion (TARGET_CPA and MAXIMIZE_CONVERSIONS strategies)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_roas": { - "description": "Target return on ad spend as a ratio, e.g. 4 = 400% (TARGET_ROAS and MAXIMIZE_CONVERSION_VALUE)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_shared_bid_strategy", - "type": "string" - } - }, - "required": [ - "type", - "bidding_strategy_id" - ], - "type": "object" - }, - { - "description": "Create a shared (portfolio) bid strategy, optionally moving campaigns onto it. Undo moves those campaigns back and removes it", - "properties": { - "campaign_ids": { - "default": [], - "description": "Campaigns to move onto it in the same step (each leaves its current strategy)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "The most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Name for the shared strategy; must not match an existing one", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "strategy": { - "enum": [ - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CONVERSION_VALUE", - "TARGET_CPA", - "TARGET_ROAS" - ], - "type": "string" - }, - "target_cpa": { - "description": "Target cost per conversion: required for TARGET_CPA, optional for MAXIMIZE_CONVERSIONS", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_roas": { - "description": "Target return on ad spend as a ratio, e.g. 4 = 400%: required for TARGET_ROAS, optional for MAXIMIZE_CONVERSION_VALUE", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "create_shared_bid_strategy", - "type": "string" - } - }, - "required": [ - "type", - "name", - "strategy" - ], - "type": "object" - }, - { - "description": "Set or clear a campaign's final URL suffix (tracking parameters on every ad click)", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "suffix": { - "description": "Query string Google appends to every landing page in the campaign, e.g. \"utm_source=google&utm_medium=cpc&utm_term={keyword}\", or \"none\" to clear it", - "maxLength": 1000, - "type": "string" - }, - "type": { - "const": "set_url_suffix", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "suffix" - ], - "type": "object" - }, - { - "description": "Create a conversion action to measure sign-ups, leads or purchases", - "properties": { - "category": { - "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", - "pattern": "^[A-Z_]+$", - "type": "string" - }, - "counting": { - "default": "ONE_PER_CLICK", - "description": "ONE_PER_CLICK for sign-ups and leads; MANY_PER_CLICK for purchases", - "enum": [ - "ONE_PER_CLICK", - "MANY_PER_CLICK" - ], - "type": "string" - }, - "default_value": { - "description": "Value per conversion when none is sent", - "maximum": 1000000, - "minimum": 0, - "type": "number" - }, - "name": { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "primary": { - "default": true, - "description": "Primary actions count in Conversions and can steer bidding", - "type": "boolean" - }, - "source": { - "default": "UPLOAD_CLICKS", - "description": "UPLOAD_CLICKS: your server uploads ad click ids (no Google tag). WEBPAGE: Google gives you a tag to put on the page", - "enum": [ - "UPLOAD_CLICKS", - "WEBPAGE" - ], - "type": "string" - }, - "type": { - "const": "create_conversion_action", - "type": "string" - } - }, - "required": [ - "type", - "name", - "category" - ], - "type": "object" - }, - { - "description": "Set how many conversions one ad click can produce for a conversion action", - "properties": { - "conversion_action_id": { - "description": "conversion_action.id from run_gaql", - "pattern": "^\\d+$", - "type": "string" - }, - "counting": { - "enum": [ - "ONE_PER_CLICK", - "MANY_PER_CLICK" - ], - "type": "string" - }, - "type": { - "const": "set_conversion_counting", - "type": "string" - } - }, - "required": [ - "type", - "conversion_action_id", - "counting" - ], - "type": "object" - }, - { - "description": "Import a GA4 key event into Google Ads as a conversion action, so campaigns can count and bid on it. The GA4 property must be linked to this account", - "properties": { - "event_name": { - "description": "The GA4 key event, e.g. generate_lead, purchase, sign_up", - "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", - "type": "string" - }, - "primary": { - "default": true, - "description": "Primary actions count in Conversions and can steer bidding", - "type": "boolean" - }, - "property_id": { - "description": "GA4 property id (from analytics_properties)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "import_ga4_key_event", - "type": "string" - } - }, - "required": [ - "type", - "property_id", - "event_name" - ], - "type": "object" - } -]New value: +[ + { + "description": "Block searches containing these words in one campaign", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE blocks any search containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "description": "The search words to block, e.g. \"free\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_negative_keywords", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Pause one keyword", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused keyword", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Pause a whole campaign (stops all its spend)", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Turn a paused campaign back on. It starts spending again; the summary says how much", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Pause one ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Change a campaign's daily budget (not shared budgets)", + "properties": { + "amount": { + "description": "New average daily budget in the account's currency, e.g. 10 for $10.00/day (not micros)", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "set_daily_budget", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "amount" + ], + "type": "object" + }, + { + "description": "Set the last day a campaign runs, so it stops spending on its own", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "end_date": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "const": "none", + "type": "string" + } + ], + "description": "Last day the campaign runs, YYYY-MM-DD in the account's time zone (it stops after 23:59:59 that day), or \"none\" to remove the end date" + }, + "type": { + "const": "set_end_date", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "end_date" + ], + "type": "object" + }, + { + "description": "Build a new Search campaign with its ad groups, keywords, ads, targeting, negatives and sitelinks, in one step. It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "keywords", + "ads" + ], + "type": "object" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MANUAL_CPC", + "description": "MANUAL_CPC uses the ad group and keyword max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English, 1003 Spanish", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States, 2826 United Kingdom, 2124 Canada (look others up in geo_target_constant)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "negative_keywords": { + "default": [], + "description": "Searches to block across the campaign", + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 200, + "type": "array" + }, + "presence_only": { + "default": true, + "description": "Show ads only to people IN the locations (true), not merely interested in them", + "type": "boolean" + }, + "search_partners": { + "default": false, + "description": "Also show on Google's search partner sites", + "type": "boolean" + }, + "sitelinks": { + "default": [], + "items": { + "properties": { + "description1": { + "description": "At most 35 characters; give both descriptions or neither", + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "description2": { + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "text": { + "description": "Link text, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + } + }, + "required": [ + "text", + "url" + ], + "type": "object" + }, + "maxItems": 8, + "type": "array" + }, + "type": { + "const": "create_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Display campaign (image ads across Google's Display Network of sites and apps) with ad groups and responsive display ads. Google's optimized targeting finds the audience. It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A responsive display ad: Google assembles ads from these headlines, descriptions and images", + "properties": { + "business_name": { + "description": "The advertiser's name, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "descriptions": { + "description": "1 to 5 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "1 to 5 short headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "logo_images": { + "default": [], + "description": "0 to 5 landscape logos, 4:1 (e.g. 1200×300, at least 512×128)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "long_headline": { + "description": "One long headline, at most 90 characters", + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "marketing_images": { + "description": "1 to 15 landscape images, 1.91:1 (e.g. 1200×628, at least 600×314)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 1, + "type": "array" + }, + "square_logo_images": { + "default": [], + "description": "0 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "square_marketing_images": { + "description": "1 to 15 square images, 1:1 (e.g. 1200×1200, at least 300×300)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "headlines", + "long_headline", + "descriptions", + "business_name", + "final_url", + "marketing_images", + "square_marketing_images" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "ads" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CLICKS", + "description": "MANUAL_CPC uses the ad groups' max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "presence_only": { + "default": true, + "description": "Show ads only to people IN the locations (true), not merely interested in them", + "type": "boolean" + }, + "type": { + "const": "create_display_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Demand Gen campaign with YouTube video ads, which is how to advertise on YouTube through the API (Google doesn't allow creating Video campaigns there). It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A Demand Gen video ad: runs on YouTube (in-stream, in-feed and Shorts), Discover and Gmail", + "properties": { + "business_name": { + "description": "The advertiser's name, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "descriptions": { + "description": "1 to 5 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "1 to 5 headlines, each at most 40 characters", + "items": { + "maxLength": 40, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "logo_image": { + "description": "A square 1:1 logo (e.g. 1200×1200, at least 128×128): an https URL, or an image asset id from the account", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "long_headlines": { + "description": "1 to 5 long headlines, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "videos": { + "description": "1 to 5 YouTube videos", + "items": { + "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "videos", + "headlines", + "long_headlines", + "descriptions", + "business_name", + "logo_image", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States (Demand Gen targets locations per ad group, not per campaign)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "ads" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CONVERSIONS", + "description": "Demand Gen bids automatically: MAXIMIZE_CONVERSIONS (needs conversion tracking) or MAXIMIZE_CLICKS", + "enum": [ + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CLICKS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "create_demand_gen_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Performance Max campaign: one budget, Google places ads across Search, YouTube, Display, Discover, Gmail and Maps from the asset groups' text, images and videos. No shopping feed (non-retail). It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "asset_groups": { + "items": { + "description": "An asset group: the headlines, descriptions, images and videos Google combines into ads on every channel", + "properties": { + "descriptions": { + "description": "2 to 5 descriptions, each at most 90 characters; Google recommends one of 60 or fewer", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page (Google may also send people to other pages on the same site)", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "long_headlines": { + "description": "1 to 5 long headlines, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "marketing_images": { + "description": "1 to 20 landscape images, 1.91:1 (e.g. 1200×628)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "portrait_marketing_images": { + "default": [], + "description": "0 to 20 portrait images, 4:5 (e.g. 960×1200)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 0, + "type": "array" + }, + "square_marketing_images": { + "description": "1 to 20 square images, 1:1 (e.g. 1200×1200)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "videos": { + "default": [], + "description": "0 to 5 YouTube videos; without one, Google may auto-generate a video from the images", + "items": { + "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "type": "array" + } + }, + "required": [ + "name", + "final_url", + "headlines", + "long_headlines", + "descriptions", + "marketing_images", + "square_marketing_images" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CONVERSIONS", + "description": "Performance Max bids for conversions only: MAXIMIZE_CONVERSIONS, or MAXIMIZE_CONVERSION_VALUE when conversions carry values", + "enum": [ + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CONVERSION_VALUE" + ], + "type": "string" + }, + "business_name": { + "description": "The advertiser's name, at most 25 characters (linked to the campaign, per Google's brand guidelines)", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "logo_images": { + "description": "1 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128), linked to the campaign", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "target_cpa": { + "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "create_performance_max_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "business_name", + "logo_images", + "asset_groups" + ], + "type": "object" + }, + { + "description": "Add an ad group, with its keywords and ads, to an existing Search campaign", + "properties": { + "ad_group": { + "properties": { + "ads": { + "items": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "keywords", + "ads" + ], + "type": "object" + }, + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "add_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "ad_group" + ], + "type": "object" + }, + { + "description": "Add keywords to an existing ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_keywords", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Add a responsive search ad to an existing ad group", + "properties": { + "ad": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "add_responsive_search_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad" + ], + "type": "object" + }, + { + "description": "Add sitelinks to a campaign", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "sitelinks": { + "items": { + "properties": { + "description1": { + "description": "At most 35 characters; give both descriptions or neither", + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "description2": { + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "text": { + "description": "Link text, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + } + }, + "required": [ + "text", + "url" + ], + "type": "object" + }, + "maxItems": 8, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_sitelinks", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "sitelinks" + ], + "type": "object" + }, + { + "description": "Make a campaign count and bid on ONE conversion category only (e.g. SIGNUP), so another product's or step's conversions don't steer it", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "category": { + "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", + "pattern": "^[A-Z_]+$", + "type": "string" + }, + "type": { + "const": "set_conversion_goal", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "category" + ], + "type": "object" + }, + { + "description": "Change one keyword's max CPC (manual CPC campaigns)", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc": { + "anyOf": [ + { + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + { + "type": "null" + } + ], + "description": "New max cost per click for this keyword, or null to clear it so the keyword uses the ad group's bid" + }, + "type": { + "const": "set_keyword_bid", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id", + "max_cpc" + ], + "type": "object" + }, + { + "description": "Change an ad group's default max CPC, which its keywords use unless they have their own", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc": { + "description": "New default max cost per click for the ad group", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_ad_group_bid", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "max_cpc" + ], + "type": "object" + }, + { + "description": "Pause one ad", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused ad", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Add locations and/or languages a campaign targets", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "language_ids": { + "default": [], + "description": "Language ids to add, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "location_ids": { + "default": [], + "description": "Geo target ids to add, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "type": { + "const": "add_campaign_targeting", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Stop targeting some of a campaign's locations and/or languages", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "language_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "location_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "type": { + "const": "remove_campaign_targeting", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Choose whether a campaign shows to people in its locations only, or also to people interested in them", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "presence_only": { + "description": "true: only people IN the locations; false: also people interested in them", + "type": "boolean" + }, + "type": { + "const": "set_location_mode", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "presence_only" + ], + "type": "object" + }, + { + "description": "Switch ONE campaign's bid strategy. A campaign on a shared (portfolio) strategy moves off it onto its own; the other campaigns on the shared strategy keep it. To change the shared strategy for every campaign on it, use set_shared_bid_strategy. If the user didn't say which they mean, ask. Google re-learns after a switch, so performance can wobble for a week or two", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "strategy": { + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "target_cpa": { + "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_bidding_strategy", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "strategy" + ], + "type": "object" + }, + { + "description": "Change a shared (portfolio) bid strategy's targets. This changes EVERY campaign on it, which the proposal lists. Its type can't be changed; to move one campaign to another strategy, use set_bidding_strategy", + "properties": { + "bidding_strategy_id": { + "description": "Shared (portfolio) strategy id: bidding_strategy.id from run_gaql, or the id at the end of campaign.bidding_strategy", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc_ceiling": { + "description": "The most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_cpa": { + "description": "Target cost per conversion (TARGET_CPA and MAXIMIZE_CONVERSIONS strategies)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_roas": { + "description": "Target return on ad spend as a ratio, e.g. 4 = 400% (TARGET_ROAS and MAXIMIZE_CONVERSION_VALUE)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_shared_bid_strategy", + "type": "string" + } + }, + "required": [ + "type", + "bidding_strategy_id" + ], + "type": "object" + }, + { + "description": "Create a shared (portfolio) bid strategy, optionally moving campaigns onto it. Undo moves those campaigns back and removes it", + "properties": { + "campaign_ids": { + "default": [], + "description": "Campaigns to move onto it in the same step (each leaves its current strategy)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "The most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Name for the shared strategy; must not match an existing one", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "strategy": { + "enum": [ + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CONVERSION_VALUE", + "TARGET_CPA", + "TARGET_ROAS" + ], + "type": "string" + }, + "target_cpa": { + "description": "Target cost per conversion: required for TARGET_CPA, optional for MAXIMIZE_CONVERSIONS", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_roas": { + "description": "Target return on ad spend as a ratio, e.g. 4 = 400%: required for TARGET_ROAS, optional for MAXIMIZE_CONVERSION_VALUE", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "create_shared_bid_strategy", + "type": "string" + } + }, + "required": [ + "type", + "name", + "strategy" + ], + "type": "object" + }, + { + "description": "Set or clear a campaign's final URL suffix (tracking parameters on every ad click)", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "suffix": { + "description": "Query string Google appends to every landing page in the campaign, e.g. \"utm_source=google&utm_medium=cpc&utm_term={keyword}\", or \"none\" to clear it", + "maxLength": 1000, + "type": "string" + }, + "type": { + "const": "set_url_suffix", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "suffix" + ], + "type": "object" + }, + { + "description": "Declare whether a campaign contains EU political advertising. While any campaign lacks this declaration, Google refuses every change to the account (EU_POLITICAL_ADVERTISING_DECLARATION_REQUIRED); find those campaigns with campaign.missing_eu_political_advertising_declaration = TRUE. It is the advertiser's own legal statement: ask the user, never assume the answer", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "contains_eu_political_advertising": { + "description": "The user's answer: true only if the campaign carries political ads under EU rules (about an election, a referendum, or a law or regulation, shown in the EU)", + "type": "boolean" + }, + "type": { + "const": "set_eu_political_advertising", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "contains_eu_political_advertising" + ], + "type": "object" + }, + { + "description": "Create a conversion action to measure sign-ups, leads or purchases", + "properties": { + "category": { + "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", + "pattern": "^[A-Z_]+$", + "type": "string" + }, + "counting": { + "default": "ONE_PER_CLICK", + "description": "ONE_PER_CLICK for sign-ups and leads; MANY_PER_CLICK for purchases", + "enum": [ + "ONE_PER_CLICK", + "MANY_PER_CLICK" + ], + "type": "string" + }, + "default_value": { + "description": "Value per conversion when none is sent", + "maximum": 1000000, + "minimum": 0, + "type": "number" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "primary": { + "default": true, + "description": "Primary actions count in Conversions and can steer bidding", + "type": "boolean" + }, + "source": { + "default": "UPLOAD_CLICKS", + "description": "UPLOAD_CLICKS: your server uploads ad click ids (no Google tag). WEBPAGE: Google gives you a tag to put on the page", + "enum": [ + "UPLOAD_CLICKS", + "WEBPAGE" + ], + "type": "string" + }, + "type": { + "const": "create_conversion_action", + "type": "string" + } + }, + "required": [ + "type", + "name", + "category" + ], + "type": "object" + }, + { + "description": "Set how many conversions one ad click can produce for a conversion action", + "properties": { + "conversion_action_id": { + "description": "conversion_action.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + }, + "counting": { + "enum": [ + "ONE_PER_CLICK", + "MANY_PER_CLICK" + ], + "type": "string" + }, + "type": { + "const": "set_conversion_counting", + "type": "string" + } + }, + "required": [ + "type", + "conversion_action_id", + "counting" + ], + "type": "object" + }, + { + "description": "Import a GA4 key event into Google Ads as a conversion action, so campaigns can count and bid on it. The GA4 property must be linked to this account", + "properties": { + "event_name": { + "description": "The GA4 key event, e.g. generate_lead, purchase, sign_up", + "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", + "type": "string" + }, + "primary": { + "default": true, + "description": "Primary actions count in Conversions and can steer bidding", + "type": "boolean" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "import_ga4_key_event", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "event_name" + ], + "type": "object" + } +]
9 tool updates
v0.17.0- Changed
account_overview1 field changed- removed
Input schema / properties / confirm_switchRemoved value: -{ - "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", - "type": "boolean" -}
- Changed
apply_changes1 field changed- changed
Input schema / properties / proposal_id / descriptionPrevious value: -"The id returned by propose_changes"New value: +"The proposal_id a propose tool returned"
- Changed
discard_proposal1 field changed- changed
Input schema / properties / proposal_id / descriptionPrevious value: -"The id returned by propose_changes"New value: +"The proposal_id a propose tool returned"
- Changed
keyword_ideas1 field changed- removed
Input schema / properties / confirm_switchRemoved value: -{ - "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", - "type": "boolean" -}
- Changed
keyword_metrics1 field changed- removed
Input schema / properties / confirm_switchRemoved value: -{ - "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", - "type": "boolean" -}
- Changed
paid_organic_overlap1 field changed- removed
Input schema / properties / confirm_switchRemoved value: -{ - "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", - "type": "boolean" -}
- Changed
propose_changes2 fields changed- changed
Input schema / properties / changes / items / oneOfPrevious value: -[ - { - "description": "Block searches containing these words in one campaign", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE blocks any search containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "description": "The search words to block, e.g. \"free\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_negative_keywords", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "keywords" - ], - "type": "object" - }, - { - "description": "Pause one keyword", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_keyword", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused keyword", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_keyword", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id" - ], - "type": "object" - }, - { - "description": "Pause a whole campaign (stops all its spend)", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_campaign", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Turn a paused campaign back on. It starts spending again; the summary says how much", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_campaign", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Pause one ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id" - ], - "type": "object" - }, - { - "description": "Change a campaign's daily budget (not shared budgets)", - "properties": { - "amount": { - "description": "New average daily budget in the account's currency, e.g. 10 for $10.00/day (not micros)", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "set_daily_budget", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "amount" - ], - "type": "object" - }, - { - "description": "Set the last day a campaign runs, so it stops spending on its own", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "end_date": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "const": "none", - "type": "string" - } - ], - "description": "Last day the campaign runs, YYYY-MM-DD in the account's time zone (it stops after 23:59:59 that day), or \"none\" to remove the end date" - }, - "type": { - "const": "set_end_date", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "end_date" - ], - "type": "object" - }, - { - "description": "Build a new Search campaign with its ad groups, keywords, ads, targeting, negatives and sitelinks, in one step. It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "keywords", - "ads" - ], - "type": "object" - }, - "maxItems": 10, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MANUAL_CPC", - "description": "MANUAL_CPC uses the ad group and keyword max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English, 1003 Spanish", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States, 2826 United Kingdom, 2124 Canada (look others up in geo_target_constant)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "negative_keywords": { - "default": [], - "description": "Searches to block across the campaign", - "items": { - "properties": { - "match_type": { - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 200, - "type": "array" - }, - "presence_only": { - "default": true, - "description": "Show ads only to people IN the locations (true), not merely interested in them", - "type": "boolean" - }, - "search_partners": { - "default": false, - "description": "Also show on Google's search partner sites", - "type": "boolean" - }, - "sitelinks": { - "default": [], - "items": { - "properties": { - "description1": { - "description": "At most 35 characters; give both descriptions or neither", - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "description2": { - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "text": { - "description": "Link text, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "url": { - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - } - }, - "required": [ - "text", - "url" - ], - "type": "object" - }, - "maxItems": 8, - "type": "array" - }, - "type": { - "const": "create_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Display campaign (image ads across Google's Display Network of sites and apps) with ad groups and responsive display ads. Google's optimized targeting finds the audience. It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A responsive display ad: Google assembles ads from these headlines, descriptions and images", - "properties": { - "business_name": { - "description": "The advertiser's name, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "descriptions": { - "description": "1 to 5 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "1 to 5 short headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "logo_images": { - "default": [], - "description": "0 to 5 landscape logos, 4:1 (e.g. 1200×300, at least 512×128)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 0, - "type": "array" - }, - "long_headline": { - "description": "One long headline, at most 90 characters", - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "marketing_images": { - "description": "1 to 15 landscape images, 1.91:1 (e.g. 1200×628, at least 600×314)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 1, - "type": "array" - }, - "square_logo_images": { - "default": [], - "description": "0 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 0, - "type": "array" - }, - "square_marketing_images": { - "description": "1 to 15 square images, 1:1 (e.g. 1200×1200, at least 300×300)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "headlines", - "long_headline", - "descriptions", - "business_name", - "final_url", - "marketing_images", - "square_marketing_images" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "ads" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CLICKS", - "description": "MANUAL_CPC uses the ad groups' max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "presence_only": { - "default": true, - "description": "Show ads only to people IN the locations (true), not merely interested in them", - "type": "boolean" - }, - "type": { - "const": "create_display_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Demand Gen campaign with YouTube video ads, which is how to advertise on YouTube through the API (Google doesn't allow creating Video campaigns there). It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "ad_groups": { - "items": { - "properties": { - "ads": { - "items": { - "description": "A Demand Gen video ad: runs on YouTube (in-stream, in-feed and Shorts), Discover and Gmail", - "properties": { - "business_name": { - "description": "The advertiser's name, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "descriptions": { - "description": "1 to 5 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "1 to 5 headlines, each at most 40 characters", - "items": { - "maxLength": 40, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "logo_image": { - "description": "A square 1:1 logo (e.g. 1200×1200, at least 128×128): an https URL, or an image asset id from the account", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "long_headlines": { - "description": "1 to 5 long headlines, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "videos": { - "description": "1 to 5 YouTube videos", - "items": { - "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "videos", - "headlines", - "long_headlines", - "descriptions", - "business_name", - "logo_image", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States (Demand Gen targets locations per ad group, not per campaign)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "ads" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CONVERSIONS", - "description": "Demand Gen bids automatically: MAXIMIZE_CONVERSIONS (needs conversion tracking) or MAXIMIZE_CLICKS", - "enum": [ - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CLICKS" - ], - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "create_demand_gen_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "ad_groups" - ], - "type": "object" - }, - { - "description": "Build a new Performance Max campaign: one budget, Google places ads across Search, YouTube, Display, Discover, Gmail and Maps from the asset groups' text, images and videos. No shopping feed (non-retail). It is created PAUSED: nothing spends until a separate enable_campaign", - "properties": { - "asset_groups": { - "items": { - "description": "An asset group: the headlines, descriptions, images and videos Google combines into ads on every channel", - "properties": { - "descriptions": { - "description": "2 to 5 descriptions, each at most 90 characters; Google recommends one of 60 or fewer", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page (Google may also send people to other pages on the same site)", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "long_headlines": { - "description": "1 to 5 long headlines, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "marketing_images": { - "description": "1 to 20 landscape images, 1.91:1 (e.g. 1200×628)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "portrait_marketing_images": { - "default": [], - "description": "0 to 20 portrait images, 4:5 (e.g. 960×1200)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 0, - "type": "array" - }, - "square_marketing_images": { - "description": "1 to 20 square images, 1:1 (e.g. 1200×1200)", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "videos": { - "default": [], - "description": "0 to 5 YouTube videos; without one, Google may auto-generate a video from the images", - "items": { - "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "type": "array" - } - }, - "required": [ - "name", - "final_url", - "headlines", - "long_headlines", - "descriptions", - "marketing_images", - "square_marketing_images" - ], - "type": "object" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "bidding": { - "default": "MAXIMIZE_CONVERSIONS", - "description": "Performance Max bids for conversions only: MAXIMIZE_CONVERSIONS, or MAXIMIZE_CONVERSION_VALUE when conversions carry values", - "enum": [ - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CONVERSION_VALUE" - ], - "type": "string" - }, - "business_name": { - "description": "The advertiser's name, at most 25 characters (linked to the campaign, per Google's brand guidelines)", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "daily_budget": { - "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", - "exclusiveMinimum": 0, - "maximum": 1000000, - "type": "number" - }, - "end_date": { - "description": "Last day the campaign runs, YYYY-MM-DD", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "language_ids": { - "default": [ - "1000" - ], - "description": "Google language ids, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "location_ids": { - "default": [ - "2840" - ], - "description": "Google geo target ids, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "logo_images": { - "description": "1 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128), linked to the campaign", - "items": { - "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 1, - "type": "array" - }, - "name": { - "description": "Campaign name; must not match an existing campaign", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "target_cpa": { - "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "create_performance_max_campaign", - "type": "string" - } - }, - "required": [ - "type", - "name", - "daily_budget", - "business_name", - "logo_images", - "asset_groups" - ], - "type": "object" - }, - { - "description": "Add an ad group, with its keywords and ads, to an existing Search campaign", - "properties": { - "ad_group": { - "properties": { - "ads": { - "items": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "maxItems": 3, - "minItems": 1, - "type": "array" - }, - "default_max_cpc": { - "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name", - "keywords", - "ads" - ], - "type": "object" - }, - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "add_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "ad_group" - ], - "type": "object" - }, - { - "description": "Add keywords to an existing ad group", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "description": "PHRASE matches searches containing the words in order; the usual choice", - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "max_cpc": { - "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "text": { - "description": "The keyword, e.g. \"cleaning invoice template\"", - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_keywords", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "keywords" - ], - "type": "object" - }, - { - "description": "Add a responsive search ad to an existing ad group", - "properties": { - "ad": { - "description": "A responsive search ad", - "properties": { - "descriptions": { - "description": "2 to 4 descriptions, each at most 90 characters", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "description": "The landing page", - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "3 to 15 headlines, each at most 30 characters", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "description": "Display path part 1, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "description": "Display path part 2, at most 15 characters", - "maxLength": 15, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "headlines", - "descriptions", - "final_url" - ], - "type": "object" - }, - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "add_responsive_search_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad" - ], - "type": "object" - }, - { - "description": "Add sitelinks to a campaign", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "sitelinks": { - "items": { - "properties": { - "description1": { - "description": "At most 35 characters; give both descriptions or neither", - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "description2": { - "maxLength": 35, - "minLength": 1, - "type": "string" - }, - "text": { - "description": "Link text, at most 25 characters", - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "url": { - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - } - }, - "required": [ - "text", - "url" - ], - "type": "object" - }, - "maxItems": 8, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_sitelinks", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "sitelinks" - ], - "type": "object" - }, - { - "description": "Make a campaign count and bid on ONE conversion category only (e.g. SIGNUP), so another product's or step's conversions don't steer it", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "category": { - "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", - "pattern": "^[A-Z_]+$", - "type": "string" - }, - "type": { - "const": "set_conversion_goal", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "category" - ], - "type": "object" - }, - { - "description": "Change one keyword's max CPC (manual CPC campaigns)", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_id": { - "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc": { - "anyOf": [ - { - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - { - "type": "null" - } - ], - "description": "New max cost per click for this keyword, or null to clear it so the keyword uses the ad group's bid" - }, - "type": { - "const": "set_keyword_bid", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id", - "max_cpc" - ], - "type": "object" - }, - { - "description": "Change an ad group's default max CPC, which its keywords use unless they have their own", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc": { - "description": "New default max cost per click for the ad group", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_ad_group_bid", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "max_cpc" - ], - "type": "object" - }, - { - "description": "Pause one ad", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "ad_id": { - "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "pause_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad_id" - ], - "type": "object" - }, - { - "description": "Re-enable one paused ad", - "properties": { - "ad_group_id": { - "description": "Ad group id, digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "ad_id": { - "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "enable_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad_id" - ], - "type": "object" - }, - { - "description": "Add locations and/or languages a campaign targets", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "language_ids": { - "default": [], - "description": "Language ids to add, e.g. 1000 English", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "type": "array" - }, - "location_ids": { - "default": [], - "description": "Geo target ids to add, e.g. 2840 United States", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "type": { - "const": "add_campaign_targeting", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Stop targeting some of a campaign's locations and/or languages", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "language_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "type": "array" - }, - "location_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "type": { - "const": "remove_campaign_targeting", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Choose whether a campaign shows to people in its locations only, or also to people interested in them", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "presence_only": { - "description": "true: only people IN the locations; false: also people interested in them", - "type": "boolean" - }, - "type": { - "const": "set_location_mode", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "presence_only" - ], - "type": "object" - }, - { - "description": "Switch ONE campaign's bid strategy. A campaign on a shared (portfolio) strategy moves off it onto its own; the other campaigns on the shared strategy keep it. To change the shared strategy for every campaign on it, use set_shared_bid_strategy. If the user didn't say which they mean, ask. Google re-learns after a switch, so performance can wobble for a week or two", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc_ceiling": { - "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "strategy": { - "enum": [ - "MANUAL_CPC", - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS" - ], - "type": "string" - }, - "target_cpa": { - "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_bidding_strategy", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "strategy" - ], - "type": "object" - }, - { - "description": "Change a shared (portfolio) bid strategy's targets. This changes EVERY campaign on it, which the proposal lists. Its type can't be changed; to move one campaign to another strategy, use set_bidding_strategy", - "properties": { - "bidding_strategy_id": { - "description": "Shared (portfolio) strategy id: bidding_strategy.id from run_gaql, or the id at the end of campaign.bidding_strategy", - "pattern": "^\\d+$", - "type": "string" - }, - "max_cpc_ceiling": { - "description": "The most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_cpa": { - "description": "Target cost per conversion (TARGET_CPA and MAXIMIZE_CONVERSIONS strategies)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_roas": { - "description": "Target return on ad spend as a ratio, e.g. 4 = 400% (TARGET_ROAS and MAXIMIZE_CONVERSION_VALUE)", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "set_shared_bid_strategy", - "type": "string" - } - }, - "required": [ - "type", - "bidding_strategy_id" - ], - "type": "object" - }, - { - "description": "Create a shared (portfolio) bid strategy, optionally moving campaigns onto it. Undo moves those campaigns back and removes it", - "properties": { - "campaign_ids": { - "default": [], - "description": "Campaigns to move onto it in the same step (each leaves its current strategy)", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "max_cpc_ceiling": { - "description": "The most Google may bid per click", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "name": { - "description": "Name for the shared strategy; must not match an existing one", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "strategy": { - "enum": [ - "MAXIMIZE_CLICKS", - "MAXIMIZE_CONVERSIONS", - "MAXIMIZE_CONVERSION_VALUE", - "TARGET_CPA", - "TARGET_ROAS" - ], - "type": "string" - }, - "target_cpa": { - "description": "Target cost per conversion: required for TARGET_CPA, optional for MAXIMIZE_CONVERSIONS", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "target_roas": { - "description": "Target return on ad spend as a ratio, e.g. 4 = 400%: required for TARGET_ROAS, optional for MAXIMIZE_CONVERSION_VALUE", - "exclusiveMinimum": 0, - "maximum": 1000, - "type": "number" - }, - "type": { - "const": "create_shared_bid_strategy", - "type": "string" - } - }, - "required": [ - "type", - "name", - "strategy" - ], - "type": "object" - }, - { - "description": "Set or clear a campaign's final URL suffix (tracking parameters on every ad click)", - "properties": { - "campaign_id": { - "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "suffix": { - "description": "Query string Google appends to every landing page in the campaign, e.g. \"utm_source=google&utm_medium=cpc&utm_term={keyword}\", or \"none\" to clear it", - "maxLength": 1000, - "type": "string" - }, - "type": { - "const": "set_url_suffix", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "suffix" - ], - "type": "object" - }, - { - "description": "Create a conversion action to measure sign-ups, leads or purchases", - "properties": { - "category": { - "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", - "pattern": "^[A-Z_]+$", - "type": "string" - }, - "counting": { - "default": "ONE_PER_CLICK", - "description": "ONE_PER_CLICK for sign-ups and leads; MANY_PER_CLICK for purchases", - "enum": [ - "ONE_PER_CLICK", - "MANY_PER_CLICK" - ], - "type": "string" - }, - "default_value": { - "description": "Value per conversion when none is sent", - "maximum": 1000000, - "minimum": 0, - "type": "number" - }, - "name": { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "primary": { - "default": true, - "description": "Primary actions count in Conversions and can steer bidding", - "type": "boolean" - }, - "source": { - "default": "UPLOAD_CLICKS", - "description": "UPLOAD_CLICKS: your server uploads ad click ids (no Google tag). WEBPAGE: Google gives you a tag to put on the page", - "enum": [ - "UPLOAD_CLICKS", - "WEBPAGE" - ], - "type": "string" - }, - "type": { - "const": "create_conversion_action", - "type": "string" - } - }, - "required": [ - "type", - "name", - "category" - ], - "type": "object" - }, - { - "description": "Set how many conversions one ad click can produce for a conversion action", - "properties": { - "conversion_action_id": { - "description": "conversion_action.id from run_gaql", - "pattern": "^\\d+$", - "type": "string" - }, - "counting": { - "enum": [ - "ONE_PER_CLICK", - "MANY_PER_CLICK" - ], - "type": "string" - }, - "type": { - "const": "set_conversion_counting", - "type": "string" - } - }, - "required": [ - "type", - "conversion_action_id", - "counting" - ], - "type": "object" - } -]New value: +[ + { + "description": "Block searches containing these words in one campaign", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE blocks any search containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "description": "The search words to block, e.g. \"free\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_negative_keywords", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Pause one keyword", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused keyword", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Pause a whole campaign (stops all its spend)", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Turn a paused campaign back on. It starts spending again; the summary says how much", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Pause one ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Change a campaign's daily budget (not shared budgets)", + "properties": { + "amount": { + "description": "New average daily budget in the account's currency, e.g. 10 for $10.00/day (not micros)", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "set_daily_budget", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "amount" + ], + "type": "object" + }, + { + "description": "Set the last day a campaign runs, so it stops spending on its own", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "end_date": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "const": "none", + "type": "string" + } + ], + "description": "Last day the campaign runs, YYYY-MM-DD in the account's time zone (it stops after 23:59:59 that day), or \"none\" to remove the end date" + }, + "type": { + "const": "set_end_date", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "end_date" + ], + "type": "object" + }, + { + "description": "Build a new Search campaign with its ad groups, keywords, ads, targeting, negatives and sitelinks, in one step. It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "keywords", + "ads" + ], + "type": "object" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MANUAL_CPC", + "description": "MANUAL_CPC uses the ad group and keyword max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English, 1003 Spanish", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States, 2826 United Kingdom, 2124 Canada (look others up in geo_target_constant)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "negative_keywords": { + "default": [], + "description": "Searches to block across the campaign", + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 200, + "type": "array" + }, + "presence_only": { + "default": true, + "description": "Show ads only to people IN the locations (true), not merely interested in them", + "type": "boolean" + }, + "search_partners": { + "default": false, + "description": "Also show on Google's search partner sites", + "type": "boolean" + }, + "sitelinks": { + "default": [], + "items": { + "properties": { + "description1": { + "description": "At most 35 characters; give both descriptions or neither", + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "description2": { + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "text": { + "description": "Link text, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + } + }, + "required": [ + "text", + "url" + ], + "type": "object" + }, + "maxItems": 8, + "type": "array" + }, + "type": { + "const": "create_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Display campaign (image ads across Google's Display Network of sites and apps) with ad groups and responsive display ads. Google's optimized targeting finds the audience. It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A responsive display ad: Google assembles ads from these headlines, descriptions and images", + "properties": { + "business_name": { + "description": "The advertiser's name, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "descriptions": { + "description": "1 to 5 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "1 to 5 short headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "logo_images": { + "default": [], + "description": "0 to 5 landscape logos, 4:1 (e.g. 1200×300, at least 512×128)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "long_headline": { + "description": "One long headline, at most 90 characters", + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "marketing_images": { + "description": "1 to 15 landscape images, 1.91:1 (e.g. 1200×628, at least 600×314)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 1, + "type": "array" + }, + "square_logo_images": { + "default": [], + "description": "0 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "square_marketing_images": { + "description": "1 to 15 square images, 1:1 (e.g. 1200×1200, at least 300×300)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "headlines", + "long_headline", + "descriptions", + "business_name", + "final_url", + "marketing_images", + "square_marketing_images" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "ads" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CLICKS", + "description": "MANUAL_CPC uses the ad groups' max CPCs; MAXIMIZE_CLICKS and MAXIMIZE_CONVERSIONS let Google bid within the budget", + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "presence_only": { + "default": true, + "description": "Show ads only to people IN the locations (true), not merely interested in them", + "type": "boolean" + }, + "type": { + "const": "create_display_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Demand Gen campaign with YouTube video ads, which is how to advertise on YouTube through the API (Google doesn't allow creating Video campaigns there). It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "ad_groups": { + "items": { + "properties": { + "ads": { + "items": { + "description": "A Demand Gen video ad: runs on YouTube (in-stream, in-feed and Shorts), Discover and Gmail", + "properties": { + "business_name": { + "description": "The advertiser's name, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "descriptions": { + "description": "1 to 5 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "1 to 5 headlines, each at most 40 characters", + "items": { + "maxLength": 40, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "logo_image": { + "description": "A square 1:1 logo (e.g. 1200×1200, at least 128×128): an https URL, or an image asset id from the account", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "long_headlines": { + "description": "1 to 5 long headlines, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "videos": { + "description": "1 to 5 YouTube videos", + "items": { + "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "videos", + "headlines", + "long_headlines", + "descriptions", + "business_name", + "logo_image", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States (Demand Gen targets locations per ad group, not per campaign)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "ads" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CONVERSIONS", + "description": "Demand Gen bids automatically: MAXIMIZE_CONVERSIONS (needs conversion tracking) or MAXIMIZE_CLICKS", + "enum": [ + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CLICKS" + ], + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "create_demand_gen_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "ad_groups" + ], + "type": "object" + }, + { + "description": "Build a new Performance Max campaign: one budget, Google places ads across Search, YouTube, Display, Discover, Gmail and Maps from the asset groups' text, images and videos. No shopping feed (non-retail). It is created PAUSED: nothing spends until a separate enable_campaign", + "properties": { + "asset_groups": { + "items": { + "description": "An asset group: the headlines, descriptions, images and videos Google combines into ads on every channel", + "properties": { + "descriptions": { + "description": "2 to 5 descriptions, each at most 90 characters; Google recommends one of 60 or fewer", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page (Google may also send people to other pages on the same site)", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "long_headlines": { + "description": "1 to 5 long headlines, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "marketing_images": { + "description": "1 to 20 landscape images, 1.91:1 (e.g. 1200×628)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "portrait_marketing_images": { + "default": [], + "description": "0 to 20 portrait images, 4:5 (e.g. 960×1200)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 0, + "type": "array" + }, + "square_marketing_images": { + "description": "1 to 20 square images, 1:1 (e.g. 1200×1200)", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "videos": { + "default": [], + "description": "0 to 5 YouTube videos; without one, Google may auto-generate a video from the images", + "items": { + "description": "A YouTube video id (e.g. dQw4w9WgXcQ) or its youtube.com / youtu.be URL. The video must be public or unlisted", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "type": "array" + } + }, + "required": [ + "name", + "final_url", + "headlines", + "long_headlines", + "descriptions", + "marketing_images", + "square_marketing_images" + ], + "type": "object" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "bidding": { + "default": "MAXIMIZE_CONVERSIONS", + "description": "Performance Max bids for conversions only: MAXIMIZE_CONVERSIONS, or MAXIMIZE_CONVERSION_VALUE when conversions carry values", + "enum": [ + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CONVERSION_VALUE" + ], + "type": "string" + }, + "business_name": { + "description": "The advertiser's name, at most 25 characters (linked to the campaign, per Google's brand guidelines)", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "daily_budget": { + "description": "Average daily budget in the account's currency, e.g. 20 for $20.00/day", + "exclusiveMinimum": 0, + "maximum": 1000000, + "type": "number" + }, + "end_date": { + "description": "Last day the campaign runs, YYYY-MM-DD", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "language_ids": { + "default": [ + "1000" + ], + "description": "Google language ids, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "location_ids": { + "default": [ + "2840" + ], + "description": "Google geo target ids, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "logo_images": { + "description": "1 to 5 square logos, 1:1 (e.g. 1200×1200, at least 128×128), linked to the campaign", + "items": { + "description": "An https URL of a PNG, JPEG or GIF (at most 5120 KB), or the id of an image asset already in the account (asset.id from run_gaql WHERE asset.type = 'IMAGE')", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" + }, + "name": { + "description": "Campaign name; must not match an existing campaign", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "target_cpa": { + "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "create_performance_max_campaign", + "type": "string" + } + }, + "required": [ + "type", + "name", + "daily_budget", + "business_name", + "logo_images", + "asset_groups" + ], + "type": "object" + }, + { + "description": "Add an ad group, with its keywords and ads, to an existing Search campaign", + "properties": { + "ad_group": { + "properties": { + "ads": { + "items": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "maxItems": 3, + "minItems": 1, + "type": "array" + }, + "default_max_cpc": { + "description": "Default max cost per click for the ad group (required when the campaign uses manual CPC)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "keywords", + "ads" + ], + "type": "object" + }, + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "add_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "ad_group" + ], + "type": "object" + }, + { + "description": "Add keywords to an existing ad group", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "description": "PHRASE matches searches containing the words in order; the usual choice", + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "max_cpc": { + "description": "Max cost per click for this keyword in the account's currency (manual CPC only); omit to use the ad group's", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "text": { + "description": "The keyword, e.g. \"cleaning invoice template\"", + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_keywords", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Add a responsive search ad to an existing ad group", + "properties": { + "ad": { + "description": "A responsive search ad", + "properties": { + "descriptions": { + "description": "2 to 4 descriptions, each at most 90 characters", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "description": "The landing page", + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "3 to 15 headlines, each at most 30 characters", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "description": "Display path part 1, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "description": "Display path part 2, at most 15 characters", + "maxLength": 15, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "headlines", + "descriptions", + "final_url" + ], + "type": "object" + }, + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "add_responsive_search_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad" + ], + "type": "object" + }, + { + "description": "Add sitelinks to a campaign", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "sitelinks": { + "items": { + "properties": { + "description1": { + "description": "At most 35 characters; give both descriptions or neither", + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "description2": { + "maxLength": 35, + "minLength": 1, + "type": "string" + }, + "text": { + "description": "Link text, at most 25 characters", + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + } + }, + "required": [ + "text", + "url" + ], + "type": "object" + }, + "maxItems": 8, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_sitelinks", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "sitelinks" + ], + "type": "object" + }, + { + "description": "Make a campaign count and bid on ONE conversion category only (e.g. SIGNUP), so another product's or step's conversions don't steer it", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "category": { + "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", + "pattern": "^[A-Z_]+$", + "type": "string" + }, + "type": { + "const": "set_conversion_goal", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "category" + ], + "type": "object" + }, + { + "description": "Change one keyword's max CPC (manual CPC campaigns)", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_id": { + "description": "Keyword criterion id, digits only (ad_group_criterion.criterion_id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc": { + "anyOf": [ + { + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + { + "type": "null" + } + ], + "description": "New max cost per click for this keyword, or null to clear it so the keyword uses the ad group's bid" + }, + "type": { + "const": "set_keyword_bid", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id", + "max_cpc" + ], + "type": "object" + }, + { + "description": "Change an ad group's default max CPC, which its keywords use unless they have their own", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc": { + "description": "New default max cost per click for the ad group", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_ad_group_bid", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "max_cpc" + ], + "type": "object" + }, + { + "description": "Pause one ad", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "pause_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Re-enable one paused ad", + "properties": { + "ad_group_id": { + "description": "Ad group id, digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "enable_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Add locations and/or languages a campaign targets", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "language_ids": { + "default": [], + "description": "Language ids to add, e.g. 1000 English", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "location_ids": { + "default": [], + "description": "Geo target ids to add, e.g. 2840 United States", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "type": { + "const": "add_campaign_targeting", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Stop targeting some of a campaign's locations and/or languages", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "language_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "location_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "type": { + "const": "remove_campaign_targeting", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Choose whether a campaign shows to people in its locations only, or also to people interested in them", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "presence_only": { + "description": "true: only people IN the locations; false: also people interested in them", + "type": "boolean" + }, + "type": { + "const": "set_location_mode", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "presence_only" + ], + "type": "object" + }, + { + "description": "Switch ONE campaign's bid strategy. A campaign on a shared (portfolio) strategy moves off it onto its own; the other campaigns on the shared strategy keep it. To change the shared strategy for every campaign on it, use set_shared_bid_strategy. If the user didn't say which they mean, ask. Google re-learns after a switch, so performance can wobble for a week or two", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc_ceiling": { + "description": "MAXIMIZE_CLICKS only: the most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "strategy": { + "enum": [ + "MANUAL_CPC", + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS" + ], + "type": "string" + }, + "target_cpa": { + "description": "MAXIMIZE_CONVERSIONS only: target cost per conversion", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_bidding_strategy", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "strategy" + ], + "type": "object" + }, + { + "description": "Change a shared (portfolio) bid strategy's targets. This changes EVERY campaign on it, which the proposal lists. Its type can't be changed; to move one campaign to another strategy, use set_bidding_strategy", + "properties": { + "bidding_strategy_id": { + "description": "Shared (portfolio) strategy id: bidding_strategy.id from run_gaql, or the id at the end of campaign.bidding_strategy", + "pattern": "^\\d+$", + "type": "string" + }, + "max_cpc_ceiling": { + "description": "The most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_cpa": { + "description": "Target cost per conversion (TARGET_CPA and MAXIMIZE_CONVERSIONS strategies)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_roas": { + "description": "Target return on ad spend as a ratio, e.g. 4 = 400% (TARGET_ROAS and MAXIMIZE_CONVERSION_VALUE)", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "set_shared_bid_strategy", + "type": "string" + } + }, + "required": [ + "type", + "bidding_strategy_id" + ], + "type": "object" + }, + { + "description": "Create a shared (portfolio) bid strategy, optionally moving campaigns onto it. Undo moves those campaigns back and removes it", + "properties": { + "campaign_ids": { + "default": [], + "description": "Campaigns to move onto it in the same step (each leaves its current strategy)", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "max_cpc_ceiling": { + "description": "The most Google may bid per click", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "name": { + "description": "Name for the shared strategy; must not match an existing one", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "strategy": { + "enum": [ + "MAXIMIZE_CLICKS", + "MAXIMIZE_CONVERSIONS", + "MAXIMIZE_CONVERSION_VALUE", + "TARGET_CPA", + "TARGET_ROAS" + ], + "type": "string" + }, + "target_cpa": { + "description": "Target cost per conversion: required for TARGET_CPA, optional for MAXIMIZE_CONVERSIONS", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "target_roas": { + "description": "Target return on ad spend as a ratio, e.g. 4 = 400%: required for TARGET_ROAS, optional for MAXIMIZE_CONVERSION_VALUE", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "number" + }, + "type": { + "const": "create_shared_bid_strategy", + "type": "string" + } + }, + "required": [ + "type", + "name", + "strategy" + ], + "type": "object" + }, + { + "description": "Set or clear a campaign's final URL suffix (tracking parameters on every ad click)", + "properties": { + "campaign_id": { + "description": "Campaign id, digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "suffix": { + "description": "Query string Google appends to every landing page in the campaign, e.g. \"utm_source=google&utm_medium=cpc&utm_term={keyword}\", or \"none\" to clear it", + "maxLength": 1000, + "type": "string" + }, + "type": { + "const": "set_url_suffix", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "suffix" + ], + "type": "object" + }, + { + "description": "Create a conversion action to measure sign-ups, leads or purchases", + "properties": { + "category": { + "description": "Conversion category, e.g. SIGNUP, PURCHASE, SUBMIT_LEAD_FORM, QUALIFIED_LEAD (see conversion_action.category in run_gaql)", + "pattern": "^[A-Z_]+$", + "type": "string" + }, + "counting": { + "default": "ONE_PER_CLICK", + "description": "ONE_PER_CLICK for sign-ups and leads; MANY_PER_CLICK for purchases", + "enum": [ + "ONE_PER_CLICK", + "MANY_PER_CLICK" + ], + "type": "string" + }, + "default_value": { + "description": "Value per conversion when none is sent", + "maximum": 1000000, + "minimum": 0, + "type": "number" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "primary": { + "default": true, + "description": "Primary actions count in Conversions and can steer bidding", + "type": "boolean" + }, + "source": { + "default": "UPLOAD_CLICKS", + "description": "UPLOAD_CLICKS: your server uploads ad click ids (no Google tag). WEBPAGE: Google gives you a tag to put on the page", + "enum": [ + "UPLOAD_CLICKS", + "WEBPAGE" + ], + "type": "string" + }, + "type": { + "const": "create_conversion_action", + "type": "string" + } + }, + "required": [ + "type", + "name", + "category" + ], + "type": "object" + }, + { + "description": "Set how many conversions one ad click can produce for a conversion action", + "properties": { + "conversion_action_id": { + "description": "conversion_action.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + }, + "counting": { + "enum": [ + "ONE_PER_CLICK", + "MANY_PER_CLICK" + ], + "type": "string" + }, + "type": { + "const": "set_conversion_counting", + "type": "string" + } + }, + "required": [ + "type", + "conversion_action_id", + "counting" + ], + "type": "object" + }, + { + "description": "Import a GA4 key event into Google Ads as a conversion action, so campaigns can count and bid on it. The GA4 property must be linked to this account", + "properties": { + "event_name": { + "description": "The GA4 key event, e.g. generate_lead, purchase, sign_up", + "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$", + "type": "string" + }, + "primary": { + "default": true, + "description": "Primary actions count in Conversions and can steer bidding", + "type": "boolean" + }, + "property_id": { + "description": "GA4 property id (from analytics_properties)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "import_ga4_key_event", + "type": "string" + } + }, + "required": [ + "type", + "property_id", + "event_name" + ], + "type": "object" + } +] - removed
Input schema / properties / confirm_switchRemoved value: -{ - "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", - "type": "boolean" -}
- Changed
run_gaql1 field changed- removed
Input schema / properties / confirm_switchRemoved value: -{ - "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", - "type": "boolean" -}
- Added
switch_account
5 tool updates
v0.15.0- Added
analytics_landing_pages - Added
analytics_properties - Added
analytics_report - Added
analytics_setup - Added
propose_analytics_changes
7 tool updates
v0.14.1- Changed
account_overview1 field changed- added
Input schema / properties / confirm_switchAdded value: +{ + "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", + "type": "boolean" +}
- Removed
gaql_fields - Changed
keyword_ideas1 field changed- added
Input schema / properties / confirm_switchAdded value: +{ + "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", + "type": "boolean" +}
- Changed
keyword_metrics3 fields changed- added
Input schema / properties / confirm_switchAdded value: +{ + "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", + "type": "boolean" +} - changed
Input schema / properties / keywords / descriptionPrevious value: -"Keywords to look up"New value: +"Keywords to look up, up to 500" - changed
Input schema / properties / keywords / maxItemsPrevious value: -100New value: +500
- Changed
paid_organic_overlap1 field changed- added
Input schema / properties / confirm_switchAdded value: +{ + "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", + "type": "boolean" +}
- Changed
propose_changes1 field changed- added
Input schema / properties / confirm_switchAdded value: +{ + "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", + "type": "boolean" +}
- Changed
run_gaql1 field changed- added
Input schema / properties / confirm_switchAdded value: +{ + "description": "Only after the user has agreed to spend their plan's account switch (a call answered \"Account switch:\"). Leave out otherwise", + "type": "boolean" +}
21 tool updates
v0.11.0- First observed
account_overview - First observed
apply_changes - First observed
billing - First observed
change_history - First observed
discard_proposal - First observed
disconnect - First observed
gaql_fields - First observed
keyword_ideas - First observed
keyword_metrics - First observed
list_accounts - First observed
paid_organic_overlap - First observed
propose_changes - First observed
run_gaql - First observed
search_console_inspect_urls - First observed
search_console_opportunities - First observed
search_console_performance - First observed
search_console_sitemaps - First observed
search_console_sites - First observed
search_console_summary - First observed
search_console_trend - First observed
undo_changes
TDQS
Scored across 26 tools
Most tools target clearly distinct resources or lifecycle steps. The main possible confusion is among the Search Console analytical tools (summary/performance/trend/opportunities) and between propose/apply/undo proposal steps, but their descriptions differentiate them well.
Names are all readable snake_case, but conventions are mixed: some are verb_noun action names (list_accounts, propose_changes, apply_changes), while many read tools are noun phrases (billing, account_overview, keyword_ideas) and service tools use domain prefixes. It is understandable but not a single predictable pattern.
26 tools is on the heavy side, though it reflects three distinct Google surfaces: Ads, GA4, and Search Console. Most tools earn their place, but some reporting/analytics tools could potentially be consolidated.
The surface covers account management, proposal/apply/undo lifecycle, Ads querying, keyword research, GA4 setup/reporting, and Search Console analysis with few dead ends. Some niche operations rely on run_gaql or are explicitly outside scope, such as sitemap submission, which is acceptable.
Maintenance
Related MCP Connectors
Google Ads, GA4, Search Console and Tag Manager for AI assistants. Every change is proposed first.
Google Ads, Reddit Ads, GA4 and Tag Manager in your AI client, with a preview before every change.
Run Google Ads and Meta Ads from ChatGPT or Claude: audit wasted spend, create and manage campaigns.
Connect authorized ad accounts to AI assistants for audits, reporting, and approval-gated changes.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to manage Google Ads accounts by providing tools for querying account data and performing write operations such as updating campaign budgets, statuses, and bidding strategies.2Apache 2.0
- AlicenseAqualityFmaintenanceEnables managing Google Ads campaigns through an AI assistant with read-only reporting, recommendations, and gated write operations for bids, budgets, and statuses, all backed by preview and audit logging.311MIT
- AlicenseAqualityAmaintenanceEnables reading and analyzing Google Ads data, planning keywords, and previewing campaign changes before applying them, all through natural language.35593 npm1Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables authorized users to manage Google Ads accounts through natural language, with guardrails like role tiers, account allowlists, spend limits, and two-step confirmations to prevent accidental changes.-