-
Notifications
You must be signed in to change notification settings - Fork 0
Blocked Search Term Recovery
Script: scripts/blocked_search_term_recovery.js
Level: Single account (CID)
What it does: Finds negative keywords blocking search terms with real conversion history — and removes them.

Excluded search terms don't announce themselves. When a converting query like hydro facial nyc or mens facial nyc gets added as a negative — by an auto-applied recommendation, a previous manager, or an overzealous exclusion session — it just quietly stops serving. Revenue drops and nothing in the interface tells you why.
Keyword-conflict tools can't catch most of these because keywords match queries via close variants while negatives match literally. A negative can block a valuable query without conflicting with any keyword text. This script skips keyword comparison entirely and audits negatives against actual search term performance.
-
Pulls search term history via GAQL (
search_term_view) for the lastLOOKBACK_DAYS— impressions, clicks, conversions, conversion value — scoped by campaign and ad group. -
Pulls every negative keyword in the account via GAQL, at four levels:
-
Account-level — from the
ACCOUNT_LEVEL_NEGATIVE_KEYWORDSshared set viashared_criterion(these are not incustomer_negative_criterion.keyword) -
Campaign-level — via
campaign_criterion, which includes Performance Max campaigns invisible toAdsApp.campaigns()entity iterators -
Ad group-level — via
ad_group_criterion -
Shared negative keyword lists — via
shared_criterion+campaign_shared_setattachment mapping
-
Account-level — from the
- Simulates negative matching exactly as Google applies it — EXACT (identical only), PHRASE (ordered word sequence), BROAD (all words, any order), literal with no close variants.
- Aggregates blocked value per negative and ranks the report by blocked conversions → conversion value → clicks.
-
Removes negatives whose blocked terms total ≥
MIN_BLOCKED_CONVERSIONS_TO_REMOVEconversions (whenDRY_RUN: false), viaAdsApp.mutate()with the correct operation type per level.
| Setting | Default | Notes |
|---|---|---|
DRY_RUN |
true |
Report only. Flip to false to remove. |
SPREADSHEET_URL |
'' |
Blank Google Sheet URL. Falls back to Logger. |
LOOKBACK_DAYS |
180 |
Must reach back to before the exclusions were added — blocked terms stop appearing in data once excluded. Use 365 for old exclusions. |
MIN_TERM_CLICKS |
1 |
Minimum clicks for a term to be considered (runtime control). |
MIN_BLOCKED_CONVERSIONS_TO_REMOVE |
1 |
Removal threshold in blocked conversions. |
REMOVE_ACCOUNT_LEVEL / REMOVE_CAMPAIGN_LEVEL / REMOVE_ADGROUP_LEVEL / REMOVE_FROM_SHARED_LISTS
|
true |
Per-level removal switches. Shared-list removal affects every attached campaign. |
PMax campaign negatives are fully visible to this script — but PMax search terms are not exposed in search_term_view. So PMax negatives are evaluated against your Search campaign term history as a proxy. A PMax negative blocking a term that converts in Search is treated as blocking value, which is the right signal when the same intent flows through both channel types. The report labels these rows CAMPAIGN (PMAX — proxy match vs Search history) so you always know which matches are proxied.
- Terms excluded long ago won't appear in a short lookback window (they stopped serving when blocked). Lengthen
LOOKBACK_DAYS. - The script measures what a negative blocks, not what it protects against. A negative can block one converter AND hundreds of junk queries — review rows where a broad or short negative is removed, and consider re-adding a tighter (exact) version.
- If auto-applied recommendations added the exclusions, they can come back. Audit Recommendations → Auto-apply and disable anything touching negative keywords, or schedule this script weekly.
On a live multi-location med-spa account, this workflow surfaced 60+ excluded search terms with conversion history — spread across Phrase, Performance Max, and AI Max exclusions — including geo-intent money terms like facials upper east side, hydro facial nyc, and best facial in manhattan. All recovered in one run, fully logged.
By AHMEEGO™ / It All Started With A Idea LLC. Discuss in r/ppc_.