FlowKit

Automatically pausing underperforming Google Ads campaigns with n8n and AI

Published 12 August 2026 · 5 min read

A Google Ads campaign that spirals out of control on a Friday evening keeps spending until someone finally reopens the dashboard on Monday morning. Our article on Google Ads and Meta Ads reporting solved the read side: consolidating metrics, spotting drift, sending a summary. It deliberately stopped short of the next step — acting. This guide builds that second half: an n8n workflow that watches campaigns continuously, lets an LLM judge whether one is genuinely off track, and cuts its budget itself via the Google Ads API, without waiting for a human to open a screen.

Why the native Google Ads node isn't enough

The first instinct when opening n8n is to look for a "Pause" or "Update" operation directly in the Google Ads node. It doesn't exist. The native node's Campaign resource only exposes two operations, both read-only:

Operation Role
Get Fetches a specific campaign by its campaignId
Get Many Lists an account's campaigns, with filters by period (last 7 days, last month…) and by status (ENABLED, PAUSED, REMOVED)

Both operations return budget (expressed in micros — divide by 1,000,000 for the real value), status, optimization score, channel type, and metrics (impressions, interactions, conversions, CTR). Plenty for reporting, as covered in our dedicated article. But for writing — changing a status, adjusting a budget — the native node simply doesn't have the piece you need. You have to go through the HTTP Request node and talk to the Google Ads API directly.

Prerequisites before you start

Three things to have ready, distinct from what the native node requires:

  • A Google Ads developer token, obtained from your Google Ads account's API Center — a "Standard" access level is enough for this use case.
  • A Google Ads OAuth2 credential in n8n (client ID, client secret, refresh token) — the same one used for the native node, reusable as a predefined credential type on the HTTP Request node.
  • The manager account ID (login-customer-id) if your campaigns are managed under an MCC — without this header, the API rejects the request with an authorization error even with a valid token.

Always test this pipeline on a test Google Ads account or on a very-low-budget campaign before pointing it at a production account: a logic error here doesn't break a workflow, it pauses a campaign that was performing fine.

Step 1 — Collect metrics with the Google Ads node

A Schedule Trigger firing every hour or two triggers a Google Ads → Campaign → Get Many node, filtered on ENABLED status and the "Last 7 Days" period to get a trend rather than a misleading snapshot. The output includes, per campaign, cumulative cost, number of conversions, and CTR over the chosen window — enough to compute a real cost per conversion, not an estimate.

Step 2 — Let an LLM judge, not just a fixed threshold

A simple IF cost_per_conversion > X works, but it ignores context: an awareness campaign doesn't have the same profile as a direct-conversion campaign, and a 48-hour cost spike isn't the same drift as a trend degrading over five consecutive days. This is where an AI Agent node adds something a threshold can't: it receives the campaign's metric history, its stated goal (target CPA, monthly budget), and produces a contextualized judgment rather than a raw comparison.

To keep that judgment usable by the rest of the workflow, force a structured output with the Structured Output Parser: a JSON { "pause": true, "campaignId": "...", "reason": "...", "confidence": 0.82 }. The reason field isn't cosmetic — it feeds the logging and the alert sent to the team, and it's what lets you understand after the fact why a decision was made.

Step 3 — Execute the pause via the Google Ads mutate API

The HTTP Request node calls POST https://googleads.googleapis.com/v18/customers/{clientCustomerId}/campaigns:mutate, with predefined authentication using the existing Google Ads OAuth2 credential. Two headers still need to be added manually — as with the reporting node, n8n doesn't inject these values automatically even with the predefined credential selected:

  • developer-token: your developer token
  • login-customer-id: the manager account ID, without dashes

The request body follows Google's standard mutate operation format, with an updateMask that explicitly states which field is changing:

{
  "operations": [
    {
      "updateMask": "status",
      "update": {
        "resourceName": "customers/{clientCustomerId}/campaigns/{campaignId}",
        "status": "PAUSED"
      }
    }
  ]
}

Only wire this node off the pause: true branch of the AI judgment — never run it unconditionally on every campaign fetched in step 1.

The safeguard most attempts skip

Automating a read is harmless if the workflow breaks: worst case, no report that day. Automating a write that cuts an ad budget changes the equation — a misjudgment by the LLM or a field-mapping bug has an immediate, visible financial impact. A study by Kupfer, Prassl, Fleiß, Malin, Thalmann, and Kubicek published in Frontiers in Psychology in 2023 (see on Google Scholar), on automation bias in AI-assisted decisions, shows that a human faced with an algorithmic recommendation tends to approve it without really checking it once the system seems broadly reliable — exactly the trap of a workflow that has "worked fine" for weeks and stops being supervised.

Two concrete safeguards, easy to wire into n8n:

  1. Cap automation by budget. Only allow unconditional automatic pausing under a daily spend threshold (an IF node on the campaign's budget). Above it, route to a human approval circuit with the Wait node and Slack buttons: the pause waits for validation before executing.
  2. Log every decision, including the ones that don't go through. Record campaign, the LLM's reason, confidence score, and the action actually executed in a Supabase table, following the same principle as our GDPR audit trail guide. If a decision is questioned later, you have the full reasoning trail, not just the outcome.

Going further

This workflow closes the loop opened by automated reporting: read the metrics, let AI judge with an explicit reason, act via a write to the API, and keep a trace of everything — the same foundation as the Compliance & Audit Pack (€149), whose Supabase logging adapts directly to this marketing use case. If your immediate priority is still an overflowing inbox, the Inbox AI Pack (€79) applies the same triage-and-alert logic to your emails; and the Complete FlowKit Bundle (€269 instead of €347) brings all three packs together on a shared base if you plan to chain several automations like this one.

FAQ

Frequently asked questions

Can n8n's native Google Ads node pause a campaign?

No. As of today, the node only exposes two operations on the Campaign resource: "Get" and "Get Many", both read-only. There is no native "Update" or "Pause" operation. To change a campaign's status, you need an HTTP Request node calling the Google Ads API's mutate endpoint directly.

Do you need a Google Ads Manager account (MCC) for this workflow?

Not strictly, but it's the most common setup in agencies or in-house teams managing several client accounts: managerCustomerId identifies the account holding API access, and clientCustomerId identifies the campaign being watched. On a standalone Google Ads account, both values are the same.

What's the real risk of automating campaign pausing?

The main risk isn't technical, it's decisional: a poorly calibrated criterion can pause a campaign going through a normal dip (weekend, seasonality) rather than a genuine drift. That's why this workflow always logs the decision and its reason, and why unconditional automatic pausing is best reserved for small budgets, with human approval required above a threshold.

Can you also automatically re-enable a campaign that recovers?

Yes, with the same mechanism: the HTTP Request node accepts the exact same mutate call with status set to ENABLED. Just add a symmetrical decision branch in the AI node, based on the history of campaigns the workflow itself has paused rather than ones that were never active.

Bundle FlowKit Complet

€269