# How to connect Google Ads to OpenClaw (no API keys)

> Connect Google Ads to OpenClaw without a Google Ads API developer token. Hosted OAuth, 10 tools your agent can call from chat, and the GAQL errors that break most setups.

Web version: https://claw-link.dev/openclaw/google-ads

The usual route to Google Ads access for OpenClaw is an MCP server you configure and keep running, plus your own OAuth app or API keys. ClawLink gives OpenClaw a more practical Google Ads setup: install one ClawHub skill, connect Google Ads in the browser, and OpenClaw can call real Google Ads actions from any chat surface with no auth, token refresh, or tool wiring to build yourself.

**Start here:** install the ClawLink plugin (`openclaw plugins install clawhub:clawlink-plugin`), pair it in the browser, then connect the app in the ClawLink dashboard. The interactive install prompt is on the web version of this page: https://claw-link.dev/openclaw/google-ads

## Setup

It takes three steps to connect OpenClaw to Google Ads.

1. **Install ClawLink** — add the plugin to OpenClaw once.
2. **Connect Google Ads** — one-click OAuth in the ClawLink dashboard.
3. **Use it from chat** — ask OpenClaw in plain English.

**Alternative for any agent (no plugin needed):** if the OpenClaw plugin route isn't available or doesn't work, any AI agent with shell access can use the ClawLink CLI instead:

```bash
npx -y @useclawlink/cli login          # sign in via browser — no API key to paste
npx -y @useclawlink/cli connect google-ads  # connect Google Ads (browser OAuth)
npx -y @useclawlink/cli actions google-ads  # list available actions
npx -y @useclawlink/cli run google-ads <action> --input '<json>'  # execute (add --confirm for writes)
```

### Install by command

The setup prompt above does all of this in one paste. By hand, it is one install command plus a browser approval:

```bash
openclaw plugins install clawhub:clawlink-plugin
```

Then ask OpenClaw to set up ClawLink. It starts browser pairing and prints an approval link — open it, approve the device, return to the chat, and say `done`. Finally, connect Google Ads in the [ClawLink dashboard](https://claw-link.dev/dashboard) — a one-click OAuth approval, no API keys.

Verify the connection by asking OpenClaw:

> Use Google Ads to run this GAQL query: SELECT campaign.name, ad_group.name, ad_group_criterion.keyword.text, metrics.cost_micros, metrics.conversions FROM keyword_view WHERE segments.date DURING LAST_30_DAYS AND metrics.conversions = 0 ORDER BY metrics.cost_micros DESC LIMIT 20. Divide cost_micros by 1,000,000 to show real currency, and tell me which keywords to cut.

### Using a different agent?

The OpenClaw plugin is one client of ClawLink's MCP server. Claude Code, Cursor, Codex, or any agent that can run a shell command pairs with the same ClawLink account through the CLI:

```bash
npx -y @useclawlink/cli login
```

`login` opens the same browser approval and stores a credential locally. Once Google Ads is connected in the dashboard, that agent calls the same 10 Google Ads tools over MCP. Full setup for MCP clients and shell agents: [connect apps to any AI agent](https://claw-link.dev/learn/connect-apps-to-any-ai-agent).

## Google Ads MCP for OpenClaw

Looking for a Google Ads MCP server for OpenClaw? ClawLink connects Google Ads to OpenClaw and exposes 10 Google Ads tools your agent can call over [MCP](https://claw-link.dev/learn/what-is-an-mcp-server), with [hosted auth](https://claw-link.dev/learn/oauth-for-ai-agents) and nothing to run or maintain yourself. Using Hermes instead? The [Hermes Google Ads integration](https://claw-link.dev/hermes/google-ads) works the same way.

Every other route to Google Ads in OpenClaw starts with a Google Ads API developer token, and the token you are issued at signup is Test Account Access level, which can only query test accounts. Reaching your real campaign data means climbing Google's access ladder: Explorer allows production but caps it at 2,880 operations a day, Basic raises that to 15,000 after a review of about five business days, and Standard removes the cap after roughly ten. ClawLink removes the prerequisite entirely. You connect Google Ads in the browser on Google's own consent screen, and OpenClaw calls the tools from the next message, with no developer token, no OAuth client secret, and no refresh token stored on your machine — and the hosted connection runs on a Basic-level token, so the 2,880-a-day Explorer ceiling is something the do-it-yourself route lives with and this one does not.

## What the OpenClaw Google Ads integration can do

10 Google Ads tools are ready for OpenClaw once the account is connected.

### All 10 Google Ads tools for OpenClaw

| Tool | What it does |
|---|---|
| **Add or remove to customer list** `googleads_add_or_remove_to_customer_list` | Add or remove contacts from a Google Ads customer list |
| **Create customer list** `googleads_create_customer_list` | Create a customer list in Google Ads |
| **Get campaign by ID** `googleads_get_campaign_by_id` | Get a Google Ads campaign by ID |
| **Get campaign by name** `googleads_get_campaign_by_name` | Get a Google Ads campaign by name |
| **Get customer lists** `googleads_get_customer_lists` | Get customer lists in Google Ads |
| **List accessible customers** `googleads_list_accessible_customers` | List Google Ads customers accessible to the account |
| **Mutate ad group criteria** `googleads_mutate_ad_group_criteria` | Create, update, or remove keywords and other ad group criteria |
| **Mutate ad groups** `googleads_mutate_ad_groups` | Create, update, or remove Google Ads ad groups |
| **Mutate campaigns** `googleads_mutate_campaigns` | Create, update, or remove Google Ads campaigns |
| **Search stream gaql** `googleads_search_stream_gaql` | Run a GAQL query stream in Google Ads |

## Example prompts

**Audit wasted spend**

> Use Google Ads to run this GAQL query: SELECT campaign.name, ad_group.name, ad_group_criterion.keyword.text, metrics.cost_micros, metrics.conversions FROM keyword_view WHERE segments.date DURING LAST_30_DAYS AND metrics.conversions = 0 ORDER BY metrics.cost_micros DESC LIMIT 20. Divide cost_micros by 1,000,000 to show real currency, and tell me which keywords to cut.

**Mine search terms**

> Use Google Ads to run: SELECT search_term_view.search_term, metrics.clicks, metrics.cost_micros, metrics.conversions FROM search_term_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.cost_micros DESC LIMIT 50. Group the terms into themes and flag the ones that look irrelevant to my business.

**Pause a campaign**

> Use Google Ads to pause the campaign named "Brand - Exact". Look it up with googleads_get_campaign_by_name first so you have the real resource name, then send a mutate whose update contains only status and resource_name. Do not include an update_mask.

**Compare accounts**

> Use Google Ads to list every account I can access with googleads_list_accessible_customers, then for each one run SELECT customer.descriptive_name, metrics.cost_micros, metrics.conversions FROM customer WHERE segments.date DURING LAST_30_DAYS and give me one table sorted by spend.

## Google Ads tool arguments that trip agents up

These come from Google Ads calls that actually failed in production. ClawLink now blocks each one before the request reaches Google and returns the correction below, so the agent gets a fixable message instead of a raw API rejection, but knowing them saves a retry loop.

- **GAQL id fields are INT64, so quoting them fails.** Write `campaign.id = 23996552320`, not `campaign.id = '23996552320'`. Models quote ids by habit because most APIs take strings, and Google Ads rejects the query outright.
- **`*_performance_report` resources do not exist in GAQL.** `FROM campaign_performance_report` is legacy AdWords, and it is the single most common failure we see, because models trained on older tutorials still write it. The current form selects `metrics.*` from a real resource: `SELECT metrics.impressions, metrics.clicks, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_30_DAYS`.
- **`FROM device` is invalid; device is a segment, not a resource.** Select `segments.device` from a real resource instead.
- **GAQL has no subqueries.** `WHERE campaign.id IN (SELECT ...)` is rejected. Filter directly on the attributed resource in one query, or run two queries and join the results yourself.
- **`ad_group_criterion` exposes no metrics.** Selecting `metrics.*` alongside it fails. Keyword performance comes from `FROM keyword_view`, which supports `ad_group_criterion.keyword.text`, `ad_group_criterion.keyword.match_type`, and `metrics.*` together.
- **`metrics.conversion_rate` is not a Google Ads field.** Use `metrics.conversions_from_interactions_rate`, or compute the rate from `metrics.conversions` and `metrics.interactions`.
- **The mutate tools have no `update_mask` parameter and silently drop unrecognized fields.** The mask is derived from the fields inside `update`, so a passed mask is discarded and any field outside the supported set vanishes before Google sees it, surfacing as `FIELD_MASK_MISSING` or a partial write. Campaign mutates accept `name`, `status`, `start_date`, `end_date`, `daily_budget`, `campaign_budget`, `bidding_strategy_type`, `manual_cpc`, `network_settings`, `targeted_locations`, and a handful more. Ad group creates accept only `name`, `type`, `status`, and `campaign`; ad group updates accept only `name`, `status`, and `resource_name`.
- **Bidding-strategy sub-fields cannot be set through these tools at all.** `target_spend.cpc_bid_ceiling_micros`, `target_cpa.target_cpa_micros`, and `target_roas.target_roas` are not writable here. If that is the request, the answer is that it is unsupported, not that the call should be retried.
- **`daily_budget` on `googleads_mutate_campaigns` is the only budget lever.** There is no separate budget tool, so an agent reaching for `googleads_mutate_campaign_budgets` or `googleads_create_campaign_budget` is calling a name that does not exist.
- **Costs come back in micros.** `metrics.cost_micros` is millionths of the account currency, so 12,340,000 is 12.34. Ask for the division explicitly or the agent will report spend a million times too high.

## ClawLink vs. building it yourself

The alternative to ClawLink is usually manual OAuth app setup plus your own token handling, permission troubleshooting, and tool plumbing for OpenClaw. That is fine if you want to build and maintain the integration yourself. Most teams just want Google Ads working from chat.

| | Manual | ClawLink |
|---|---|---|
| **Connection flow** | Register a Google Ads app, configure redirect URLs, manage consent details, and reconnect users when auth settings drift. | Users connect Google Ads through the hosted browser flow and ClawLink keeps the token lifecycle out of your app code. |
| **Ongoing maintenance** | You own refresh logic, permission debugging, environment config, and every provider-specific edge case for Google Ads. | ClawLink handles the repetitive integration plumbing so your team can focus on the workflow instead of the infrastructure. |
| **Agent usability** | You still need to expose the right Google Ads actions to the runtime in a format your agent can reliably use. | 10 tools for Google Ads are already exposed through ClawLink, so the agent can read and act from chat immediately. |

## ClawLink vs. Composio

Composio also exposes Google Ads to AI agents. It is developer infrastructure: Python and TypeScript SDKs, an MCP server, and a catalog past 1,000 apps, aimed at teams shipping agent products. ClawLink is built for OpenClaw users instead. You install the plugin once, connect Google Ads in the browser, and the 10 tools above work from chat. There is no SDK, no config file, and no API key handling. Choosing between them? Read the full [Composio alternatives](https://claw-link.dev/hub/composio-alternatives) comparison.

### OpenClaw installed the Google Ads skill but can't call the tools
The ClawHub skill teaches OpenClaw about Google Ads, but the calls run through the ClawLink plugin and your connected account. Make sure Google Ads is connected in the dashboard, then start a fresh chat so OpenClaw reloads the tool catalog. If OpenClaw runs as a persistent gateway, restart it so the new tools register.

### Connection succeeds but no tools appear
Reconnect Google Ads from the dashboard, then start a fresh chat if the runtime still has the old tool catalog loaded.

### "Tool schema not loaded yet" error when calling Google Ads tools
Google Ads tool schemas load on demand the first time a tool runs and are cached after that, so this error usually clears on its own: wait a few seconds and retry the same request. If every Google Ads call keeps failing with it in a fresh chat, reconnect from the dashboard, and contact support if it still persists — that pattern points to a configuration problem on our side, not something you can fix by reconnecting again.

### Google Ads returns 403 or "permission denied" on one action while others work
Two usual causes. The connected account may not have access to the specific workspace, inbox, store, or project in the request — check that first. If access looks right, the agent may have sent a placeholder value (like "YOUR_ID" or an example id from documentation) instead of a real one: ask it to run a list or search tool first, then retry the action with a real id from those results. Most failures at this stage are one of these two, not ClawLink bugs.

### arguments.query is invalid GAQL. `*_performance_report` resources are from the legacy AdWords API and do not exist in GAQL.
The agent wrote `FROM campaign_performance_report` (or `keyword_performance_report`, or `ad_performance_report`). Those are AdWords report names that Google retired with the old API, and they appear in a large share of the tutorials models were trained on, so this is the most frequent Google Ads failure on ClawLink. GAQL has no report resources: you select metrics from the entity itself. Replace the resource with `campaign`, `ad_group`, `ad_group_ad`, or `keyword_view` and keep the `metrics.*` fields, for example `SELECT campaign.name, metrics.impressions, metrics.clicks, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_30_DAYS`. ClawLink catches this before the call leaves, so the fix is one corrected query rather than a debugging session.

Ask the agent to diagnose it:

```text
That query used a legacy AdWords report resource. Rewrite it as GAQL selecting metrics.* from a real resource (campaign, ad_group, or keyword_view) with a segments.date filter, show me the query text before you run it, then run it.
```

### FIELD_MASK_MISSING
Google rejects the mutate because, by the time the request arrived, the update object was empty. The cause is upstream: the mutate tools accept a fixed set of fields and quietly discard everything else, so an agent that sent `budget_amount_micros` or a nested bidding-strategy object had those keys stripped, leaving nothing to build a field mask from. Passing `update_mask` yourself does not help either, because the mask is derived and a supplied one is discarded. Retry with only supported fields: campaign updates take `name`, `status`, `start_date`, `end_date`, `daily_budget`, `campaign_budget`, `bidding_strategy_type`, and related settings, while ad group updates take just `name`, `status`, and `resource_name`. If the request was to change a target CPA or a bid ceiling, that is not writable through these tools and no retry will land it.

Ask the agent to diagnose it:

```text
Show me the exact operations array you sent. Remove any update_mask, drop every field outside the tool's supported set, and tell me plainly if what I asked for (bid ceilings, target CPA, target ROAS) is unsupported rather than retrying.
```

### PROHIBITED_SEGMENT_IN_SELECT_OR_WHERE_CLAUSE
The query mixed `FROM conversion_action` with `segments.conversion_action` or `segments.conversion_action_name`. Those segments are incompatible with the `conversion_action` resource, so Google rejects the combination. There are two valid shapes and you have to pick one. Either keep `FROM conversion_action` and select the attributes `conversion_action.id` and `conversion_action.name` instead of the segments, or keep the segment and move the resource to `FROM customer` or `FROM campaign`, remembering that only conversion metrics such as `metrics.conversions`, `metrics.all_conversions`, and `metrics.conversions_value` may be selected next to a conversion segment.

Ask the agent to diagnose it:

```text
Rewrite that as two options: one using FROM conversion_action with conversion_action.name as an attribute, and one using FROM campaign with segments.conversion_action_name and only conversion metrics. Show me both, then run the one that answers my question.
```

### Tool 'googleads_create_campaign_budget' not found
The tool does not exist, and neither do `googleads_mutate_campaign_budgets`, `googleads_search`, `googleads_mutate_ad_group_ads`, or `googleads_mutate_campaign_criteria`. Agents invent these names because the Google Ads API itself has separate budget and criterion services, so the guess is reasonable and wrong. Budgets are changed through the `daily_budget` field on `googleads_mutate_campaigns`, and reporting runs through `googleads_search_stream_gaql`, not `googleads_search`. Have the agent list the real catalog before it guesses again.

Ask the agent to diagnose it:

```text
Run clawlink_list_tools for google-ads and show me the exact tool names available. Then redo my request using only names from that list.
```

### OAuth finished in the browser but the account is still missing
Try reconnecting Google Ads and complete the consent flow in the same browser session. Partial OAuth approvals or switching accounts mid-flow can leave the connection incomplete.

### Is there a OpenClaw Google Ads integration?
Yes. ClawLink is the fastest way to connect OpenClaw to Google Ads: link your Google Ads account once in the browser and OpenClaw can call the Google Ads API through 10 ready-made tools — no custom code or token handling.

### How do I add Google Ads to OpenClaw with ClawLink?
Paste the setup prompt from this page into OpenClaw. It installs the ClawLink Google Ads skill from ClawHub, then you click Connect in the dashboard to authorize Google Ads. OpenClaw calls the tools from the next message — no config files or API keys to manage.

### How long does it take to connect Google Ads to OpenClaw?
About two minutes. Sign in, click Connect next to Google Ads in the dashboard, authenticate, and OpenClaw can use it from the next chat message.

### Why use ClawLink instead of wiring Google Ads up myself?
The alternative to ClawLink is usually manual OAuth app setup plus your own token handling, permission troubleshooting, and tool plumbing for OpenClaw. That is fine if you want to build and maintain the integration yourself. Most teams just want Google Ads working from chat.

### Do I need a Google Ads API developer token to connect Google Ads to OpenClaw?
Not through ClawLink. This is the step every DIY guide requires and most gloss over: the developer token you receive when you sign up for the Google Ads API is issued at Test Account Access level, which queries test accounts only, so it cannot read the campaigns you actually run. Google's ladder from there has three more rungs. Explorer reaches production but allows 2,880 operations a day against it. Basic lifts that to 15,000 a day and takes about five business days to review. Standard removes the cap and takes around ten. The limits are measured over a sliding 24-hour window rather than resetting at midnight, which is why a heavy afternoon can still be throttling you the next morning. ClawLink connects through hosted OAuth instead, so you approve access on Google's consent screen and never handle a developer token, client secret, or refresh token — and because the hosted connection runs on a Basic-level token, you are not living with the Explorer ceiling either.

### Can OpenClaw change my Google Ads budgets and bids?
Budgets yes, bids mostly no. `googleads_mutate_campaigns` accepts a `daily_budget` field, and that is the only budget lever in the toolkit; there is no separate budget tool, so an agent calling `googleads_create_campaign_budget` is using a name that does not exist. Bidding is more limited: you can set `bidding_strategy_type` and `manual_cpc`, but the sub-fields inside a portfolio strategy, such as `target_cpa.target_cpa_micros`, `target_roas.target_roas`, and `target_spend.cpc_bid_ceiling_micros`, are not writable through these tools. Ask for one of those and the correct answer is that it is unsupported.

### Why do my agent's Google Ads reporting queries keep failing?
Almost always the GAQL, not the connection. Six patterns cover most of it: legacy AdWords report names like `FROM campaign_performance_report`, using `FROM device` when device is a segment, subqueries with `IN (SELECT ...)`, quoting numeric ids such as `campaign.id = '123'`, selecting `metrics.*` from `ad_group_criterion` instead of `keyword_view`, and asking for `metrics.conversion_rate`, which is not a field. ClawLink checks for all six before the query reaches Google and returns the corrected form, so the agent can fix the query on the next turn rather than retrying the same broken one.

### Does the agent need my Google Ads customer ID?
Usually not. `customer_id` is optional on `googleads_search_stream_gaql`, and in production most successful queries omit it, so a missing customer ID is not the reason a call failed. When you manage several accounts, have the agent run `googleads_list_accessible_customers` first and name the account you mean, since that is what disambiguates the request.

### Does this work with a manager (MCC) account?
It works, but be explicit about which account you mean. On the do-it-yourself route, requests made through a manager account carry a `login-customer-id` header naming the manager, and a missing or wrong value there is the classic 403 that Google's own documentation leads with. On a hosted connection there is no header for you to set, so the equivalent step is naming the account: have the agent run `googleads_list_accessible_customers`, confirm which customer it is about to act on, and pass that as `customer_id` rather than leaving it implicit. If a call fails against one account while succeeding against another under the same manager, that is the mismatch to look at first, not the query.

### OpenClaw installed the Google Ads skill but can't call the tools
The ClawHub skill teaches OpenClaw about Google Ads, but the calls run through the ClawLink plugin and your connected account. Make sure Google Ads is connected in the dashboard, then start a fresh chat so OpenClaw reloads the tool catalog. If OpenClaw runs as a persistent gateway, restart it so the new tools register.

## Related

- [Google Super](https://claw-link.dev/openclaw/google-super) — Unified access to multiple Google services in one integration
- [Google Drive](https://claw-link.dev/openclaw/google-drive) — Upload, search, and manage files
- [Google Analytics tools](https://claw-link.dev/openclaw/google-analytics) — Connect Google Analytics properties through hosted Google OAuth
