Marketing agencies · Alerts

Media watchdog

Every morning, the short list of what broke across the portfolio: accounts that dropped to zero, campaigns that stopped converting, accounts with no adjustments, balances running out and stalled sources.

UsageCommon
EffortMedium
ForAgencies with many media accounts and a team that cannot check all of them every day.
Source

Daily media, changes, accounts and source runs

Rule

Live source, objective and windows before alerting

Outcome

Alerts with key and state per client

Activation

Daily message and task per alert

What it solves

  • The agency learns about a problem before the client does.
  • Alerts fire only on real problems, not because of a late source or the wrong objective.
  • Prepaid accounts do not stop for lack of balance without warning.

Business questions it answers

Ask your agent these questions once the case is live.

Which accounts dropped to zero yesterday?
Which clients have had no adjustments for more than 7 days?
Which prepaid accounts run out of balance this week?
Is any source late and possibly hiding a problem?
Which campaign stopped converting and how much has it spent since?

What you need

  • Portfolio media in a daily table with the client on each row
  • Account-to-client registry with the official accounts and their status
  • A delivery channel (Chat, Slack, Discord) or task manager

What you get

  • Daily alerts table with key and state
  • Balance monitor for prepaid accounts with days until empty
  • Source freshness monitor
  • Daily AI-written message for leadership

Where to activate

Daily message to leadership

At 7am on weekdays, in the team channel, only with what is new or got worse.

Task per alert

One ticket per client and alert family in the project manager, with an owner, a due date and a daily check.

AI agent via MCP

Answers "what broke yesterday" from the alerts table.

Ready to build?

Depends on portfolio media already being unified. The rules are SQL; the care goes into the limits and the state so it does not turn into noise. The detailed view has the business rules, the pitfalls and the acceptance test. Or send everything straight to your agent with the Nekt MCP.

The problem

With dozens of accounts, nobody checks all of them every day. The agency finds out about the paused campaign, the account with no balance or the conversions that dropped to zero when the client complains. And a badly built alert is worse: it fires every day because of a late source or a reach campaign with no leads, and the team learns to ignore it.

How it is usually done, and the rule

Each row is a mistake that already happened in practice.

The common wayThe rule
01
Alerting zero spend from a connector that did not run.
A stalled source is not a stalled network

Before saying spend dropped to zero, check that the source synced, using its run in Nekt. Without a sync, the alert is FONTE_SEM_SYNC. Only with a live source does zero spend become REDE_ZERADA. Do not generate performance alerts on a degraded source.

02
A fixed 2-day limit for every source.
Delay tolerance follows the source cadence

Delay = expected date minus the latest date in the table. Tolerances used: Meta and Google D-1; LinkedIn and GA4 D-2; marketing automation D-3. Weekly source: interval between extractions plus 2 days of slack (9 days). If the cadence changes, the limit changes with it. An account intentionally paused in the registry does not alert.

03
A zero-leads alert on a reach campaign.
Judge by optimization, not by name

Reach, traffic or video campaigns are not judged on conversions. What defines it is the ad set's optimization_goal and the optimized event, not TOFU, MOFU or BOFU in the campaign name.

04
Calling a campaign that never converted, or has no spend, dropped to zero.
Dropped to zero means it stopped converting while spending

CAMPANHA_ZEROU only when there is spend in the recent window, zero conversions of the optimized event and conversions in the earlier history. The message includes network, spend since it stopped and the history. REDE_ZERADA is a network with budget in the plan and no spend.

05
Looking only at the 30-day total.
Short windows against the baseline

Compare the 7 days through yesterday with the previous 7 and with the 28-day baseline. Always show leads per day over the last 7, 15 and 30 days. The reference day is yesterday, the last full day in the client's time zone.

06
Counting any event in the history as an adjustment.
Human adjustments exclude automatic ones

No adjustment = a client with spend in the last 7 days and no human change for more than 7 days, evaluated per network. Meta: actor_name other than 'Meta' in the change history. Google: interface, Editor, app, applied recommendations and bulk upload; scripts, automated rules and API are left out.

07
Treating balance as available funds on every account.
Balance follows the account semantics

On a prepaid account (is_prepay_account true), balance is remaining credit; on a postpaid account, it is the amount owed. Store the raw balance under a neutral name and derive available balance only when Meta exposes it. Days until empty = available balance / average daily spend over the last 7 days. If there is a fee on Pix (instant payment) top-ups (e.g. 12.15%), the net balance is lower than the amount paid.

08
Monitoring the balance of every account in the table.
Only the client's official accounts

A source's accounts table lists every account the credential can see in Business Manager, including closed and third-party accounts. Filter by the official account_id in the account-to-client registry. An account with account_status other than active and zero spend with a live source becomes a payment alert.

09
Sending the whole list every day.
Alerts with a key and state

Stable key client|type|network|object. Persistent state: new, recurring, resolved. The same alert is not resent; every day it is checked whether it cleared. Optimization tips wait 7 days to mature before being reassessed.

10
Asking the model to find anomalies in raw data.
Rules in SQL, text by AI

Detection is SQL over the day's tables. The LLM only writes the message from the alerts, with network, amount and what to check first. If the alerts table is not from today, the message warns that the data is stale.

Alert types

Evaluated in order: first the source, then the account, then performance.

FONTE_SEM_SYNCSource not syncingdelay above tolerance or last run failed
CONTA_COM_PROBLEMAPayment issue or blocked accountaccount_status not active
SALDO_BAIXOBalance running outbalance / 7d average spend below N days
REDE_ZERADANetwork with budget and no spendlive source and zero spend
CAMPANHA_ZEROUStopped convertingrecent spend, zero conversions, past conversions
QUEDA_RESULTADODrop against the baseline7d vs previous 7d and 28d baseline
RITMO_VERBABudget pacing off plancumulative spend vs budget prorated by days
SEM_AJUSTENo human adjustmentspend in 7d and no human change in over 7d
REACH, TRAFFIC, VIDEONot judged on conversionsevaluate by CPM, reach and frequency

Definitions

Reference day
yesterday, the last full day in the client's time zone
7d window
the 7 days through yesterday; previous 7d is the 7 days before it; baseline is the last 28 days
Late source
expected date minus the latest date in the table, above the source's tolerance
Human adjustment
a change history event made by a person; on Meta, actor_name other than 'Meta'
Available balance
remaining credit on a prepaid account as reported by Meta; never derived from a postpaid account's balance
Days until empty
available balance / average daily spend over the last 7 days
Open alert
key client|type|network|object present on the day; resolved when it disappears on reassessment

Pitfalls that already happened

A paused campaign nobody noticed

The client had normal lead volume for the month, but the daily view showed six days in a row with no leads at all.

Leads per day over 7, 15 and 30 days, always.

Constant alarm

The sources switched to running once a week and the 2-day limit flagged every account. The team stopped reading the alert.

A limit derived from the cadence: interval plus 2 days.

A zero that was a stalled connector

The network showed zero because the source had not run, and the team went to change the campaign.

Check the source run before the network alert.

Balance from an account that is not the client's

The accounts table brought the whole Business Manager, with closed and third-party accounts in the balance monitor.

Filter by each client's official account_id.

Expired card

The account's card expired and the ads stopped silently for days.

Alert on account status and zero spend with a live source.

The same tip every day

Optimization tips repeated daily turned into noise before anyone acted.

Stable key, one task per tip and 7 days to mature.

Validated on real data. In Nekt's own Meta Ads account, 27% of one week's events in the change history had actor_name 'Meta' (automatic changes to delivery status, first delivery and billing). Counted as adjustments, they would make an idle account look well tended. In the same source, the accounts table lists 9 Business Manager accounts, with prepaid, postpaid and closed accounts mixed together, and only 1 of them has delivery.

Acceptance test

The case is done when every item passes.

Agent package

Paste into Claude, ChatGPT or any client with the Nekt MCP connected.

Full Markdown
Media watchdog
- Reference day = yesterday, the last full day in the client's time zone.
- Before any performance alert, check the source. Delay above tolerance (Meta and Google D-1, LinkedIn and GA4 D-2, marketing automation D-3, weekly source interval + 2 days) = FONTE_SEM_SYNC, and that network's performance is not analyzed.
- Zero spend with a live source and budget in the plan = REDE_ZERADA.
- CAMPANHA_ZEROU = recent spend, zero conversions of the optimized event and conversions in the history. Report network, spend and history.
- Reach, traffic and video campaigns (by optimization_goal, not by name) are not judged on conversions.
- Compare 7 days against the previous 7 and against the 28-day baseline. Always show leads per day over 7, 15 and 30 days.
- No adjustment = spend in the last 7 days and no human change for more than 7 days. On Meta, human means actor_name other than 'Meta'.
- Balance only for the official accounts in the registry. Prepaid: balance is credit; postpaid: balance is amount owed. Days until empty = balance / 7-day average spend.
- Each alert has the key client|type|network|object and a state (new, recurring, resolved). Do not repeat an alert already sent.
Client exceptions:
- <client>: shared account; only campaigns with <term> in the name are included.
- <client>: prepaid account topped up via Pix with a <x>% fee; warn when <n> days of balance are left.
- <client>: <platform> source runs weekly; tolerance of <n> days.

Variations

Plan vs. actuals

Alerts per plan line: unlinked, no delivery, out of period, off plan and budget pacing.

Optimization tips

Spend leaking without conversions, high CPA, scale up and creative fatigue, with 7 days to mature.

Balance on Google Ads

Account budget and projected end of month based on spend pace.