Most Google Ads accounts are silently leaking budget every day — on job seekers, competitors, and irrelevant queries that will never convert. Manually reviewing search terms is slow, inconsistent, and doesn't scale.
NegativeIQ automates the entire process.
It fetches your search terms from Google Ads into a Google Sheet, classifies each one using AI, and lets you push confirmed negatives back into your campaigns with a single click. No data leaves your account. No subscriptions. No black box.
Fetch → Pre-classify → AI-classify → You review → Push negatives → System learns
| Step | What happens |
|---|---|
| 1. Fetcher runs daily | Pulls all search terms from Search + PMax campaigns into your Google Sheet |
| 2. Pre-classify | Rule-based pass against your keyword lists — zero API cost |
| 3. AI-classify | Remaining terms sent to AI in batches — classified in seconds |
| 4. You review | Check classification, confidence score, and AI reasoning. Override if needed |
| 5. Export | Validated negatives written to staging sheet |
| 6. Uploader runs | Books negatives into your campaigns or shared negative lists |
| 7. Learning loop | Your corrections feed back into keyword lists and AI examples |
Google Ads
│
├── Fetcher Script (Google Ads Scripts — runs daily)
│ → Writes to Google Sheet: SearchTerms + PMax SearchTerms
│
Google Sheet (Apps Script)
├── AI Config — client profile, categories, AI examples, neg_lists registry
├── Keyword Lists — Brand Pure / Brand Kombi / Bestand / Sperrbegriffe / Mitbewerber / Brand Noise
├── SearchTerms — standard search campaign terms
├── PMax SearchTerms — Performance Max category label insights
├── Negative_Export — staging area for the uploader
└── Expansion_Ideen — keywords flagged as expansion opportunities
│
└── Uploader Script (Google Ads Scripts)
Books Negative_Export rows into Google Ads
Deletes successfully uploaded rows from the sheet
| File | Where it lives | What it does |
|---|---|---|
AI_Max_NegativeIQ_V2_3d___GAS.js |
Google Sheet → Extensions → Apps Script | Main Apps Script — classification, export, learning loop |
AI_Max_Negative_IQ_v2_3_fetcher.js |
Google Ads → Tools → Scripts | Fetches search terms + PMax insights into the Sheet |
AI_Max_Negative_IQ_v3.js |
Google Ads → Tools → Scripts | Reads Negative_Export and books negatives into Google Ads |
AI_Max_NegativeIQ_V2.3b_Template.xlsx |
— | Sheet template reference |
Active version: V2_3d
Create a new Google Sheet with these tabs (exact names, case-sensitive):
SearchTerms · PMax SearchTerms · AI Config · Keyword Lists · Negative_Export · Expansion_Ideen
Or copy the template directly →
Open the Sheet → Extensions → Apps Script. Paste AI_Max_NegativeIQ_V2_3d___GAS.js and save.
Set your API key: gear icon → Script Properties → add:
Key: AIML_API_KEY
Value: your-api-key-here
Uses AIML API with gpt-4o-mini by default. Swap model or endpoint in callAIBatch() if needed.
A1:B7 — Client Profile
| Key | Value |
|---|---|
client_name |
Your client or account name |
client_industry |
e.g. E-Commerce, SaaS, Versicherung |
default_neg_list |
Name of your default shared negative list in Google Ads |
brand_noise_list |
Name of your Brand Noise negative list |
conv_protect |
TRUE to skip terms with conversions |
confidence_warn |
Confidence threshold for warnings, e.g. 0.7 |
batch_size |
Terms per API call, e.g. 15 |
A9:B30 — neg_lists registry (one row per shared negative list, key neg_lists)
E1:G50 — Categories
| Code | Description | Action |
|---|---|---|
Brand Pure |
Exact brand name or clear purchase intent | Review |
Brand Kombi |
Brand + geo/product, direct intent | Review |
Brand Noise |
Brand + research/dissatisfaction signal | Negativ |
Mitbewerber |
Competitor brand terms | Negativ |
Junk |
Irrelevant, no intent | Negativ |
Informational |
Research queries, no purchase intent | Negativ |
Informational-Potential |
Research with SEO opportunity | Expansion |
Bestand (Aktiv) |
Already covered by active keywords | Review |
Unklar |
AI could not classify confidently | Review |
H1:I50 — AI Examples (seed examples to guide the AI)
Headers in row 3, data from row 4:
| A | B | C | D | E | F |
|---|---|---|---|---|---|
| Brand Pure | Brand Kombi | Bestand (Aktiv) | Sperrbegriffe | Mitbewerber | Brand Noise Terms |
Brand Noise Terms (col F) are noise modifiers: erfahrungen, alternative, kündigen, test, probleme, fake — not full terms.
Google Ads → Tools → Bulk Actions → Scripts → New script → paste AI_Max_Negative_IQ_v2_3_fetcher.js
Update the config block:
const SPREADSHEET_URL = 'YOUR_SHEET_URL_HERE';
const LOOKBACK_DAYS = 'LAST_30_DAYS';
const MIN_CLICKS = 1;
const PMAX_MIN_IMPR = 0;Set to run daily.
Google Ads → Tools → Bulk Actions → Scripts → New script → paste AI_Max_Negative_IQ_v3.js
const SPREADSHEET_URL = 'YOUR_SHEET_URL_HERE';
const EXPORT_SHEET_NAME = 'Negative_Export';Run manually after each export cycle, or schedule it.
Term contains brand name?
│
├── YES — Exact brand name only? → Brand Pure (confidence 1.0)
├── YES — Brand + known noise modifier? → Brand Noise → routes to brand_noise_list
├── YES — Exact match in Brand Kombi list? → Brand Kombi (confidence 1.0)
├── YES — Ambiguous modifier? → AI Queue (AI decides: Kombi vs Noise)
└── NO — Other list checks:
Sperrbegriffe → Junk
Bestand exact match → Bestand (Aktiv)
Mitbewerber → Mitbewerber
No match → AI Queue
Conv-Schutz runs first. If a term has conversions and
conv_protect = TRUE, it is flagged⚠️ Conv-Schutzand skipped during export regardless of classification.
[Fetcher — daily] Appends new search terms to both term sheets
[Sheet Menu]
1. Prepare Layout Styles sheets, sets up dropdowns
2a. Pre-Classify Config-list matching (no API cost)
2b. AI-Classify LLM classification for AI Queue rows only
→ Review col G (Classification), col H (Confidence), col I (Reason)
→ Override in col J (Korrektur)
→ Check col K (Validiert ✅) for rows ready to export
4. Export Writes to Negative_Export + Expansion_Ideen
5. Update Config Learning loop → updates Keyword Lists + AI examples
[Uploader] Books Negative_Export into Google Ads, deletes uploaded rows
Run 🔍 Diagnose & Debug from the sheet menu for a full status report:
- Sheet tab presence · Column header validation · Classification distribution
- AI Config summary · neg_lists registry · Category list · Keyword Lists counts · API key check
V2.3 (current)
- Brand tier split —
Eigene Markereplaced with three granular categories:Brand Pure,Brand Kombi,Brand Noise - Keyword Lists expanded to 6 columns
- Pre-classify brand logic updated with noise modifier routing
- AI system prompt updated with Brand tier rules
- Match type defaults: Mitbewerber + Brand Noise both default to
Exact - Export: Brand Noise auto-routes to
brand_noise_list - Learning loop: Brand tier corrections write to correct columns
V2.2
- Config sheet split into
AI ConfigandKeyword Lists getConfig(),learningLoop(),debugDiagnose()updated accordingly
V2.1 / V2.1.1
- PMax SearchTerms sheet added
- Fetcher extended with
fetchPMaxSearchTerms() - neg_lists registry added to AI Config
- Mitbewerber match type:
Phrase→Exact
V2.0
- Two-step classification: Pre-Classify → AI-Classify
- Conv-Schutz introduced
- Learning Loop introduced
V1
- Initial uploader: reads
Negative_Export, books negatives, deletes uploaded rows
- List names are case-sensitive in Google Ads. Check spelling before running the uploader.
- Brand_Noise_Negatives list must be created manually in Google Ads first.
- The fetcher aggregates metrics for duplicate terms instead of creating new rows.
- Learning Loop only processes rows with
Status = Verarbeitetand a value in col J. - AI uses
gpt-4o-minivia AIML API attemperature: 0.1for consistent output.
MIT — free to use, modify, and share.
