> ## Documentation Index
> Fetch the complete documentation index at: https://lava.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Ads

> Google Ads API access for managing and reporting on Google search, display, and video advertising on behalf of a connected advertiser, query campaigns, ad groups, keywords, and performance via GAQL (googleAds:search), and create or update campaigns, budgets, and ads via :mutate.

Google Ads API access for managing and reporting on Google search, display, and video advertising on behalf of a connected advertiser, query campaigns, ad groups, keywords, and performance via GAQL (googleAds:search), and create or update campaigns, budgets, and ads via :mutate. Use when an agent needs to launch, optimize, or report on Google Ads campaigns. Routes through Pipedream Connect, the user sees one Google consent screen on connect that says "Pipedream wants access" (Pipedream owns the verified OAuth client and the Google Ads developer token), so Lava needs no developer token or API approval of its own. Ad spend is billed by Google directly to the connected account.

4 example endpoints available through Lava's AI Gateway. See the [Google Ads API docs](https://developers.google.com/google-ads/api/rest/overview) for full documentation.

<Warning>This provider requires your own credentials — connect your API key or OAuth account before use.</Warning>

<Info>This is a **catch-all provider** — any valid URL under `https://googleads.googleapis.com` is supported. Google Ads REST API endpoints. Construct URLs as [https://googleads.googleapis.com/v\&#123;N\&#125;/\&#123;path\&#125](https://googleads.googleapis.com/v\&#123;N\&#125;/\&#123;path\&#125);, where v\{N} is the current Google Ads API version (e.g. v21). Every call is POST: read with customers/\{customerId}/googleAds:search (a GAQL query in the body, e.g. \{ "query": "SELECT campaign.id, campaign.name, metrics.clicks FROM campaign" }) or :searchStream, and write with the :mutate endpoints (campaigns:mutate, adGroups:mutate, adGroupAds:mutate, campaignBudgets:mutate, etc.). customerId is the 10-digit Google Ads account id, in the path as customers/\{customerId}/. A real customer id you pass is always used as-is and never redirected (dashes are fine, customers/123-456-7890/... is normalized to digits automatically). If you do not know it, pass the literal placeholder customers/DEFAULT/ (use a digit-free word like DEFAULT, a token containing any digit is treated as a real id, not a placeholder): when this connection captured a customer id at connect time, the gateway fills in the connected account automatically, for both the slash form (customers/DEFAULT/googleAds:search) and the colon form (customers/DEFAULT:mutate). If no id was captured (a manager/MCC login, a connection made before this feature, or a transient throttle at connect), the placeholder is NOT substituted and Google returns INVALID\_CUSTOMER\_ID, in that case retry with the real 10-digit id (find it in the top-right of the Google Ads UI). The substitution applies to the URL path ONLY: any customers/\{id}/... resource\_names inside the request body must use the real id. The listAccessibleCustomers GET endpoint is not available through this provider (it is POST-only). Do NOT send an Authorization header or a developer-token header, Pipedream injects both its developer token and the connected user's Google credential automatically. This provider acts on the single Google Ads account you connect; manager-account (MCC) cross-account access is not supported here. GAQL is queried, not REST-resourced: select fields from a resource with optional WHERE/ORDER BY/LIMIT and date ranges (segments.date DURING LAST\_30\_DAYS). Mutations take an operations array (create/update/remove); updates also need update\_mask. See [https://developers.google.com/google-ads/api/rest/overview](https://developers.google.com/google-ads/api/rest/overview) for the full reference. The endpoints below are curated examples.</Info>

## Endpoints

### Run a GAQL query against the connected account (googleAds:search). The workhorse read, list campaigns, ad groups, keywords, or pull metrics. Put the query in the body. Use this as a cheap auth probe after connect (e.g. select customer.id) to confirm the grant is healthy. Paginate with page\_token from the response; cap rows with LIMIT or page\_size.

**POST** `https://googleads.googleapis.com/v21/customers/1234567890/googleAds:search` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://googleads.googleapis.com/v21/customers/1234567890/googleAds:search', {
      body: {
    "query": "SELECT campaign.id, campaign.name, campaign.status, metrics.impressions, metrics.clicks, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.cost_micros DESC"
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fgoogleads.googleapis.com%2Fv21%2Fcustomers%2F1234567890%2FgoogleAds%3Asearch" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"SELECT campaign.id, campaign.name, campaign.status, metrics.impressions, metrics.clicks, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.cost_micros DESC"}'
    ```
  </Tab>
</Tabs>

### List keywords and their performance with a GAQL query over the keyword\_view resource. Filter by ad group, match type, or date range, and order by metrics to find top or wasted spend.

**POST** `https://googleads.googleapis.com/v21/customers/1234567890/googleAds:search` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://googleads.googleapis.com/v21/customers/1234567890/googleAds:search', {
      body: {
    "query": "SELECT ad_group_criterion.keyword.text, ad_group_criterion.keyword.match_type, metrics.clicks, metrics.cost_micros, metrics.conversions FROM keyword_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.cost_micros DESC LIMIT 50"
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fgoogleads.googleapis.com%2Fv21%2Fcustomers%2F1234567890%2FgoogleAds%3Asearch" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"SELECT ad_group_criterion.keyword.text, ad_group_criterion.keyword.match_type, metrics.clicks, metrics.cost_micros, metrics.conversions FROM keyword_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.cost_micros DESC LIMIT 50"}'
    ```
  </Tab>
</Tabs>

### Create or update a campaign budget. A campaign needs a budget before it can run, so create the budget first and reference its resource\_name from campaigns:mutate. amount\_micros is the daily amount in micros (1,000,000 micros = 1 unit of account currency).

**POST** `https://googleads.googleapis.com/v21/customers/1234567890/campaignBudgets:mutate` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://googleads.googleapis.com/v21/customers/1234567890/campaignBudgets:mutate', {
      body: {
    "operations": [
      {
        "create": {
          "name": "Lava, Daily budget",
          "amount_micros": 50000000,
          "delivery_method": "STANDARD"
        }
      }
    ]
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fgoogleads.googleapis.com%2Fv21%2Fcustomers%2F1234567890%2FcampaignBudgets%3Amutate" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"operations":[{"create":{"name":"Lava, Daily budget","amount_micros":50000000,"delivery_method":"STANDARD"}}]}'
    ```
  </Tab>
</Tabs>

### Create or update campaigns. Each operation is a create, update, or remove. For create, set name, an advertising\_channel\_type (e.g. SEARCH), a status (PAUSED is safest until reviewed), and campaign\_budget (a budget resource\_name from campaignBudgets:mutate). For update, set the campaign resource\_name and an update\_mask listing the fields you're changing.

**POST** `https://googleads.googleapis.com/v21/customers/1234567890/campaigns:mutate` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://googleads.googleapis.com/v21/customers/1234567890/campaigns:mutate', {
      body: {
    "operations": [
      {
        "create": {
          "name": "Lava, Search, Brand",
          "advertising_channel_type": "SEARCH",
          "status": "PAUSED",
          "campaign_budget": "customers/1234567890/campaignBudgets/9876543210"
        }
      }
    ]
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fgoogleads.googleapis.com%2Fv21%2Fcustomers%2F1234567890%2Fcampaigns%3Amutate" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"operations":[{"create":{"name":"Lava, Search, Brand","advertising_channel_type":"SEARCH","status":"PAUSED","campaign_budget":"customers/1234567890/campaignBudgets/9876543210"}}]}'
    ```
  </Tab>
</Tabs>

## Next Steps

<CardGroup cols={2}>
  <Card title="All Providers" icon="grid" href="/gateway/supported-providers">
    Browse all supported AI providers
  </Card>

  <Card title="Forward Proxy" icon="route" href="/gateway/forward-proxy">
    Learn how to construct proxy URLs and authenticate requests
  </Card>
</CardGroup>
