Camberstack
Camberstack is an MCP server that connects AI clients to Google Ads and optionally Search Console, Analytics, and Merchant Center, letting them read accounts, analyze performance, and safely propose, apply, and undo approved changes.
Read Google Ads data: list accounts, view campaign spend/conversions, run read-only GAQL queries, and research keyword ideas and metrics.
Analyze Search Console: list sites, compare performance, find trends and opportunities, inspect indexed URLs, and view sitemaps.
Analyze Google Analytics: list GA4 properties, inspect setup, review landing-page performance, and run custom GA4 reports.
Analyze Merchant Center: list accounts, review product issues and reports, and join product problems with Shopping/Performance Max spend.
Find paid/organic opportunities: join Ads search terms with Search Console queries to spot overlap and gaps.
Propose Google Ads changes without applying them: create campaigns (Search, Display, Demand Gen, Performance Max), edit/pause/enable/delete ads, keywords, ad groups, campaigns, budgets, bids, targeting, negatives, conversion actions, assets, schedules, and more.
Propose Analytics and Merchant Center changes: create GA4 properties, manage key events/linking, update product attributes, exclude/include products, and manage product overrides.
Approve and apply safely: proposals are dry-run and summarized; apply only after explicit approval, with risky changes flagged.
Undo and audit: reverse applied changes where possible through new proposals, view change history, and discard open proposals.
Manage access and plans: switch active accounts, view billing/plan limits, and disconnect Google access.
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 applied changes can be undone in one call, on every plan, apart from deletions Google can't reverse, which are flagged first. 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, plus |
| 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 | sends the user's approved message to the maintainer; no account data or conversation |
| no | checks sitemap and property changes against the live property and stores a proposal |
| 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 | the Merchant Center accounts the login can read (sub-accounts included); if Merchant Center isn't granted yet, a personal link that adds it |
| no | account issues, product status counts, and each product issue with how many products it hits and examples; or one product's issues in full |
| no | any read-only Merchant Center Query Language (MCQL) query, e.g. Shopping clicks per product from |
| no | Merchant Center problems (disapproved, limited, pending) joined with what each product earned in Shopping and Performance Max ads, most value first, and whether it stopped spending in the last 7 days |
| no | like |
| 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.
Merchant Center accounts are their own plan allowance, the same size as Google Ads' (Free 1, Pro 5), counted as
mc:<id> in tool_calls with their own switch (switch_account takes mc:<id>).
The Merchant Center tools need content, which isn't part of connecting: the first call without it
returns a personal /connect/merchant-center link that adds it. They're listed only for ADMIN_EMAILS until
MERCHANT_PUBLIC's date (or =1). Before any call works, the Cloud project needs
the Merchant API enabled and registered once with a production Merchant Center account the operator administers
(POST https://merchantapi.googleapis.com/accounts/v1/accounts/{ID}/developerRegistration:registerGcp); merchants
don't register. Unregistered, calls answer 401 "not registered", which the tools report as Camberstack's to fix.
Reports work on standalone accounts and sub-accounts, not on an advanced account itself. Account 000000001 is the
demo (sample data: two best sellers disapproved for a price mismatch 9 days ago; overrides there fix the issue).
Products Camberstack creates live in its own primary API source ("Camberstack products"); only those can be updated in place or deleted (undo re-creates them from Camberstack's copy). Adding an offer_id another feed already has is refused, since Google would move that product into our source ("offer stealing").
Merchant Center changes never edit the merchant's feed. Each is an override in Camberstack's own supplemental data source
("Camberstack overrides"), created on the first write. Google applies a supplemental source only once it's in a primary
source's rules, so the first override on a feed's products also patches that feed's defaultRule to put ours first
(every source already there is kept): the summary shows it as a ⚠ line. Feeds made in the Merchant Center UI or by
autofeed can't be patched, and the proposal says so. Google can't read overrides back, so merchant_overrides keeps
Camberstack's copy per product; undo restores exactly that (removing the input when there was none). The Merchant API
has no dry run: re-resolving at apply is the check, as with GA4. Untested against a live account until the project is
registered: try a Shopify-managed feed's rule patch on dev before opening it up.
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).
Delete: keywords, ads, ad groups, campaigns, a campaign's negatives and sitelinks (
delete_*).Edit and organize: edit a responsive search ad in place (it keeps its id and stats), ad group negatives, shared negative lists, ad schedules, device bids, callouts, snippets, business name, logos and images, AI Max and Google-written text, conversion value, window and attribution, remarketing lists, applying or dismissing recommendations, and review requests for exemptible refusals.
Measure: create or remove a conversion action, set its counting, import a GA4 key event, scope a campaign to one conversion goal.
Connect: link or unlink a Merchant Center account (
productLinks:create/:remove; neither dry-runs: create has none and remove's always answers 500, so propose checks the account is reachable and not a test account, which Google won't link).
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, deleting an ad, ad group or campaign. Undo removes only what Camberstack itself created. Google can't restore a removed ad, ad group, campaign or conversion action, so those carry a ⚠ and no undo (a GA4 import is the exception: undo imports it again). Undo adds a deleted keyword back with its id and stats, and a negative or sitelink as a new one; a paused keyword has no undo. (Undoing a GA4 import removes the action, since Google can't hide it again; importing again restores it.) Removing a verified Search Console property carries a ⚠ and no undo: it has to be added and verified again.
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
(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. Connections from before 0.25.0 hold webmasters.readonly, which still reads: their first Search Console proposal returns the /connect/search-console link. 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=… \
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: |
| public origin, the OAuth issuer (default |
| SQLite location (default |
| 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 |
| When the Merchant Center tools open to everyone. |
| the Agency plan's price (its own product); unset = 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.
License
MIT
Available Tools
33 toolsaccount_overviewAccount overviewARead-onlyInspect
Spend, clicks, conversions and cost per conversion per campaign over a window, plus attention when something needs a look: disapproved ads and why, Google's recommendations, primary conversions gone quiet.
| 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 safety is covered. The description goes beyond them by disclosing the return shape: per-campaign performance metrics plus a diagnostic `attention` block (disapproval reasons, recommendations, conversions gone quiet) — real value an agent can't get from 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?
A single sentence, front-loaded with the primary metrics, with the exception/diagnostic part trailing after the colon. Every clause carries information, though the dense colon-list takes a moment to parse.
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 must convey what comes back, and it does: metric set, grain, window, and the three diagnostic categories. Minor gaps remain — whether results are rows per campaign, what the `attention` structure looks like, and any currency/aggregation caveats.
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 schema already explains `days` (1-365, default 30, ending yesterday) and `customer_id` (with or without dashes, from list_accounts). The description's 'over a window' only echoes this, adding no format or constraint detail 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?
It names a specific set of metrics (spend, clicks, conversions, CPA) at a stated grain (per campaign) over a window, and separately describes the `attention` section with three named diagnostics. It is clearly distinguishable from the raw-query sibling run_gaql and the analytics_* tools, but it never explicitly contrasts itself with them.
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, when-not-to-use, or alternative named. The 'plus `attention` when something needs a look' clause describes output content, not selection guidance, so an agent must infer that this is a first-stop account summary rather than a targeted report.
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, unless its summary says otherwise, 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?
Adds substantial behavior beyond annotations: all-or-nothing application, Google-side checks, rollback on failure, logging, reversibility via undo_changes, and the special needs-approval outcome when the account changed. This is exactly the context an agent needs for a destructive, non-idempotent mutation.
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 core action in the first sentence, then adds approval requirement, atomicity, reversal, and stale-account handling. Every sentence carries operational information 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?
For a destructive mutation with one parameter and no output schema, the description covers prerequisites, transactional behavior, rollback, reversal, logging, and the stale-account result. Nothing important is missing for correct invocation.
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% for the single required proposal_id parameter, and the schema already says it is the proposal_id returned by a propose tool. The description links the proposal to propose_changes but does not add format or validation details 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: applies a proposal from propose_changes to the account. It clearly distinguishes this mutation tool from sibling proposal tools like propose_changes, discard_proposal, and undo_changes.
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 says to call only after the user has approved the proposal, and explains the workflow when the account changed: show the new needs-approval proposal and apply only after approval. It also names undo_changes as the reversal path, giving clear alternatives and conditions.
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.
merchant_accountsList Merchant Center accountsARead-onlyInspect
Lists the Google Merchant Center accounts this Google login can read, including sub-accounts of an advanced (multi-client) account. Use an account_id from here in the other Merchant Center tools. If Merchant Center 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 declare readOnlyHint and non-destructive, so the safety profile is covered. The description adds behavior the annotations can't: it discloses the not-connected case and that the response then carries a grant_url the user must open to add Merchant Center — genuinely useful operational context an agent needs to handle the empty/error path.
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 what it lists, then the downstream use, then the edge case. No repetition of the title or annotations; every sentence carries distinct 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 and no params, the description carries the return-value burden and does address the notable branch (grant_url when unconnected). It doesn't characterize the shape of the returned account objects (id, name, sub-account nesting), which would be the last missing piece.
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?
Zero parameters, so the baseline is 4. The description still adds value by explaining where the account_id consumed by sibling tools comes from, tying this no-arg call into the broader workflow.
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 ('Lists') and resource ('Google Merchant Center accounts'), plus the scope detail that sub-accounts of advanced/multi-client accounts are included. That scope detail plus the Merchant Center qualifier is enough to separate it from sibling list_accounts/account_overview 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?
Gives a clear downstream directive: 'Use an account_id from here in the other Merchant Center tools,' which establishes this as the entry point for the merchant_* family. It stops short of naming an explicit alternative or a when-not-to-use condition, so it's clear context rather than full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merchant_ad_spendMerchant Center issues by ad spendARead-onlyInspect
Which Merchant Center problems cost money: products that are disapproved, limited or pending, joined with what they earned in Shopping and Performance Max ads (cost, clicks, conversions, conversion value) over the window, most value first, and whether each has stopped spending in the last 7 days. Use it when Shopping or Performance Max results drop, before fixing issues one by one. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days, ending yesterday; reach back before a drop | |
| limit | No | Most products to return | |
| account_id | Yes | Merchant Center account ID, digits only (from merchant_accounts) | |
| 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, and the trailing 'Changes nothing' only restates that. The genuinely additive context is behavioral output detail — value-descending ordering and the last-7-days stopped-spending flag — but there is no discussion of rate limits, data freshness, or how missing spend data is represented.
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 but well-ordered sentence front-loads the core purpose, then usage guidance, then the safety note. Every clause adds something, though the packed parenthetical of metrics is slightly heavy.
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 must describe returns, and it does: the issue states, the joined ad metrics, the sort order, and the stopped-spending flag. Combined with a fully covered input schema, 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?
Schema description coverage is 100%, so all four parameters are already documented in the schema, including the days window and limit. The description reinforces the window concept ('over the window', 'reach back before a drop') but adds no syntax, constraints, or semantics 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 resource and outcome: disapproved/limited/pending products joined with Shopping and Performance Max ad spend. It explicitly names return fields (cost, clicks, conversions, conversion value) and ordering (most value first), which distinguishes it clearly from merchant_product_issues.
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 trigger: 'Use it when Shopping or Performance Max results drop, before fixing issues one by one.' That implies the alternative (merchant_product_issues without spend context) but never names it explicitly, so there is no explicit exclusion or named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merchant_product_issuesMerchant Center product issuesARead-onlyInspect
Why products aren't showing on Google (Shopping ads and free listings): the account's own issues, how many products are eligible, limited, pending or disapproved, and every product issue (such as a price mismatch or a missing GTIN) with how many products it affects, worst first, and a few example products. With offer_id, that one product's issues in full. Use it when Shopping or Performance Max spend or clicks drop, or products are missing. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| examples | No | Example products listed per issue | |
| offer_id | No | One product's ID as in the feed (offer_id), to see its issues in full | |
| account_id | Yes | Merchant Center account ID, digits only (from merchant_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds real substance beyond the readOnlyHint/destructiveHint annotations: issue ordering ('worst first'), the inclusion of example products, and the offer_id drill-down mode. 'Changes nothing' duplicates the annotation rather than extending it, which keeps this from 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?
The core purpose is front-loaded in the opening clause and every sentence carries information. It is a dense single paragraph, however, and the parenthetical examples ('such as a price mismatch or a missing GTIN') add length without changing agent behavior.
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, and the description compensates by describing the return shape: eligibility counts, an ordered issue list with affected product counts, and sample products. An agent knows what it will get and in what order.
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 explicitly explains the modal behavior of offer_id ('that one product's issues in full'), which is a semantic the schema only hints at. The examples parameter is only implicitly covered by 'a few example products'.
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 — it surfaces why products aren't showing on Google, including account-level issues, eligibility counts, and per-issue product impact. It clearly distinguishes itself from siblings like merchant_report or merchant_accounts by naming the Shopping/free-listings diagnosis context.
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 gives explicit triggering conditions: 'Use it when Shopping or Performance Max spend or clicks drop, or products are missing.' That is far better than implied usage, though it does not name a specific alternative tool to use when those symptoms are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merchant_reportRun a Merchant Center reportARead-onlyInspect
Runs a read-only Merchant Center Query Language (MCQL) query on one account and returns up to limit rows. One view per query. product_performance_view: segments date, week, offer_id, title, brand, marketing_method (ADS or ORGANIC), customer_country_code, category_l1…l5, product_type_l1…l5, custom_label0…4; metrics clicks, impressions, click_through_rate (conversions, conversion_value and conversion_rate count free listings only). It needs a date range and at least one metric, e.g. SELECT offer_id, title, clicks, impressions FROM product_performance_view WHERE date DURING LAST_30_DAYS AND marketing_method = 'ADS' ORDER BY clicks DESC LIMIT 50. product_view (current status): id, offer_id, title, brand, price, availability, gtin, feed_label, aggregated_reporting_context_status (ELIGIBLE, ELIGIBLE_LIMITED, PENDING, NOT_ELIGIBLE_OR_DISAPPROVED), item_issues, click_potential (LOW, MEDIUM, HIGH); id must be selected. Also price_competitiveness_product_view, price_insights_product_view and best_sellers_product_cluster_view. WHERE joins conditions with AND only (no OR); dates as date BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' or date DURING LAST_7_DAYS / LAST_30_DAYS. Reports work on standalone accounts and sub-accounts, not on an advanced account itself. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most rows to return | |
| query | Yes | An MCQL SELECT statement | |
| account_id | Yes | Merchant Center account ID, digits only (from merchant_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, and non-destructive behavior, and the description adds substantial context beyond that. It discloses 'Changes nothing,' the one-view-per-query rule, required query elements, conversion metric scope, account restrictions, and the row limit.
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 purpose and example are front-loaded, and most content is useful for correct MCQL construction. The description is long and dense, with several field lists that could be formatted more readably, but the details largely earn their 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?
For a complex query-language tool with no output schema, the description covers return row behavior, view schemas, query constraints, supported date syntax, account exclusions, and an example. It is complete enough for an agent to invoke 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?
Although schema coverage is 100%, the description adds significant meaning for the query parameter: MCQL SELECT syntax, available views and fields, date-range requirements, view constraints, and an example. It also clarifies account_id scope and limit behavior beyond the schema text.
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 uses a specific verb and resource: it runs an MCQL query on one Merchant Center account and returns rows. It does not explicitly route the agent away from close siblings such as merchant_ad_spend, merchant_product_issues, or run_gaql, so sibling differentiation relies on domain knowledge.
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 gives clear usage context: one view per query, a required date range and metric, AND-only WHERE clauses, supported date formats, and the account-type exclusion. However, it does not explicitly say when to use this tool instead of sibling report tools.
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 rather than edit it: 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; and deleting: delete_keyword, delete_ad, delete_ad_group, delete_campaign (ads, ad groups and campaigns can't be undone), delete_negative_keywords, delete_sitelinks; and negatives: add_ad_group_negatives, delete_ad_group_negatives, create_negative_list, edit_negative_list, apply_negative_list, delete_negative_list; and edit_responsive_search_ad, which keeps the ad instead of replacing it; and set_ad_schedule, set_device_bid, add_campaign_assets, delete_campaign_assets, set_ai_max, set_conversion_settings; and create_remarketing_list, set_campaign_audience, act_on_recommendation; and link_merchant_center / unlink_merchant_center (Shopping and Performance Max need the link). 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?
Annotations declare non-destructive and idempotent, and the description adds real context beyond them: the tool dry-runs against the live account rather than only validating locally, changes are persisted as a proposal object, irreversible sub-operations are flagged inline ('ads, ad groups and campaigns can't be undone', remove_conversion_action 'permanent unless a GA4 import'), and a hard 50-change cap with a specific counting rule is disclosed.
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 purpose and the approval instruction are front-loaded and earn their place, but the middle is a single ~250-word run-on sentence chained with 'and ... and ...' spanning building/tuning/deleting/negatives, which is hard to scan or use as a lookup. The information is useful; the structure is not.
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 tool with dozens of polymorphic change types and no output schema, the description supplies what an agent needs: what it returns (plain-English summary with ⚠ lines), that nothing is applied, how to proceed after approval, and the size limit. Nothing essential for 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% and each oneOf variant carries its own description, so the baseline is 3. The description adds value by enumerating which change `type` values are accepted and by stating that each keyword counts as one change for the cap, but it does not repeat per-variant parameter semantics — which is appropriate here.
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 opening sentence names the specific action (checks against the live account, dry-runs with Google, stores a proposal, returns a plain-English summary) and states 'Nothing is changed', which cleanly separates it from the apply_changes sibling. The exhaustive list of supported change types makes the resource scope unmistakable.
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?
Explicit workflow guidance: show the summary to the user, apply only after approval, surface any ⚠ line before approval. It also gives the batching rule — at most 50 changes, split into several proposals up front and show all summaries together — which is the kind of when/how instruction agents otherwise get wrong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
propose_merchant_changesPropose Merchant Center changes (applies nothing)AIdempotentInspect
Checks Merchant Center product changes against the live account 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: set_product_attributes (override a product's price, sale price, GTIN, brand, title, availability, …, e.g. to fix a price mismatch or a missing GTIN), exclude_products / include_products (from Shopping ads or free listings), clear_product_overrides; and add_product / update_product / delete_product for products Camberstack creates in its own data source. Changes to products from the merchant's feed are overrides in Camberstack's own supplemental data source, layered on top: the feed itself is never edited. Point out any ⚠ line before they approve. A fix in the feed or the store (Shopify, …) lasts longer: suggest it too.
| Name | Required | Description | Default |
|---|---|---|---|
| changes | Yes | Changes to propose; several can go in one proposal | |
| account_id | Yes | Merchant Center account ID, digits only (from merchant_accounts) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: the call writes nothing, it produces a proposal with a plain-English summary, feed-based products become overrides in Camberstack's supplemental data source and the merchant's feed is never edited, delete_product is undoable by re-creation, and ⚠ lines must be surfaced before approval. That is real behavioral disclosure for a mutation-adjacent tool whose annotations only say non-destructive/idempotent/open-world.
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 essential fact (checks and proposes, changes nothing) and the required follow-up workflow before any enumeration. The 'Supported:' catalogue is information-dense but long and runs together in one paragraph; a short bulleted list would scan faster, though little is genuinely 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?
For a 2-parameter tool with full schema coverage, no output schema, and non-destructive annotations, the description covers purpose, safety, workflow, approval gating, reversibility, and the feed-vs-supplemental-data-source model. An agent has everything needed to call it and route the result 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; the description earns above that by explaining the semantics of the change types as a set — in particular that update_product only applies to Camberstack-created products while feed products must use set_product_attributes, and that feed changes are overrides layered on a supplemental source. It also gives motivating examples (price mismatch, missing GTIN, out-of-stock exclusion).
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 Merchant Center product changes ... stores them as a proposal'), and immediately clarifies the crucial scope that nothing is applied. It distinguishes itself from the write-path siblings by naming apply_changes and undo_changes and by enumerating exactly which change types it accepts.
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 — propose, show the summary, apply only after user approval via apply_changes, reverse with undo_changes — plus a stategic hint to also suggest fixing things in the feed or store. The one gap is that it never routes the agent against the generic propose_changes / propose_analytics_changes siblings; the reader must infer that merchant product changes belong here.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
propose_search_console_changesPropose Search Console changes (applies nothing)AIdempotentInspect
Checks Search Console 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, except where a ⚠ line says it can't). Supported: submit_sitemap (also resubmits, so Google reads it again), delete_sitemap, add_site (unless the login already owns the domain, it stays unverified until the user verifies ownership in Search Console), remove_site. Requesting indexing isn't possible through Google's API. A connection made before editing existed answers with a link that adds it. 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 already declare readOnlyHint=false, destructiveHint=false and idempotentHint=true; the description adds substantial context beyond that — proposals are stored, add_site leaves the property unverified, delete_sitemap doesn't stop crawling, remove_site can't be recovered by undo, and indexing can't be requested. The only gap is that it doesn't say where the proposal is stored or how long it lives, and the ⚠ mechanism is referenced without a full definition. No contradiction with annotations (destructiveHint=false is consistent with 'applies nothing').
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 key fact ('nothing is changed') and the approval workflow before the supported-types list. The long parentheticals in the second sentence make it denser than necessary, but every clause carries real 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 tool with a single, deeply structured parameter and no output schema, the description covers prerequisites (user verification for add_site), irreversibility (remove_site), impossible operations (indexing requests), and the stale-connection edge case. An agent has what it needs to call this correctly and to instruct the user afterward.
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 per-variant descriptions, so the baseline is 3; the description still earns credit by enumerating the four supported change types and adding operational nuance (submit_sitemap resubmits, add_site may stay unverified) that helps an agent pick the right `type` value. It does not mention the maxItems of 20 or explain what the ⚠ line looks like in the payload.
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 Search Console changes against the live property and stores them as a proposal') and immediately disambiguates scope with 'nothing is changed'. The title and first sentence make clear this is a dry-run/staging tool distinct from apply_changes and the other propose_* siblings.
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 use undo_changes to reverse (with the ⚠ exception named). It also names apply_changes and undo_changes as the alternatives, so routing is unambiguous.
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: propose_search_console_changes submits one.
| 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 'Changes nothing' reinforces rather than informs. The real added value is the disclosure of what the payload contains (last download timestamp, URL count, error and warning counts), which lets an agent judge fitness before calling; only pagination and per-sitemap edge cases are left unstated.
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 with no filler: the first front-loads the resource and its returned fields, the second handles the safety/routing note. 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?
With no output schema, the description carries the burden of describing return values and does so concretely. A one-parameter read tool with annotations and a fully documented schema needs nothing further.
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 single parameter has 100% schema description coverage, including the exact sc-domain vs URL-prefix format and a pointer to search_console_sites for discovering it. The description adds no parameter detail, so the baseline of 3 applies since the schema carries the load.
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 specific resource (the sitemaps submitted for a website) and enumerates the returned facts: last download time, URL count, error and warning counts. It also distinguishes itself from the mutating sibling propose_search_console_changes, so an agent can tell the two apart 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 clearly frames this as the read path and names propose_search_console_changes as the alternative for submitting one, which is an explicit exclusion. It stops short of explaining when to reach for this versus adjacent reporting siblings such as search_console_summary or search_console_inspect_urls, so it is clear context rather than a full routing guide.
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.
send_feedbackSend feedback to CamberstackAInspect
Sends the user's message to Camberstack's maintainer, who reads every one and can reply to the user's Google email. Use it when the user wants to report a bug or ask for something Camberstack doesn't do. Show them the exact message first and send it only after they agree. Put in only what they want said: no account IDs, campaign data or conversation history.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | bug, idea (a request), or other | idea |
| message | Yes | The message, as the user approved it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say this is a non-destructive, non-read-only, non-idempotent write with no open-world flag. The description goes well beyond that: a human reads it, a reply channel exists via the user's Google email, and a mandatory user-approval step precedes the send. It also discloses a data-minimization constraint (no account IDs, campaign data, or conversation history), which is real behavioral context an agent must respect.
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?
Four sentences, no waste, front-loaded with purpose then usage then safety protocol. Each sentence carries a distinct obligation (what it does, when, approval gate, content restriction).
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 could say what a call returns or how failures surface (e.g., if no Google email is on file to receive the reply). Otherwise complete for a 2-parameter write tool with full annotation coverage.
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 enum and length bounds are already documented; description adds genuine meaning by constraining content ("only what they want said", no account IDs/campaign data/history) and clarifying that the message must be the user-approved text. The `kind` parameter is left entirely to the schema, which is acceptable given full coverage.
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 ("Sends the user's message to Camberstack's maintainer") plus the recipient's behavior (reads every one, can reply by email). This is unmistakably distinct from every sibling, which are all analytics/merchant/search-console operations.
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 triggering conditions ("when the user wants to report a bug or ask for something Camberstack doesn't do") and an explicit procedural gate: show the exact message first, send only after they agree. It also specifies what must NOT be included, which is an exclusion rule.
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 a 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). Called with neither, it answers with the "Account switch:" notice and spends nothing. Changes nothing in Google Ads; a no-op for an account that is already active. Merchant Center accounts are a separate allowance with their own switch: pass mc:<account_id>, as the notice gives it.
| 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?
Goes well past the destructiveHint/idempotentHint annotations: it quantifies the cost (one switch per 30 days), discloses the side effect on the least recently used active account and its lock duration, notes that switching back also counts, and says it changes nothing in Google Ads. That is exactly the 'what gets consumed/destroyed' context the annotations alone cannot convey.
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 cost and effect, then preconditions, then edge cases – a sound ordering. Some sentences are dense and clause-stacked ('locks until the date the "Account switch:" notice gave, switching back included'), which costs a little readability but no sentence is padding.
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 still tells the agent what the tool answers when called without the required prior notice. Cost, side effects, no-op behavior, and the Merchant Center variant are all covered for a single-parameter mutation 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?
The schema already documents customer_id at 100% coverage, so the schema carries the base load. The description still adds real value by specifying the mc:<account_id> form for Merchant Center accounts, which the schema description does not mention, though it leaves the dashes/format handling to 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: it spends the plan's one account switch per 30 days to make customer_id the active account. No sibling tool touches plan-level account switching, and the description makes that unique role unmistakable.
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 preconditions ('only after a tool answered "Account switch:" for this account and the user agreed, or answered "Account choice:" and the user picked this account') plus the graceful fallback path when neither holds. The 'a first pick spends no switch' carve-out resolves the main ambiguity an agent would hit.
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.
8 tool updates
v0.25.0- Added
merchant_accounts - Added
merchant_ad_spend - Added
merchant_product_issues - Added
merchant_report - 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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "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": "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": "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" - }, - "request_review": { - "description": "Only after Google refused a keyword as exemptible and the user says it complies: the policy and flagged text from the refusal", - "items": { - "properties": { - "policy_name": { - "minLength": 1, - "type": "string" - }, - "violating_text": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "policy_name", - "violating_text" - ], - "type": "object" - }, - "maxItems": 10, - "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": "Digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "request_review_topics": { - "description": "Only after Google refused this and the user says it complies: the topics from the refusal, which asks Google to review it. PROHIBITED topics can't be", - "items": { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "maxItems": 10, - "minItems": 1, - "type": "array" - }, - "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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" - }, - { - "description": "Delete one keyword. Undo adds it back with its history", - "properties": { - "ad_group_id": { - "description": "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": "delete_keyword", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_id" - ], - "type": "object" - }, - { - "description": "Delete one ad. Permanent, with no undo: say so before they approve; to only stop it, pause it", - "properties": { - "ad_group_id": { - "description": "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": "delete_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "ad_id" - ], - "type": "object" - }, - { - "description": "Delete an ad group with its ads and keywords. Permanent, with no undo: say so before they approve; to only stop it, pause it", - "properties": { - "ad_group_id": { - "description": "Digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "delete_ad_group", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id" - ], - "type": "object" - }, - { - "description": "Delete a whole campaign. Permanent, with no undo: say so before they approve; to only stop it, pause it", - "properties": { - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "delete_campaign", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Delete negative keywords from a campaign, so those searches can show its ads again", - "properties": { - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_ids": { - "description": "campaign_criterion.criterion_id of each negative, from run_gaql WHERE campaign_criterion.negative = TRUE", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "delete_negative_keywords", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "criterion_ids" - ], - "type": "object" - }, - { - "description": "Take sitelinks off a campaign. Google can't edit a sitelink: to change one, delete it and add_sitelinks in the same proposal", - "properties": { - "asset_ids": { - "description": "asset.id of each sitelink, from run_gaql FROM campaign_asset WHERE campaign_asset.field_type = 'SITELINK'", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 8, - "minItems": 1, - "type": "array" - }, - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "delete_sitelinks", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "asset_ids" - ], - "type": "object" - }, - { - "description": "Block searches in one ad group, so it stops catching another group's searches", - "properties": { - "ad_group_id": { - "description": "Digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "add_ad_group_negatives", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "keywords" - ], - "type": "object" - }, - { - "description": "Delete negative keywords from an ad group", - "properties": { - "ad_group_id": { - "description": "Digits only (ad_group.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "criterion_ids": { - "description": "ad_group_criterion.criterion_id of each negative, from run_gaql WHERE ad_group_criterion.negative = TRUE", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "delete_ad_group_negatives", - "type": "string" - } - }, - "required": [ - "type", - "ad_group_id", - "criterion_ids" - ], - "type": "object" - }, - { - "description": "Create a shared negative keyword list, optionally on campaigns", - "properties": { - "campaign_ids": { - "default": [], - "description": "Campaigns to use it on", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "keywords": { - "items": { - "properties": { - "match_type": { - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "name": { - "description": "List name; must not match an existing list", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "create_negative_list", - "type": "string" - } - }, - "required": [ - "type", - "name", - "keywords" - ], - "type": "object" - }, - { - "description": "Add or remove keywords in a shared negative list. This changes every campaign using it, which the proposal lists", - "properties": { - "add": { - "default": [], - "items": { - "properties": { - "match_type": { - "enum": [ - "EXACT", - "PHRASE", - "BROAD" - ], - "type": "string" - }, - "text": { - "maxLength": 80, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text", - "match_type" - ], - "type": "object" - }, - "maxItems": 50, - "type": "array" - }, - "remove_criterion_ids": { - "default": [], - "description": "shared_criterion.criterion_id of each to remove", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "shared_set_id": { - "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "edit_negative_list", - "type": "string" - } - }, - "required": [ - "type", - "shared_set_id" - ], - "type": "object" - }, - { - "description": "Put a shared negative list on campaigns, or take it off", - "properties": { - "add_campaign_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "remove_campaign_ids": { - "default": [], - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "shared_set_id": { - "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "apply_negative_list", - "type": "string" - } - }, - "required": [ - "type", - "shared_set_id" - ], - "type": "object" - }, - { - "description": "Delete a shared negative list from every campaign. It has no undo: say so before they approve", - "properties": { - "shared_set_id": { - "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", - "pattern": "^\\d+$", - "type": "string" - }, - "type": { - "const": "delete_negative_list", - "type": "string" - } - }, - "required": [ - "type", - "shared_set_id" - ], - "type": "object" - }, - { - "description": "Edit a responsive search ad's words or link in place, instead of adding a new ad. Give only what changes", - "properties": { - "ad_id": { - "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "descriptions": { - "description": "The full new list, replacing the old one", - "items": { - "maxLength": 90, - "minLength": 1, - "type": "string" - }, - "maxItems": 4, - "minItems": 2, - "type": "array" - }, - "final_url": { - "maxLength": 2048, - "pattern": "^https?:\\/\\/", - "type": "string" - }, - "headlines": { - "description": "The full new list, replacing the old one", - "items": { - "maxLength": 30, - "minLength": 1, - "type": "string" - }, - "maxItems": 15, - "minItems": 3, - "type": "array" - }, - "path1": { - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "path2": { - "maxLength": 15, - "minLength": 1, - "type": "string" - }, - "request_review_topics": { - "description": "Only after Google refused this and the user says it complies: the topics from the refusal, which asks Google to review it. PROHIBITED topics can't be", - "items": { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "maxItems": 10, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "edit_responsive_search_ad", - "type": "string" - } - }, - "required": [ - "type", - "ad_id" - ], - "type": "object" - }, - { - "description": "Choose which days and hours a campaign runs, in the account's time zone, with optional bid changes. Hours left out don't run", - "properties": { - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "schedule": { - "description": "The whole new schedule, replacing the old one; empty means all day, every day", - "items": { - "properties": { - "bid_percent": { - "description": "Bid change in these hours, e.g. -20", - "maximum": 900, - "minimum": -90, - "type": "number" - }, - "day": { - "enum": [ - "MONDAY", - "TUESDAY", - "WEDNESDAY", - "THURSDAY", - "FRIDAY", - "SATURDAY", - "SUNDAY" - ], - "type": "string" - }, - "end_hour": { - "maximum": 24, - "minimum": 1, - "type": "integer" - }, - "start_hour": { - "maximum": 23, - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "day", - "start_hour", - "end_hour" - ], - "type": "object" - }, - "maxItems": 42, - "type": "array" - }, - "type": { - "const": "set_ad_schedule", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "schedule" - ], - "type": "object" - }, - { - "description": "Raise or lower a campaign's bids on one device. Smart bidding ignores everything here except -100", - "properties": { - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "device": { - "enum": [ - "DESKTOP", - "MOBILE", - "TABLET" - ], - "type": "string" - }, - "percent": { - "description": "Bid change in percent, e.g. -20; -100 stops showing on that device, 0 clears it", - "maximum": 900, - "minimum": -100, - "type": "number" - }, - "type": { - "const": "set_device_bid", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "device", - "percent" - ], - "type": "object" - }, - { - "description": "Add callouts, structured snippets, a business name, logos or images to a campaign", - "properties": { - "business_name": { - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "callouts": { - "default": [], - "description": "Short selling points, at most 25 characters each", - "items": { - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "type": "array" - }, - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "images": { - "default": [], - "description": "Images: landscape 1.91:1 or square 1:1", - "items": { - "description": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 0, - "type": "array" - }, - "logos": { - "default": [], - "description": "Square logos, 1:1", - "items": { - "description": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", - "maxLength": 2048, - "minLength": 1, - "type": "string" - }, - "maxItems": 5, - "minItems": 0, - "type": "array" - }, - "snippets": { - "default": [], - "items": { - "properties": { - "header": { - "enum": [ - "Amenities", - "Brands", - "Courses", - "Degree programs", - "Destinations", - "Featured hotels", - "Insurance coverage", - "Models", - "Neighborhoods", - "Service catalog", - "Shows", - "Styles", - "Types" - ], - "type": "string" - }, - "values": { - "items": { - "maxLength": 25, - "minLength": 1, - "type": "string" - }, - "maxItems": 10, - "minItems": 3, - "type": "array" - } - }, - "required": [ - "header", - "values" - ], - "type": "object" - }, - "maxItems": 4, - "type": "array" - }, - "type": { - "const": "add_campaign_assets", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Take assets off a campaign. No undo: add them again with add_campaign_assets", - "properties": { - "asset_ids": { - "description": "asset.id of each, from run_gaql FROM campaign_asset", - "items": { - "pattern": "^\\d+$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "field_type": { - "enum": [ - "CALLOUT", - "STRUCTURED_SNIPPET", - "BUSINESS_NAME", - "BUSINESS_LOGO", - "LOGO", - "AD_IMAGE" - ], - "type": "string" - }, - "type": { - "const": "delete_campaign_assets", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "field_type", - "asset_ids" - ], - "type": "object" - }, - { - "description": "Turn AI Max and automatically created text on or off for a campaign. Give only what changes", - "properties": { - "ai_max": { - "description": "AI Max for Search", - "type": "boolean" - }, - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "text_automation": { - "description": "Let Google write its own headlines and descriptions", - "type": "boolean" - }, - "type": { - "const": "set_ai_max", - "type": "string" - }, - "url_expansion": { - "description": "Let Google send people to other pages on the site", - "type": "boolean" - } - }, - "required": [ - "type", - "campaign_id" - ], - "type": "object" - }, - { - "description": "Change a conversion action's value, counting window or attribution. Give only what changes", - "properties": { - "attribution": { - "enum": [ - "LAST_CLICK", - "DATA_DRIVEN" - ], - "type": "string" - }, - "click_window_days": { - "description": "Days after a click a conversion still counts", - "maximum": 90, - "minimum": 1, - "type": "integer" - }, - "conversion_action_id": { - "description": "conversion_action.id from run_gaql", - "pattern": "^\\d+$", - "type": "string" - }, - "default_value": { - "maximum": 1000000, - "minimum": 0, - "type": "number" - }, - "type": { - "const": "set_conversion_settings", - "type": "string" - } - }, - "required": [ - "type", - "conversion_action_id" - ], - "type": "object" - }, - { - "description": "Create a list of the site's visitors, from the Google tag on the site. No customer data is uploaded", - "properties": { - "membership_days": { - "default": 30, - "description": "How long a visitor stays on the list", - "maximum": 540, - "minimum": 1, - "type": "integer" - }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "create_remarketing_list", - "type": "string" - }, - "url_contains": { - "description": "Visitors to pages whose URL contains this join the list, e.g. example.com", - "maxLength": 512, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "type", - "name", - "url_contains" - ], - "type": "object" - }, - { - "description": "Add a remarketing list to a campaign in observation, or take it off: ads still show to everyone, and you can see and bid on the list", - "properties": { - "bid_percent": { - "description": "Bid change for people on the list, e.g. 20", - "maximum": 900, - "minimum": -90, - "type": "number" - }, - "campaign_id": { - "description": "Digits only (campaign_id from account_overview or run_gaql)", - "pattern": "^\\d+$", - "type": "string" - }, - "on": { - "type": "boolean" - }, - "type": { - "const": "set_campaign_audience", - "type": "string" - }, - "user_list_id": { - "description": "user_list.id from run_gaql", - "pattern": "^\\d+$", - "type": "string" - } - }, - "required": [ - "type", - "campaign_id", - "user_list_id", - "on" - ], - "type": "object" - }, - { - "description": "Apply or dismiss one of Google's recommendations. Applying has no undo and Google picks the details: say so before they approve", - "properties": { - "action": { - "enum": [ - "APPLY", - "DISMISS" - ], - "type": "string" - }, - "recommendation_id": { - "description": "The end of recommendation.resource_name from run_gaql", - "pattern": "^[\\w=-]+$", - "type": "string" - }, - "type": { - "const": "act_on_recommendation", - "type": "string" - } - }, - "required": [ - "type", - "recommendation_id", - "action" - ], - "type": "object" - } -]New value: +[ + { + "description": "Block searches containing these words in one campaign", + "properties": { + "campaign_id": { + "description": "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": "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": "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": "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": "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": "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": "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": "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": "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "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": "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" + }, + "request_review": { + "description": "Only after Google refused a keyword as exemptible and the user says it complies: the policy and flagged text from the refusal", + "items": { + "properties": { + "policy_name": { + "minLength": 1, + "type": "string" + }, + "violating_text": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy_name", + "violating_text" + ], + "type": "object" + }, + "maxItems": 10, + "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": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "request_review_topics": { + "description": "Only after Google refused this and the user says it complies: the topics from the refusal, which asks Google to review it. PROHIBITED topics can't be", + "items": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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" + }, + { + "description": "Delete one keyword. Undo adds it back with its history", + "properties": { + "ad_group_id": { + "description": "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": "delete_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Delete one ad. Permanent, with no undo: say so before they approve; to only stop it, pause it", + "properties": { + "ad_group_id": { + "description": "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": "delete_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Delete an ad group with its ads and keywords. Permanent, with no undo: say so before they approve; to only stop it, pause it", + "properties": { + "ad_group_id": { + "description": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Delete a whole campaign. Permanent, with no undo: say so before they approve; to only stop it, pause it", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Delete negative keywords from a campaign, so those searches can show its ads again", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_ids": { + "description": "campaign_criterion.criterion_id of each negative, from run_gaql WHERE campaign_criterion.negative = TRUE", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "delete_negative_keywords", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "criterion_ids" + ], + "type": "object" + }, + { + "description": "Take sitelinks off a campaign. Google can't edit a sitelink: to change one, delete it and add_sitelinks in the same proposal", + "properties": { + "asset_ids": { + "description": "asset.id of each sitelink, from run_gaql FROM campaign_asset WHERE campaign_asset.field_type = 'SITELINK'", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 8, + "minItems": 1, + "type": "array" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_sitelinks", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "asset_ids" + ], + "type": "object" + }, + { + "description": "Block searches in one ad group, so it stops catching another group's searches", + "properties": { + "ad_group_id": { + "description": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_ad_group_negatives", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Delete negative keywords from an ad group", + "properties": { + "ad_group_id": { + "description": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_ids": { + "description": "ad_group_criterion.criterion_id of each negative, from run_gaql WHERE ad_group_criterion.negative = TRUE", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "delete_ad_group_negatives", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_ids" + ], + "type": "object" + }, + { + "description": "Create a shared negative keyword list, optionally on campaigns", + "properties": { + "campaign_ids": { + "default": [], + "description": "Campaigns to use it on", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "description": "List name; must not match an existing list", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "create_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "name", + "keywords" + ], + "type": "object" + }, + { + "description": "Add or remove keywords in a shared negative list. This changes every campaign using it, which the proposal lists", + "properties": { + "add": { + "default": [], + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "type": "array" + }, + "remove_criterion_ids": { + "default": [], + "description": "shared_criterion.criterion_id of each to remove", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "shared_set_id": { + "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "edit_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "shared_set_id" + ], + "type": "object" + }, + { + "description": "Put a shared negative list on campaigns, or take it off", + "properties": { + "add_campaign_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "remove_campaign_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "shared_set_id": { + "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "apply_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "shared_set_id" + ], + "type": "object" + }, + { + "description": "Delete a shared negative list from every campaign. It has no undo: say so before they approve", + "properties": { + "shared_set_id": { + "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "shared_set_id" + ], + "type": "object" + }, + { + "description": "Edit a responsive search ad's words or link in place, instead of adding a new ad. Give only what changes", + "properties": { + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "descriptions": { + "description": "The full new list, replacing the old one", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "The full new list, replacing the old one", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "request_review_topics": { + "description": "Only after Google refused this and the user says it complies: the topics from the refusal, which asks Google to review it. PROHIBITED topics can't be", + "items": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "edit_responsive_search_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_id" + ], + "type": "object" + }, + { + "description": "Choose which days and hours a campaign runs, in the account's time zone, with optional bid changes. Hours left out don't run", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "schedule": { + "description": "The whole new schedule, replacing the old one; empty means all day, every day", + "items": { + "properties": { + "bid_percent": { + "description": "Bid change in these hours, e.g. -20", + "maximum": 900, + "minimum": -90, + "type": "number" + }, + "day": { + "enum": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ], + "type": "string" + }, + "end_hour": { + "maximum": 24, + "minimum": 1, + "type": "integer" + }, + "start_hour": { + "maximum": 23, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "day", + "start_hour", + "end_hour" + ], + "type": "object" + }, + "maxItems": 42, + "type": "array" + }, + "type": { + "const": "set_ad_schedule", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "schedule" + ], + "type": "object" + }, + { + "description": "Raise or lower a campaign's bids on one device. Smart bidding ignores everything here except -100", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "device": { + "enum": [ + "DESKTOP", + "MOBILE", + "TABLET" + ], + "type": "string" + }, + "percent": { + "description": "Bid change in percent, e.g. -20; -100 stops showing on that device, 0 clears it", + "maximum": 900, + "minimum": -100, + "type": "number" + }, + "type": { + "const": "set_device_bid", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "device", + "percent" + ], + "type": "object" + }, + { + "description": "Add callouts, structured snippets, a business name, logos or images to a campaign", + "properties": { + "business_name": { + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "callouts": { + "default": [], + "description": "Short selling points, at most 25 characters each", + "items": { + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "images": { + "default": [], + "description": "Images: landscape 1.91:1 or square 1:1", + "items": { + "description": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 0, + "type": "array" + }, + "logos": { + "default": [], + "description": "Square logos, 1:1", + "items": { + "description": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "snippets": { + "default": [], + "items": { + "properties": { + "header": { + "enum": [ + "Amenities", + "Brands", + "Courses", + "Degree programs", + "Destinations", + "Featured hotels", + "Insurance coverage", + "Models", + "Neighborhoods", + "Service catalog", + "Shows", + "Styles", + "Types" + ], + "type": "string" + }, + "values": { + "items": { + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "header", + "values" + ], + "type": "object" + }, + "maxItems": 4, + "type": "array" + }, + "type": { + "const": "add_campaign_assets", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Take assets off a campaign. No undo: add them again with add_campaign_assets", + "properties": { + "asset_ids": { + "description": "asset.id of each, from run_gaql FROM campaign_asset", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "field_type": { + "enum": [ + "CALLOUT", + "STRUCTURED_SNIPPET", + "BUSINESS_NAME", + "BUSINESS_LOGO", + "LOGO", + "AD_IMAGE" + ], + "type": "string" + }, + "type": { + "const": "delete_campaign_assets", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "field_type", + "asset_ids" + ], + "type": "object" + }, + { + "description": "Turn AI Max and automatically created text on or off for a campaign. Give only what changes", + "properties": { + "ai_max": { + "description": "AI Max for Search", + "type": "boolean" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "text_automation": { + "description": "Let Google write its own headlines and descriptions", + "type": "boolean" + }, + "type": { + "const": "set_ai_max", + "type": "string" + }, + "url_expansion": { + "description": "Let Google send people to other pages on the site", + "type": "boolean" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Change a conversion action's value, counting window or attribution. Give only what changes", + "properties": { + "attribution": { + "enum": [ + "LAST_CLICK", + "DATA_DRIVEN" + ], + "type": "string" + }, + "click_window_days": { + "description": "Days after a click a conversion still counts", + "maximum": 90, + "minimum": 1, + "type": "integer" + }, + "conversion_action_id": { + "description": "conversion_action.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + }, + "default_value": { + "maximum": 1000000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "set_conversion_settings", + "type": "string" + } + }, + "required": [ + "type", + "conversion_action_id" + ], + "type": "object" + }, + { + "description": "Create a list of the site's visitors, from the Google tag on the site. No customer data is uploaded", + "properties": { + "membership_days": { + "default": 30, + "description": "How long a visitor stays on the list", + "maximum": 540, + "minimum": 1, + "type": "integer" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "create_remarketing_list", + "type": "string" + }, + "url_contains": { + "description": "Visitors to pages whose URL contains this join the list, e.g. example.com", + "maxLength": 512, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "name", + "url_contains" + ], + "type": "object" + }, + { + "description": "Add a remarketing list to a campaign in observation, or take it off: ads still show to everyone, and you can see and bid on the list", + "properties": { + "bid_percent": { + "description": "Bid change for people on the list, e.g. 20", + "maximum": 900, + "minimum": -90, + "type": "number" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "on": { + "type": "boolean" + }, + "type": { + "const": "set_campaign_audience", + "type": "string" + }, + "user_list_id": { + "description": "user_list.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "user_list_id", + "on" + ], + "type": "object" + }, + { + "description": "Apply or dismiss one of Google's recommendations. Applying has no undo and Google picks the details: say so before they approve", + "properties": { + "action": { + "enum": [ + "APPLY", + "DISMISS" + ], + "type": "string" + }, + "recommendation_id": { + "description": "The end of recommendation.resource_name from run_gaql", + "pattern": "^[\\w=-]+$", + "type": "string" + }, + "type": { + "const": "act_on_recommendation", + "type": "string" + } + }, + "required": [ + "type", + "recommendation_id", + "action" + ], + "type": "object" + }, + { + "description": "Link a Merchant Center account to this Google Ads account, so Shopping and Performance Max campaigns can use its products (the user must be an admin of both)", + "properties": { + "merchant_center_id": { + "description": "Merchant Center account ID (from merchant_accounts)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "link_merchant_center", + "type": "string" + } + }, + "required": [ + "type", + "merchant_center_id" + ], + "type": "object" + }, + { + "description": "Remove the link between a Merchant Center account and this Google Ads account; Shopping and Performance Max campaigns using its products stop serving", + "properties": { + "merchant_center_id": { + "description": "Merchant Center account ID (from merchant_accounts)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "unlink_merchant_center", + "type": "string" + } + }, + "required": [ + "type", + "merchant_center_id" + ], + "type": "object" + } +]
- Added
propose_merchant_changes - Added
propose_search_console_changes - Added
send_feedback
1 tool update
v0.23.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": "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" - } -]New value: +[ + { + "description": "Block searches containing these words in one campaign", + "properties": { + "campaign_id": { + "description": "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": "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": "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": "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": "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": "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": "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": "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": "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "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": "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": "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" + }, + "request_review": { + "description": "Only after Google refused a keyword as exemptible and the user says it complies: the policy and flagged text from the refusal", + "items": { + "properties": { + "policy_name": { + "minLength": 1, + "type": "string" + }, + "violating_text": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy_name", + "violating_text" + ], + "type": "object" + }, + "maxItems": 10, + "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": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "request_review_topics": { + "description": "Only after Google refused this and the user says it complies: the topics from the refusal, which asks Google to review it. PROHIBITED topics can't be", + "items": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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" + }, + { + "description": "Delete one keyword. Undo adds it back with its history", + "properties": { + "ad_group_id": { + "description": "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": "delete_keyword", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_id" + ], + "type": "object" + }, + { + "description": "Delete one ad. Permanent, with no undo: say so before they approve; to only stop it, pause it", + "properties": { + "ad_group_id": { + "description": "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": "delete_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "ad_id" + ], + "type": "object" + }, + { + "description": "Delete an ad group with its ads and keywords. Permanent, with no undo: say so before they approve; to only stop it, pause it", + "properties": { + "ad_group_id": { + "description": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_ad_group", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id" + ], + "type": "object" + }, + { + "description": "Delete a whole campaign. Permanent, with no undo: say so before they approve; to only stop it, pause it", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_campaign", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Delete negative keywords from a campaign, so those searches can show its ads again", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_ids": { + "description": "campaign_criterion.criterion_id of each negative, from run_gaql WHERE campaign_criterion.negative = TRUE", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "delete_negative_keywords", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "criterion_ids" + ], + "type": "object" + }, + { + "description": "Take sitelinks off a campaign. Google can't edit a sitelink: to change one, delete it and add_sitelinks in the same proposal", + "properties": { + "asset_ids": { + "description": "asset.id of each sitelink, from run_gaql FROM campaign_asset WHERE campaign_asset.field_type = 'SITELINK'", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 8, + "minItems": 1, + "type": "array" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_sitelinks", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "asset_ids" + ], + "type": "object" + }, + { + "description": "Block searches in one ad group, so it stops catching another group's searches", + "properties": { + "ad_group_id": { + "description": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "add_ad_group_negatives", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "keywords" + ], + "type": "object" + }, + { + "description": "Delete negative keywords from an ad group", + "properties": { + "ad_group_id": { + "description": "Digits only (ad_group.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "criterion_ids": { + "description": "ad_group_criterion.criterion_id of each negative, from run_gaql WHERE ad_group_criterion.negative = TRUE", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "delete_ad_group_negatives", + "type": "string" + } + }, + "required": [ + "type", + "ad_group_id", + "criterion_ids" + ], + "type": "object" + }, + { + "description": "Create a shared negative keyword list, optionally on campaigns", + "properties": { + "campaign_ids": { + "default": [], + "description": "Campaigns to use it on", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "keywords": { + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "name": { + "description": "List name; must not match an existing list", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "create_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "name", + "keywords" + ], + "type": "object" + }, + { + "description": "Add or remove keywords in a shared negative list. This changes every campaign using it, which the proposal lists", + "properties": { + "add": { + "default": [], + "items": { + "properties": { + "match_type": { + "enum": [ + "EXACT", + "PHRASE", + "BROAD" + ], + "type": "string" + }, + "text": { + "maxLength": 80, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text", + "match_type" + ], + "type": "object" + }, + "maxItems": 50, + "type": "array" + }, + "remove_criterion_ids": { + "default": [], + "description": "shared_criterion.criterion_id of each to remove", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "shared_set_id": { + "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "edit_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "shared_set_id" + ], + "type": "object" + }, + { + "description": "Put a shared negative list on campaigns, or take it off", + "properties": { + "add_campaign_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "remove_campaign_ids": { + "default": [], + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "shared_set_id": { + "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "apply_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "shared_set_id" + ], + "type": "object" + }, + { + "description": "Delete a shared negative list from every campaign. It has no undo: say so before they approve", + "properties": { + "shared_set_id": { + "description": "Shared negative list id (shared_set.id from run_gaql WHERE shared_set.type = 'NEGATIVE_KEYWORDS')", + "pattern": "^\\d+$", + "type": "string" + }, + "type": { + "const": "delete_negative_list", + "type": "string" + } + }, + "required": [ + "type", + "shared_set_id" + ], + "type": "object" + }, + { + "description": "Edit a responsive search ad's words or link in place, instead of adding a new ad. Give only what changes", + "properties": { + "ad_id": { + "description": "Ad id, digits only (ad_group_ad.ad.id from run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "descriptions": { + "description": "The full new list, replacing the old one", + "items": { + "maxLength": 90, + "minLength": 1, + "type": "string" + }, + "maxItems": 4, + "minItems": 2, + "type": "array" + }, + "final_url": { + "maxLength": 2048, + "pattern": "^https?:\\/\\/", + "type": "string" + }, + "headlines": { + "description": "The full new list, replacing the old one", + "items": { + "maxLength": 30, + "minLength": 1, + "type": "string" + }, + "maxItems": 15, + "minItems": 3, + "type": "array" + }, + "path1": { + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "path2": { + "maxLength": 15, + "minLength": 1, + "type": "string" + }, + "request_review_topics": { + "description": "Only after Google refused this and the user says it complies: the topics from the refusal, which asks Google to review it. PROHIBITED topics can't be", + "items": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "edit_responsive_search_ad", + "type": "string" + } + }, + "required": [ + "type", + "ad_id" + ], + "type": "object" + }, + { + "description": "Choose which days and hours a campaign runs, in the account's time zone, with optional bid changes. Hours left out don't run", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "schedule": { + "description": "The whole new schedule, replacing the old one; empty means all day, every day", + "items": { + "properties": { + "bid_percent": { + "description": "Bid change in these hours, e.g. -20", + "maximum": 900, + "minimum": -90, + "type": "number" + }, + "day": { + "enum": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ], + "type": "string" + }, + "end_hour": { + "maximum": 24, + "minimum": 1, + "type": "integer" + }, + "start_hour": { + "maximum": 23, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "day", + "start_hour", + "end_hour" + ], + "type": "object" + }, + "maxItems": 42, + "type": "array" + }, + "type": { + "const": "set_ad_schedule", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "schedule" + ], + "type": "object" + }, + { + "description": "Raise or lower a campaign's bids on one device. Smart bidding ignores everything here except -100", + "properties": { + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "device": { + "enum": [ + "DESKTOP", + "MOBILE", + "TABLET" + ], + "type": "string" + }, + "percent": { + "description": "Bid change in percent, e.g. -20; -100 stops showing on that device, 0 clears it", + "maximum": 900, + "minimum": -100, + "type": "number" + }, + "type": { + "const": "set_device_bid", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "device", + "percent" + ], + "type": "object" + }, + { + "description": "Add callouts, structured snippets, a business name, logos or images to a campaign", + "properties": { + "business_name": { + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "callouts": { + "default": [], + "description": "Short selling points, at most 25 characters each", + "items": { + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "type": "array" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "images": { + "default": [], + "description": "Images: landscape 1.91:1 or square 1:1", + "items": { + "description": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 0, + "type": "array" + }, + "logos": { + "default": [], + "description": "Square logos, 1:1", + "items": { + "description": "https URL of a PNG, JPEG or GIF (up to 5120 KB), or an image asset.id", + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 0, + "type": "array" + }, + "snippets": { + "default": [], + "items": { + "properties": { + "header": { + "enum": [ + "Amenities", + "Brands", + "Courses", + "Degree programs", + "Destinations", + "Featured hotels", + "Insurance coverage", + "Models", + "Neighborhoods", + "Service catalog", + "Shows", + "Styles", + "Types" + ], + "type": "string" + }, + "values": { + "items": { + "maxLength": 25, + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 3, + "type": "array" + } + }, + "required": [ + "header", + "values" + ], + "type": "object" + }, + "maxItems": 4, + "type": "array" + }, + "type": { + "const": "add_campaign_assets", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Take assets off a campaign. No undo: add them again with add_campaign_assets", + "properties": { + "asset_ids": { + "description": "asset.id of each, from run_gaql FROM campaign_asset", + "items": { + "pattern": "^\\d+$", + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "field_type": { + "enum": [ + "CALLOUT", + "STRUCTURED_SNIPPET", + "BUSINESS_NAME", + "BUSINESS_LOGO", + "LOGO", + "AD_IMAGE" + ], + "type": "string" + }, + "type": { + "const": "delete_campaign_assets", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "field_type", + "asset_ids" + ], + "type": "object" + }, + { + "description": "Turn AI Max and automatically created text on or off for a campaign. Give only what changes", + "properties": { + "ai_max": { + "description": "AI Max for Search", + "type": "boolean" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "text_automation": { + "description": "Let Google write its own headlines and descriptions", + "type": "boolean" + }, + "type": { + "const": "set_ai_max", + "type": "string" + }, + "url_expansion": { + "description": "Let Google send people to other pages on the site", + "type": "boolean" + } + }, + "required": [ + "type", + "campaign_id" + ], + "type": "object" + }, + { + "description": "Change a conversion action's value, counting window or attribution. Give only what changes", + "properties": { + "attribution": { + "enum": [ + "LAST_CLICK", + "DATA_DRIVEN" + ], + "type": "string" + }, + "click_window_days": { + "description": "Days after a click a conversion still counts", + "maximum": 90, + "minimum": 1, + "type": "integer" + }, + "conversion_action_id": { + "description": "conversion_action.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + }, + "default_value": { + "maximum": 1000000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "set_conversion_settings", + "type": "string" + } + }, + "required": [ + "type", + "conversion_action_id" + ], + "type": "object" + }, + { + "description": "Create a list of the site's visitors, from the Google tag on the site. No customer data is uploaded", + "properties": { + "membership_days": { + "default": 30, + "description": "How long a visitor stays on the list", + "maximum": 540, + "minimum": 1, + "type": "integer" + }, + "name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "create_remarketing_list", + "type": "string" + }, + "url_contains": { + "description": "Visitors to pages whose URL contains this join the list, e.g. example.com", + "maxLength": 512, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "name", + "url_contains" + ], + "type": "object" + }, + { + "description": "Add a remarketing list to a campaign in observation, or take it off: ads still show to everyone, and you can see and bid on the list", + "properties": { + "bid_percent": { + "description": "Bid change for people on the list, e.g. 20", + "maximum": 900, + "minimum": -90, + "type": "number" + }, + "campaign_id": { + "description": "Digits only (campaign_id from account_overview or run_gaql)", + "pattern": "^\\d+$", + "type": "string" + }, + "on": { + "type": "boolean" + }, + "type": { + "const": "set_campaign_audience", + "type": "string" + }, + "user_list_id": { + "description": "user_list.id from run_gaql", + "pattern": "^\\d+$", + "type": "string" + } + }, + "required": [ + "type", + "campaign_id", + "user_list_id", + "on" + ], + "type": "object" + }, + { + "description": "Apply or dismiss one of Google's recommendations. Applying has no undo and Google picks the details: say so before they approve", + "properties": { + "action": { + "enum": [ + "APPLY", + "DISMISS" + ], + "type": "string" + }, + "recommendation_id": { + "description": "The end of recommendation.resource_name from run_gaql", + "pattern": "^[\\w=-]+$", + "type": "string" + }, + "type": { + "const": "act_on_recommendation", + "type": "string" + } + }, + "required": [ + "type", + "recommendation_id", + "action" + ], + "type": "object" + } +]
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 33 tools
Tools are well-scoped by service and action (search_console_*, analytics_*, merchant_* are distinct resource families), so most are easy to tell apart. The four propose_* tools (propose_changes, propose_analytics_changes, propose_merchant_changes, propose_search_console_changes) overlap conceptually and rely on descriptions to separate them, and the multiple Search Console analysis tools (summary/performance/trend/opportunities) require reading descriptions to pick correctly.
Predominantly consistent snake_case with service-prefixed grouping (search_console_, analytics_, merchant_) and clear verb_noun action names (propose_*, apply_changes, undo_changes). Minor inconsistency: the generic Ads tool is 'propose_changes' while the others are 'propose_<service>_changes', and a few bare names (billing, disconnect) break the verb_noun pattern.
33 tools is heavy and pushes well past the typically-scoped range, requiring the agent to discriminate among many options. It is partly justified because the server spans four distinct Google services (Ads, Search Console, GA4, Merchant Center), but the count still feels borderline for smooth selection.
Coverage is broad across all four services: Ads full lifecycle (create/pause/edit/delete, bidding, negatives, conversions, audiences), Search Console read + sitemap/site changes, GA4 setup/reporting, and Merchant Center products/reports/ad spend, plus a generic GAQL escape hatch. Few obvious gaps, though some admin/edge operations depend on run_gaql and cross-service joins are limited to paid_organic_overlap.
Maintenance
Related MCP Connectors
- AdCopilotDeprecatedcloud.adcopilot
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.-