Google Ads logo

Advertising

Connect Google Ads to Excel, Sheets and AI

Campaigns, ad groups, keywords and spend as queryable tables. Join them to your own conversion data sitting in Postgres or a spreadsheet export folder.

1connection
0inbound ports
read-onlyenforced

One connection, every surface

Where your Google Ads data can go

Connect Google Ads once and the same read-only connection feeds all of these — no second setup, no second copy of the data. 1 of 11 have a step-by-step guide.

Supported

Google Ads to Excel

Microsoft Excel · Excel add-in

Pull live Google Ads results straight into a worksheet and refresh them on demand — desktop Excel, Excel Online, Microsoft 365.

How Excel works no Google Ads walkthrough written yet
Supported

Google Ads to Google Sheets

Sheets add-on

Run a saved Google Ads query from the sidebar and drop the rows into the sheet. Shared collaborators can refresh it themselves.

How Google Sheets works no Google Ads walkthrough written yet
Guide

Google Ads MCP server

Claude, Cursor and MCP clients

Give an AI assistant read-only access to Google Ads with the schema it needs to write correct SQL — no credentials in the chat.

Read the guide
Supported

Google Ads REST API

HTTP endpoint

Publish a Google Ads query as an authenticated JSON endpoint any application can call, with an OpenAPI 3.1 spec and ready-made Postman, Insomnia and Hoppscotch collections. No database port is opened.

How REST API works no Google Ads walkthrough written yet
Supported

Google Ads to Airtable

Automation platform

Sync Google Ads rows into an Airtable base on a schedule, or fetch them inside an Airtable automation script.

How Airtable works no Google Ads walkthrough written yet
Supported

Google Ads to Baserow

Automation platform

Feed a Baserow table from Google Ads over the REST endpoint — self-hosted or Baserow cloud.

How Baserow works no Google Ads walkthrough written yet
Supported

Google Ads to SeaTable

Automation platform

Keep a SeaTable base current with Google Ads data without exporting a file or exposing the database.

How SeaTable works no Google Ads walkthrough written yet
Supported

Google Ads to Smartsheet

Automation platform

Push Google Ads results into a Smartsheet grid so plans and reports read from the source system, not last week's export.

How Smartsheet works no Google Ads walkthrough written yet
Supported

Google Ads to Anvil

Anvil Works · App platform

Back an Anvil Python app with Google Ads through the REST endpoint instead of embedding database credentials in the app.

How Anvil works no Google Ads walkthrough written yet
Supported

Google Ads to Power BI

Power Query M

Paste the generated Power Query M into the Power BI Advanced Editor and the report reads live Google Ads results over HTTPS — no ODBC driver, no database port opened.

How Power BI works no Google Ads walkthrough written yet
Supported

Google Ads alerts and reports

Slack · Discord · Email · Webhook

Put a Google Ads query on a schedule and have the rows delivered to Slack, Discord, email or a signed webhook — or hold the message until a row count, threshold or percentage change crosses the line you set.

How alerts and reports work no Google Ads walkthrough written yet

How it works

5 steps, no inbound firewall change

01

Get a developer token for your Google Ads account and create a service account with domain-wide delegation.

02

Install the Network Agent and give it the service account key, the developer token, the email to impersonate and the customer id. A manager account id is optional, for reaching a sub-account.

03

Choose which of the 12 tables to sync. Campaigns, ad groups, keywords, search terms, geography, devices and the account itself are on by default.

04

Write ordinary SQL against gads.campaign, gads.search_term_view and the rest — or let Nova write it.

05

Read it from Excel, Sheets, Power BI, MCP or REST, joined to whatever holds your revenue.

Feature deep-dive

What Google Ads gives you

Spend next to revenue, in one statement

Google Ads knows what you spent. It does not know what the customer went on to pay you, and the report that matters needs both.

  • gads.campaign carries impressions, clicks, cost, conversions and conversion value by day, so it joins cleanly to anything keyed by campaign name or UTM.
  • gads.search_term_view is the actual query someone typed, which is where the money usually leaks — and it is joinable to your own conversion data rather than trapped in the Ads interface.
  • Money arrives in micros, exactly as the API reports it. A dollar is 1,000,000, so nothing has been rounded before you divide it yourself.

The 12 tables

  • Structure — customer, campaign, ad_group, ad_group_ad.
  • Search — keyword_view, search_term_view, landing_page_view.
  • Breakdowns — geographic_view, device_view, age_range_view, gender_view.
  • Audit — change_history.
  • Every row also keeps the complete API response in a raw_data JSON column, so a metric that is not a named column is still there.

Where the numbers stop, honestly

Two things about Ads data that any tool has to live with, said plainly rather than discovered later.

  • Reports run to yesterday, not today — today's figures are incomplete at Google's end and would only mislead.
  • Each incremental run re-reads the last few days as well as the new one, because conversions attribute late and a number you pulled on Monday is not the number Google will settle on by Thursday.
  • Change history is capped at 29 days by the Google Ads API itself. It is a recent-changes feed, not a permanent audit log.
  • Some geographic columns carry Google's criterion ids rather than place names, and a couple of ad-copy columns are not populated yet. What is there is accurate; what is not is empty rather than wrong.

Shared by every API connector

How every API connector works

  • Your account becomes tables — endpoints are mapped to typed SQL tables with primary keys and indexes, so you write SELECT, JOIN and GROUP BY instead of paging through JSON.
  • You choose what syncs, and how often — each table has its own interval, or none at all. Where the vendor's API supports it, only records that changed since the last run are fetched.
  • The copy is yours — it lives in an AES-256-GCM encrypted DuckDB file next to the agent, on your machine. Not in our cloud.
  • The vendor only ever hears from you — the agent calls the API directly from your own network, so your token is not needed by Query Streams to answer a query.

Good to know

  • It is a synced copy, not a live proxy — a query reads what has already been fetched, so it returns at SQL speed and never spends your API rate limit. Selected tables can additionally refresh a stale row as you read it.
  • Rate limits are respected for you — each connector paces itself well inside the vendor's published limits, so a report cannot get your account throttled for everything else that uses it.
  • Nothing is thrown away — fields the table does not name are kept in a raw_data JSON column you can still query.
  • Join it to your databases — an API table and a SQL Server table in the same statement is an ordinary query here, not an integration project.

Cross-source SQL

Join Google Ads to the rest of your data

Spend lives in Google Ads and revenue lives somewhere else entirely, which is why the two are usually reconciled in a spreadsheet once a month. One statement can ask the campaign, the account it produced and the invoice it was billed on, together. Each source runs only the part it can, streams the result back, and the join happens centrally — the sources never talk to each other and nothing is copied anywhere.

3 connections · 3 agents

Google Ads Advertising
PostgreSQL Relational engine
Stripe Payments & billing

One statement

-- spend from Google Ads, the account from your database, revenue from Stripe
SELECT   g.campaign_name, SUM(g.cost_micros) / 1000000 AS spend, SUM(i.amount_due) AS invoiced
FROM     ads.gads.campaign1       g
JOIN     pg_crm.public.customers2 c ON c.utm_campaign = g.campaign_name
JOIN     billing.stripe.invoices3 i ON i.customer = c.stripe_id
GROUP BY g.campaign_name
ORDER BY invoiced DESC;

The three parts are connection, schema and table — and the connection name is whatever you called it. Illustrative columns; your tables will be your tables. Cost arrives in micros, as the Google Ads API reports it, so the division is yours to do and nothing has been rounded on the way. Read-only applies to every piece: SELECT, WITH and EXPLAIN only, with a ceiling on how much any one source may hand over for a single query. How federated queries work

Connection details

What Google Ads needs

Authentication
A Google service account key with domain-wide delegation, a developer token, and the email it impersonates. All held on the agent
Account
A customer id, plus an optional manager account id for reaching a sub-account
Reached over
HTTPS from your network to the Google Ads API. Nothing inbound
Schema
gads — so gads.campaign, gads.search_term_view
Tables
12, of which seven are on by default: customer, campaign, ad_group, keyword_view, search_term_view, geographic_view, device_view
Money
In micros, as the API reports it — divide by a million for currency
Freshness
Runs to yesterday. Each incremental pass re-reads the previous three days so late-attributed conversions land
History
90 days on first sync. change_history is limited to 29 days by Google
Local copy
An AES-256-GCM encrypted DuckDB file beside the agent, on your machine

Read-only is structural. The connector only issues Google's search queries — there is no mutate call in it at all — so a query cannot change a bid, pause a campaign or spend a cent.

In a cross-source query the middle part of a three-part reference is gads. A connection called ads reading the campaign table is written ads.gads.campaign.

Vendor documentation: ads.google.com

FAQ

Questions about Google Ads

Which tools can read Google Ads data through Query Streams?

All of them, from one connection: Excel, Google Sheets, MCP, REST API, Airtable, Baserow, SeaTable, Smartsheet, Anvil, Power BI, scheduled alerts and reports. Connect the account once and every surface reads the same read-only connection — there is no per-tool setup and no second copy of the data.

Do I have to open a firewall port to my Google Ads account?

No. The Query Streams Network Agent runs inside your network and opens a single outbound encrypted connection. Nothing listens for inbound traffic, no VPN is required, and the account keeps its existing firewall rules.

Can Query Streams change data in Google Ads?

No. The agent enforces read-only at the point of execution — one statement at a time, SELECT and friends only. Credentials stay on the agent and are never sent to Query Streams.

What does Query Streams need to connect to Google Ads?

A reachable host, a role and its password — the agent carries the driver, so nothing is installed on the account. Authentication: A Google service account key with domain-wide delegation, a developer token, and the email it impersonates. All held on the agent. Account: A customer id, plus an optional manager account id for reaching a sub-account. Reached over: HTTPS from your network to the Google Ads API. Nothing inbound. Schema: gads — so gads.campaign, gads.search_term_view.

Can I join Google Ads to another database in the same query?

Yes — that is a federated query. One statement can reference Google Ads and your other connections at once, written as connection.schema.table. Each source runs only the part it can and streams the result back; the join happens centrally, so the sources never connect to each other and nothing is copied or scheduled. Read-only applies to every piece — SELECT, WITH and EXPLAIN only — and there is a ceiling on how much any one source may hand over for a single query. Federated queries are a plan feature; the federated queries page carries the current source and size limits.

Put Google Ads where the work happens

Install the agent, point it at your account, and pick a destination.

Read-only Outbound only Credentials stay on the agent