Reporting, GAQL queries, keyword research, and guarded campaign management
for the Google Ads API —
in one Python file with no dependencies. No client library, no SDK,
nothing to pip install except the tool itself. Auth rides on gcloud
Application Default Credentials, so every user authenticates as themselves.
$ gads campaigns
id name status type budget/day impr clicks cost conv ctr avg_cpc
----------- ----------- ------- ------ ---------- ---- ------ ------ ---- ---- -------
24006866610 Campaign #1 ENABLED SEARCH $50.00 115 8 $11.21 0 7.0% $1.40
- Every mutate is a dry run by default. Write commands print the exact
JSON payload they would send and exit; add
--executeto send it. - Everything is created PAUSED — campaigns, ad groups, ads, keywords. Enabling spend is always a deliberate, separate act.
- Reads are plain GAQL; the tool adds nothing that can change an account without the two steps above.
Requires Python 3.9+ and the gcloud CLI.
With pipx (recommended):
pipx install git+https://github.com/Benmore-Studio/gads.gitOr as a single file — the CLI is one standalone Python file, so this works too:
curl -fsSL https://raw.githubusercontent.com/Benmore-Studio/gads/main/gads/cli.py \
-o ~/.local/bin/gads && chmod +x ~/.local/bin/gadsOr run it without installing (uv):
uvx --from git+https://github.com/Benmore-Studio/gads.git gads doctor-
Authenticate Google (opens a browser; the
--scopesflag is required):gcloud auth application-default login \ --scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/adwords gcloud auth application-default set-quota-project <your-gcp-project>
-
Configure the tool — you'll need your org's shared developer token (from the manager account's Admin → API Center) and the GCP project where the Google Ads API is enabled:
gads init
-
Verify everything:
gads doctor
doctorchecks gcloud, the OAuth scopes, config, API reachability, and reports your developer token's access level (Explorer = read-only; Basic unlocks planning + writes).
Config lives in ~/.config/gads/config.json; every value can be
overridden per-invocation with GADS_DEVELOPER_TOKEN, GADS_QUOTA_PROJECT,
GADS_CUSTOMER, GADS_LOGIN_CUSTOMER_ID.
Every report takes --customer (defaults from config), --output table|json|csv, and most take --range (30d style — inclusive of
today — or GAQL keywords like TODAY, LAST_7_DAYS).
| Command | What it shows |
|---|---|
gads accounts |
accessible accounts with names/currency/type |
gads account |
account settings (currency, timezone, auto-tagging) |
gads campaigns |
campaign performance + daily budgets |
gads adgroups [--campaign ID] |
ad group performance |
gads ads [--ad-group ID] |
ads with approval status + headline preview |
gads keywords [--ad-group ID] |
keyword performance + quality score |
gads search-terms |
the actual queries that triggered your ads |
gads negatives |
negative keywords at campaign + ad group level |
gads devices / days / hours |
performance splits |
gads history [--days N] |
change history — who changed what |
gads recommendations |
Google's optimization suggestions |
gads budgets / conversions / assets |
supporting resources |
gads query "SELECT ..." |
raw GAQL, auto-paginated |
gads fields 'campaign.%' |
discover queryable GAQL fields |
gads keyword-ideas --seed "custom app development" --url https://example.com/services
gads keyword-metrics -k "app development company" -k "hire app developers"Volumes, competition, and top-of-page bid ranges; --geo / --language
default to US / English.
gads rsa-create --ad-group 123 --final-url https://example.com \
-H "Headline One" -H "Headline Two" -H "Headline Three" \
-D "First description." -D "Second description." # prints payload
gads rsa-create ... --execute # actually creates (PAUSED)
gads keywords-add --ad-group 123 -k "app development company" --match phrase
gads negatives-add --campaign 456 -k "free" -k "template"
gads campaign-create --name "App Dev - Search" --daily-budget 50
gads adgroup-create --campaign 456 --name "Custom Apps" --cpc-bid 2.50
gads campaign-status --campaign 456 --status paused
gads ad-status --ad-group 123 --ad-id 789 --status paused
gads budget-set --budget 321 --daily 75
gads asset-image --file creative.png --name "Hero 1200x628"
gads raw customers/123/someService:mutate '{"operations":[...]}' # escape hatchYour org's developer token determines what the API allows:
- Explorer (granted automatically): all reporting above.
- Basic (apply in the manager account → Admin → API Center): adds keyword planning and all write commands.
gads doctor tells you which level your token currently has.
Apache-2.0. Not an official Google product.