FlowKit

Automating Google Ads and Meta Ads reporting with n8n and AI

Published 27 July 2026 · 5 min read

Opening Google Ads, opening Meta Ads Manager, copying the key numbers into a spreadsheet, comparing to the previous week, repeating for every client account — this Monday-morning ritual easily eats an hour per account for a result that says nothing more than a table of numbers side by side. n8n can query both APIs directly, consolidate the metrics into a common format, flag campaigns losing steam, and deliver a readable summary in Slack or by email — without a human ever opening a dashboard.

Why automate multi-platform ad reporting

Manual reporting always suffers from the same limits: it only gets produced when someone remembers to do it, it rarely compares more than two periods, and it flags nothing between two checks — a campaign whose cost per acquisition doubles on a Wednesday can burn through budget until next Monday's report. A study published in Sustainability by Mohamed, Mahmoud, Mahdi and Mostafa (2022), focused on automating repetitive reporting tasks, shows that the main gain isn't just time saved: it's mostly the reduction in manual entry and calculation errors, plus the consistency of execution, that justify automating a task once data compilation becomes recurring. Multi-account ad reporting checks exactly those two boxes.

Connecting n8n to the Google Ads API

n8n's native Google Ads node mainly covers fetching campaigns; for a detailed performance report (impressions, clicks, cost, conversions by day and by campaign), you need the HTTP Request node:

  1. Create a Google Ads OAuth2 API credential in n8n (Client ID and Client Secret from a Google Cloud project, plus the developer token generated in the Google Ads interface).
  2. In the HTTP Request node, select Predefined Credential Type and this credential: n8n then handles OAuth2 token refresh automatically.
  3. Query the POST https://googleads.googleapis.com/v18/customers/{customerId}/googleAds:searchStream endpoint with a GAQL (Google Ads Query Language) query selecting the metrics you want over the desired period.

A common pitfall documented by the n8n community: even with the predefined credential, the developer-token header is not automatically injected, which produces a DEVELOPER_TOKEN_PARAMETER_MISSING error. The fix is simple — add the header manually in the node's Headers tab, with your developer token as the value — but it consistently surprises people on first setup.

Connecting n8n to Meta Ads Insights

On the Meta side, the Facebook Graph API node is more directly usable: it natively covers the ad account insights endpoint. After creating a long-lived access token (a System User in Meta Business Suite, with the ads_read permission), a request to act_{ad-account-id}/insights with the fields spend, impressions, clicks, ctr, actions, frequency returns the metrics you need, broken down by campaign via the level=campaign parameter. The frequency field — the average number of times the same user has seen the ad — is what will let you spot ad fatigue further down the workflow.

Consolidating metrics into a common format

Google Ads and Meta neither name nor structure their metrics the same way (cost vs. spend, conversions vs. typed actions). A Code node normalizes both feeds into a single schema before any comparison:

return items.map(item => {
  const spend = Number(item.json.costMicros ? item.json.costMicros / 1e6 : item.json.spend);
  const conversions = Number(item.json.conversions ?? item.json.actions ?? 0);
  return {
    json: {
      platform: item.json.platform, // "google_ads" or "meta_ads"
      campaign: item.json.campaignName ?? item.json.campaign_name,
      spend,
      clicks: Number(item.json.clicks),
      conversions,
      cpa: spend > 0 && conversions > 0 ? spend / conversions : null,
    }
  };
});

This same common format then lets you sort by ascending CPA or descending spend in a single pass, across every platform — rather than two separate reports nobody takes the time to cross-reference mentally.

Detecting ad fatigue before it costs you

A campaign whose CTR drops while exposure frequency climbs is a classic sign of a worn-out creative — budget keeps flowing for diminishing returns. A study published in the Journal of Marketing Analytics by Elsen, Pieters and Wedel (2025), on the effects of ad exposure duration and frequency, shows that the effect of repetition depends heavily on the type of creative: a "typical" ad (expected format and message for the audience) tolerates a higher-than-average frequency, while an atypical creative wears out faster but benefits more from longer, less frequent exposures. In practice, this argues against applying a single frequency threshold to every campaign: the workflow instead computes, campaign by campaign, how CTR evolves relative to its own frequency over recent weeks, and only flags cases where the trend turns clearly negative — a threshold relative to that campaign's own history, not a magic number imported from elsewhere.

Generating a plain-language summary with AI

An AI node (Anthropic or OpenAI — see our guide on connecting Claude or GPT to n8n) turns the consolidated table into two or three paragraphs: campaigns performing well, ones losing steam with a creative-fatigue hypothesis when frequency confirms it, and a recommended action (pause, refresh the creative, reallocate budget). The prompt stays deliberately constrained to the figures supplied in the request, without extrapolating on unverifiable external causes — the same principle as an audit summary, detailed in our article on the AI-generated summary report from the Compliance & Audit Pack.

Distributing and archiving the report

The report then goes out via Slack (the same pattern as the daily email digest in the AI Inbox Pack, here on a weekly cron) or an HTML email for an external client. Before sending, every report — raw data and AI summary included — is worth archiving into a Supabase table: that lets you reconstruct a performance history across several months, following the same logging pattern as the Supabase audit trail we cover elsewhere.

Budget-overrun alerts independent of the report

The CPA and cumulative spend calculation can also feed a second, more reactive trigger: if a campaign's daily spend exceeds a defined threshold (stored in Supabase or Google Sheets), an immediate Slack alert goes out without waiting for Monday's report. It's the same threshold logic as technical error monitoring — see our guide on error handling and the Error Workflow — applied here to a budget metric instead of a failure.

Common pitfalls

  • Forgetting the developer-token header on Google Ads calls via HTTP Request: the DEVELOPER_TOKEN_PARAMETER_MISSING error shows up even with a correctly configured credential.
  • Comparing different currencies or time zones between Google Ads and Meta accounts without normalizing first: a consolidated report mixing EUR and USD without conversion, or days anchored to different time zones, silently skews the comparisons.
  • Granting write access to the reporting workflow's credentials: a read-only scope (reporting/insights) is enough and limits the damage if a token is compromised.
  • Applying a universal frequency threshold to detect ad fatigue, when the relevant threshold depends on the creative's type and each campaign's own history.

Going further

The underlying principle — consolidated API calls, metric calculations in a Code node, AI-constrained summary, archiving, and independent alerting — is exactly what powers the reporting workflows in the Compliance & Audit Pack (€149). If you scale this kind of AI summary across multiple accounts or several reports a week, our guide on tracking AI call costs in n8n helps keep that expense under control.

FAQ

Frequently asked questions

Does n8n have native nodes for Google Ads and Meta Ads?

Partly. The native Google Ads node mostly covers fetching campaigns; for detailed performance reports you need the HTTP Request node with the 'Predefined Credential Type' authentication option. On the Meta side, the Facebook Graph API node is more complete and natively covers the ad account insights endpoint.

Why does the HTTP Request node return DEVELOPER_TOKEN_PARAMETER_MISSING on Google Ads?

This is a documented behavior: even with the Google Ads OAuth2 API credential selected as a predefined credential, n8n does not automatically inject the developer-token header. You need to add it manually in the HTTP Request node's Headers tab, with your Google Ads developer token as the value.

How do you set a reliable ad-fatigue threshold?

There is no universal threshold: the frequency at which a creative wears out depends heavily on its type. The most reliable approach is to compute, per campaign, the correlation between frequency and CTR over recent weeks, and only alert when the trend turns clearly negative for that campaign itself — not against some industry-wide average.

Does this workflow need write access to the Google Ads and Meta APIs?

No. A read-only scope (reporting/insights) is entirely sufficient to consolidate metrics and generate a summary. Keeping write access (bid or budget changes) in a strictly separate workflow limits the blast radius of a misconfiguration or a compromised token.

Bundle FlowKit Complet

€269