Google Ads

Google Ads API integration with managed OAuth. Query campaigns, ad groups, keywords, and performance metrics with GAQL. Use this skill when users want to interact with Google Ads data. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).

MIT-0 · Free to use, modify, and redistribute. No attribution required.
17 · 5.4k · 7 current installs · 8 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
Name/description match the instructions: the SKILL.md shows how to call Maton gateway endpoints to access Google Ads (GAQL, customer listing, connections). Required network access and MATON_API_KEY are appropriate for a managed-OAuth proxy service.
Instruction Scope
Instructions only describe HTTP calls to Maton endpoints (gateway.maton.ai, ctrl.maton.ai, connect.maton.ai) and example GAQL queries. They do not ask the agent to read local files, unrelated environment variables, or transmit data to unexpected endpoints.
Install Mechanism
No install spec and no code files — instruction-only skill. Nothing is written to disk or downloaded by the skill itself, which minimizes install-time risk.
Credentials
Only MATON_API_KEY is required and is used consistently in examples. No unrelated credentials, filesystem config paths, or broad secret access are requested. The single API key is proportionate for a gateway-based Google Ads integration.
Persistence & Privilege
always is false and there are no requests to modify other skills or system-wide settings. The skill can be invoked autonomously (platform default), which is expected for a user-invocable integration; this is not combined with other red flags.
Scan Findings in Context
[no_findings] expected: The regex scanner had no code to analyze because this is an instruction-only skill (SKILL.md + LICENSE). No suspicious patterns were detected in code files.
Assessment
This skill proxies Google Ads calls through Maton and requires a MATON_API_KEY — you are delegating OAuth and Google Ads access to Maton. Before installing, verify you trust Maton (maton.ai), confirm how they store and scope OAuth tokens, and ensure the API key you supply is least-privilege and revocable. Treat the MATON_API_KEY like any sensitive secret (don't paste it into public places). If you prefer not to use a third-party gateway, consider using your own integration or the referenced api-gateway skill. Finally, monitor activity for unexpected requests or connections after enabling the skill.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.5
Download zip
latestvk979zd5gek89crw2xh7ewcycsd80xyqr

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

Runtime requirements

🧠 Clawdis
EnvMATON_API_KEY

SKILL.md

Google Ads

Access the Google Ads API with managed OAuth authentication. Query campaigns, ad groups, keywords, and performance metrics using GAQL.

Quick Start

# List accessible customers
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/google-ads/v23/customers:listAccessibleCustomers')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Base URL

https://gateway.maton.ai/google-ads/{native-api-path}

Replace {native-api-path} with the actual Google Ads API endpoint path. The gateway proxies requests to googleads.googleapis.com and automatically injects OAuth and developer tokens.

Authentication

All requests require the Maton API key in the Authorization header:

Authorization: Bearer $MATON_API_KEY

Environment Variable: Set your API key as MATON_API_KEY:

export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Google Ads OAuth connections at https://ctrl.maton.ai.

List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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

Create Connection

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'google-ads'}).encode()
req = urllib.request.Request('https://ctrl.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

Get Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
    "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.

Delete Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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

Specifying Connection

If you have multiple Google Ads connections, specify which one to use with the Maton-Connection header:

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'SELECT campaign.id, campaign.name FROM campaign'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/google-ads/v23/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', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If omitted, the gateway uses the default (oldest) active connection.

API Reference

List Accessible Customers

GET /google-ads/v23/customers:listAccessibleCustomers

Search (GAQL Query)

POST /google-ads/v23/customers/{customerId}/googleAds:search
Content-Type: application/json

{
  "query": "SELECT campaign.id, campaign.name, campaign.status FROM campaign ORDER BY campaign.id"
}

Search Stream (for large results)

POST /google-ads/v23/customers/{customerId}/googleAds:searchStream
Content-Type: application/json

{
  "query": "SELECT campaign.id, campaign.name FROM campaign"
}

Common GAQL Queries

List Campaigns

SELECT campaign.id, campaign.name, campaign.status, campaign.advertising_channel_type
FROM campaign
WHERE campaign.status != 'REMOVED'
ORDER BY campaign.name

Campaign Performance

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

List Ad Groups

SELECT ad_group.id, ad_group.name, ad_group.status, campaign.id, campaign.name
FROM ad_group
WHERE ad_group.status != 'REMOVED'

List Keywords

SELECT ad_group_criterion.keyword.text, ad_group_criterion.keyword.match_type, metrics.impressions, metrics.clicks
FROM keyword_view
WHERE segments.date DURING LAST_30_DAYS

Code Examples

JavaScript

// Get customer IDs
const customers = await fetch(
  'https://gateway.maton.ai/google-ads/v23/customers:listAccessibleCustomers',
  { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } }
).then(r => r.json());

// Query campaigns
const campaigns = await fetch(
  `https://gateway.maton.ai/google-ads/v23/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());

Python

import os
import requests

headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}

# Query campaigns
response = requests.post(
    f'https://gateway.maton.ai/google-ads/v23/customers/{customer_id}/googleAds:search',
    headers=headers,
    json={'query': 'SELECT campaign.id, campaign.name FROM campaign'}
)

Notes

  • Use listAccessibleCustomers first to get customer IDs
  • Customer IDs are 10-digit numbers (remove dashes)
  • Monetary values are in micros (divide by 1,000,000)
  • Date ranges: LAST_7_DAYS, LAST_30_DAYS, THIS_MONTH
  • Status values: ENABLED, PAUSED, REMOVED
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets (fields[], sort[], records[]) to disable glob parsing
  • IMPORTANT: When piping curl output to jq 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.

Error Handling

StatusMeaning
400Missing Google Ads connection
401Invalid or missing Maton API key
429Rate limited (10 req/sec per account)
4xx/5xxPassthrough error from Google Ads API

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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

Troubleshooting: Invalid App Name

  1. Ensure your URL path starts with google-ads. For example:
  • Correct: https://gateway.maton.ai/google-ads/v23/customers:listAccessibleCustomers
  • Incorrect: https://gateway.maton.ai/v23/customers:listAccessibleCustomers

Resources

Files

2 total
Select a file
Select a file to preview.

Comments

Loading comments…