Access the Google Ads API with managed OAuth authentication. Query campaigns, ad groups, keywords, and performance metrics using GAQL.
CLI:
maton google-ads query -c 1234567890 --resource campaign --fields 'campaign.id, campaign.status'
maton google-ads query -c 1234567890 --gaql 'SELECT campaign.id, campaign.status FROM campaign'
maton api '/google-ads/v24/customers/1234567890/googleAds:search' -f query='SELECT campaign.id, campaign.status FROM campaign'
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'SELECT campaign.id, campaign.name, campaign.status FROM campaign'}).encode()
req = urllib.request.Request('https://api.maton.ai/google-ads/v24/customers/1234567890/googleAds:search', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/google-ads/{native-api-path}
Maton proxies requests to googleads.googleapis.com and automatically injects OAuth and developer tokens.
NPM:
npm install -g @maton-ai/cli
Homebrew:
brew install maton-ai/cli/maton
CLI:
maton login # Opens browser for API key
maton login --interactive # Skip browser, paste API key directly
maton whoami # Show current auth state
Manual:
MATON_API_KEY:export MATON_API_KEY="YOUR_API_KEY"
Manage your Google Ads OAuth connections at https://api.maton.ai.
CLI:
maton connection list google-ads --status ACTIVE
maton api -X GET /connections -f app=google-ads -f status=ACTIVE
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=google-ads&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
CLI:
maton connection create google-ads
maton api /connections -f app=google-ads
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'google-ads'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
CLI:
maton connection view {connection_id}
maton api /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "google-ads",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
CLI:
maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple Google Ads connections, specify which one to use:
CLI:
maton google-ads campaign list -c 1234567890 --connection {connection_id}
maton api /google-ads/v24/customers/1234567890/googleAds:search --connection {connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'SELECT campaign.id, campaign.name FROM campaign'}).encode()
req = urllib.request.Request('https://api.maton.ai/google-ads/v24/customers/1234567890/googleAds:search', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always specify the connection to ensure requests go to the intended account.
GET /google-ads/v24/customers:listAccessibleCustomers
Example:
maton google-ads account list
POST /google-ads/v24/customers/{customerId}/googleAds:search
Content-Type: application/json
{
"query": "SELECT campaign.id, campaign.name, campaign.status FROM campaign ORDER BY campaign.id"
}
Example:
maton google-ads query -c 1234567890 --resource campaign --fields 'campaign.id, campaign.name, campaign.status' --order-by 'campaign.id'
POST /google-ads/v24/customers/{customerId}/googleAds:search
Content-Type: application/json
{
"query": "SELECT ad_group_criterion.keyword.text, ad_group_criterion.keyword.match_type, ad_group_criterion.status, metrics.impressions, metrics.clicks, metrics.cost_micros FROM keyword_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.impressions DESC"
}
Example:
maton google-ads keyword list -c 1234567890 --date-range LAST_7_DAYS -L 25 --campaign-id 99999
Note: This command requests metrics, so it cannot be run against a manager (MCC) account directly. Run it against the client customer ID under the manager, optionally with --login-customer-id. See Manager (MCC) Account Access.
POST /google-ads/v24/customers/{customerId}/googleAds:searchStream
Content-Type: application/json
{
"query": "SELECT campaign.id, campaign.name FROM campaign"
}
Example:
maton google-ads query-stream -c 1234567890 --resource campaign --fields 'campaign.id, campaign.name'
SELECT campaign.id, campaign.name, campaign.status, campaign.advertising_channel_type
FROM campaign
WHERE campaign.status != 'REMOVED'
ORDER BY campaign.name
SELECT campaign.id, campaign.name, metrics.impressions, metrics.clicks, metrics.cost_micros, metrics.conversions
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
ORDER BY metrics.impressions DESC
SELECT ad_group.id, ad_group.name, ad_group.status, campaign.id, campaign.name
FROM ad_group
WHERE ad_group.status != 'REMOVED'
SELECT ad_group_criterion.keyword.text, ad_group_criterion.keyword.match_type, metrics.impressions, metrics.clicks, metrics.cost_micros
FROM keyword_view
WHERE segments.date DURING LAST_30_DAYS
AND ad_group_criterion.status = 'ENABLED'
ORDER BY metrics.cost_micros DESC
LIMIT 50
SELECT search_term_view.search_term, campaign.name, ad_group.name, metrics.impressions, metrics.clicks, metrics.conversions
FROM search_term_view
WHERE segments.date DURING LAST_30_DAYS
ORDER BY metrics.clicks DESC
SELECT customer.descriptive_name, segments.date, metrics.impressions, metrics.clicks, metrics.cost_micros, metrics.conversions
FROM customer
WHERE segments.date DURING LAST_7_DAYS
When accessing a customer account through a Google Ads manager (MCC) account, pass the manager's customer ID via --login-customer-id (CLI) or the login-customer-id header (direct API). The customer ID in the path is still the client account being queried.
CLI:
# List campaigns in client account 1234567890 via manager 9876543210
maton google-ads campaign list -c 1234567890 --login-customer-id 9876543210
maton api '/google-ads/v24/customers/1234567890/googleAds:search' -H 'login-customer-id: 9876543210' -f query='SELECT campaign.id, campaign.name FROM campaign'
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'SELECT campaign.id, campaign.name FROM campaign'}).encode()
req = urllib.request.Request('https://api.maton.ai/google-ads/v24/customers/1234567890/googleAds:search', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('login-customer-id', '9876543210')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Google Ads uses token-based pagination. The CLI automatically paginates with '--paginate'.
Example:
maton google-ads campaign list -c 1234567890 --paginate
# List accessible customer accounts
maton google-ads account list
# Filter with jq
maton google-ads campaign list -c 1234567890 --json --jq '.results[] | {id: .campaign.id, name: .campaign.name}'
# Extract specific fields
maton google-ads campaign list -c 1234567890 --json --jq '.results[].campaign.name'
// Get customer IDs
const customers = await fetch(
'https://api.maton.ai/google-ads/v24/customers:listAccessibleCustomers',
{ headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } }
).then(r => r.json());
// Query campaigns
const campaigns = await fetch(
`https://api.maton.ai/google-ads/v24/customers/${customerId}/googleAds:search`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
},
body: JSON.stringify({
query: 'SELECT campaign.id, campaign.name FROM campaign'
})
}
).then(r => r.json());
import os
import requests
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
# Query campaigns
response = requests.post(
f'https://api.maton.ai/google-ads/v24/customers/{customer_id}/googleAds:search',
headers=headers,
json={'query': 'SELECT campaign.id, campaign.name FROM campaign'}
)
listAccessibleCustomers first to get customer IDsLAST_7_DAYS, LAST_30_DAYS, THIS_MONTHENABLED, PAUSED, REMOVED--login-customer-id (or the login-customer-id header). See Manager (MCC) Account Access.curl -g when URLs contain brackets (fields[], sort[], records[]) to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.| Status | Meaning |
|---|---|
| -------- | --------- |
| 400 | Missing Google Ads connection |
| 401 | Invalid or missing Maton API key |
| 429 | Rate limited (10 req/sec per account) |
| 4xx/5xx | Passthrough error from Google Ads API |
CLI:
maton whoami
maton connection list
Manual:
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
google-ads. For example:https://api.maton.ai/google-ads/v24/customers:listAccessibleCustomershttps://api.maton.ai/v24/customers:listAccessibleCustomers共 3 个版本