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.
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.
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 yetGoogle 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 yetGoogle 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 guideGoogle 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 yetGoogle 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 yetGoogle 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 yetGoogle 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 yetGoogle 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 yetGoogle 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 yetGoogle 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 yetGoogle 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 yetHow it works
5 steps, no inbound firewall change
Get a developer token for your Google Ads account and create a service account with domain-wide delegation.
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.
Choose which of the 12 tables to sync. Campaigns, ad groups, keywords, search terms, geography, devices and the account itself are on by default.
Write ordinary SQL against gads.campaign, gads.search_term_view and the rest — or let Nova write it.
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
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

