---
title: "Add keywords to a Google Ads ad group"
method: POST
path: "/api/v1/tools/google_add_keywords/execute"
tags: ["Google Ads"]
---

# Add keywords to a Google Ads ad group

`POST /api/v1/tools/google_add_keywords/execute`

## Request

- Base URL: `https://adako.ai`
- URL: `https://adako.ai/api/v1/tools/google_add_keywords/execute`
- Auth: HTTP bearer

Adds keywords to one existing ad group, with an optional max CPC per keyword. Keywords that already exist in that ad group with the same match type are skipped rather than duplicated, and the result says which ones were skipped.
Use when: the user has agreed on specific keywords, usually after google_research_keywords or google_analyze_search_terms.
Do not use when: you would be guessing the terms, or when the campaign only accepts broad match — some newer campaign types reject exact and phrase keywords outright, and Google will refuse the whole batch with a broad-match-only error. If that happens, tell the user rather than retrying with different match types.
Write keyword text plainly: no quotation marks for phrase and no square brackets for exact — the match type is a separate field. Bids are decimals in the account currency and are ignored by campaigns using automated bidding.
If you are unsure which account, campaign or period the user means, ask them — do not guess ids or dates.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `arguments` object, required
    - `customer_id` string: Google Ads customer id (10 digits, dashes optional). Omit to use the primary account; list_connected_accounts shows the valid ids.
    - `ad_group_id` string, required: Ad group id as returned by google_get_campaign_structure.
    - `keywords` object[], required: Keywords to add to this ad group.
      - `text` string, required: Keyword text without match-type punctuation (no quotes or brackets).
      - `match_type` 'EXACT' | 'PHRASE' | 'BROAD', required
      - `cpc_bid` number: Optional max CPC, decimal in the account currency.
    - `idempotency_key` string: Optional caller-supplied key; identical keys never execute twice.

## Response `200`

The tool ran. A write returns proposal_id and approve_url while the change waits for approval.

- SuccessEnvelope
  - `success` unknown, required
  - `tool` string, required
  - `data` object, required: Machine-readable result.
  - `markdown` string, required: The same result written for a person or a model.
  - `quota` Quota: Task usage for the current billing period.
    - `plan` string
    - `used` integer
    - `limit` integer
    - `period_end` string
    - `upgrade_url` string
  - `proposal_id` string: Present for writes. Nothing changes on the ad platform until it is approved.
  - `approve_url` string: Where a person approves the proposal.
  - `request_id` string, required

## Other responses

- `400`: Invalid arguments, or the ad account could not be resolved.
- `401`: Missing, invalid, revoked or expired API key.
- `402`: Monthly task quota used up, or the plan does not include this tool.
- `403`: The connected ad account lacks the access level this tool needs.
- `404`: Unknown tool name.
- `409`: Not connected, reconnect needed, confirmation required, a proposal already pending or no longer pending, an identical create that failed earlier today (proposal_failed_before), a create that duplicates an approved one (duplicate_create), the ad-account limit of the plan reached (account_limit), or an Idempotency-Key reused with different arguments.
- `429`: Rate limited by Adako or by the ad platform. See Retry-After.
- `500`: Unexpected error inside Adako.
- `502`: The ad platform returned an error.

---

[API](https://skmtc.dev/adako/apis/adako-rest-api.md) · [All operations](https://skmtc.dev/adako/apis/adako-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adako/apis/adako-rest-api/revisions/59ee60d48a56?raw)
