Recommendations and alerts

X3 does not guess. Every recommendation comes from a fixed rule with minimum amounts, shows the numbers behind it and says how sure it is. Alerts tell you when something is broken or worth a look.

Recommendations

GET /v1/projects/{project}/recommendations (scopes analytics:read + ads:read; MCP recommendations_list). The Pulse shows up to five; for the standard periods (7d, this_week, 30d) they are precomputed by the insights.alerts job, other periods are computed on request.

Minimums: at least 3 leads or 300 € spend in the period. Campaigns in their learning phase (first spend less than 7 days ago or fewer than 50 clicks) never give budget away. Periods shorter than 7 days are evaluated on the last 14 days, and the recommendation says so in basis.

RuleWhenSuggests
shift_budgetCampaign A takes at least twice its share of leads in budget and costs ≥ 1.8× the median cost per lead (or has no lead at ≥ 2× the median); campaign B brings ≥ 3 leads at ≤ 0.7× the median, half of them qualifiedMove about half of A's spend to B; expected extra leads per week with a range
scale_winnerB is cheap (≤ 0.7× median), ≥ 3 leads, ≥ 2 qualified, budget forecast below 90 %Raise B's budget by up to 30 %
check_spend_no_leadsA spent ≥ max(500 €, 3× median) without a lead under all six counting rulesCheck landing page, form and audience
fix_funnel_stepOne step loses ≥ 1.4× as many visitors as before and ≥ 10 points more, with ≥ 50 entriesThe step and the leads lost per week
swap_creativeMeta video ad whose hook rate (3-second views ÷ impressions) is below 0.6× the campaign median, ≥ 150 € and ≥ 1,000 impressionsReplace the ad
connect_costs≥ 50 paid visits in 30 days from a platform without a connected ad accountConnect the account
map_unmatched≥ 50 paid visits (or ≥ 10 %) that match no adMap them so cost per lead is right
fix_reportingConversion uploads failing, access expired or pending for more than an hourFix the reporting access

How sure: the trigger uses the active counting rule; the direction is then checked under all six. High = holds in 6 of 6, ≥ 10 leads and ≥ 75 % surely assigned; medium = ≥ 4 of 6 or 5–9 leads; low otherwise (not shown in the Pulse). If campaign A was the first contact for many leads, the recommendation says so and moves only half.

Feedback: POST …/recommendations/{id}/feedback with done, later (until Monday), dismiss (hidden for 14 days, optional reason) or undo – scope ads:write; MCP recommendations_feedback. Done starts an impact measurement after 7 days that appears in the weekly report ("Since done: +3 leads, 168 € per lead").

Alerts

GET /v1/alerts (all your projects) and GET /v1/projects/{project}/alerts, scope analytics:read; MCP alerts_list. Alerts are tasks: every change that can affect one (budget saved, account connected, sync finished, upload result, lead status, goal changed) re-checks it right away, the job tasks.evaluate every 15 minutes is the fallback. Texts always use the current numbers. An alert whose condition is gone resolves itself (auto_resolved, with reason and time); discrete states (connections, goals, sync) at once, numbers with a band against flickering (budget over: opens at 103 %, resolves below 101 %). The answer also carries resolvedByKind, occurrence, reason and reopenLabel.

RuleTypeWhen
no_leadsproblemNo lead for much longer than usual while visits continue
tracking_downproblemNo events for hours during the day on a site that normally has traffic
cpl_spikeproblemCost per lead of the last 7 days ≥ +50 % against the 7 days before (≥ 3 leads in both)
reporting_failedattentionLeads not reported to an ad platform
cost_sync_staleattentionCosts of an active account not refreshed for 6 hours
search_console_problemattentionThe Search Console connection expired, the property refused access, or the sync failed or is overdue. Closes itself as soon as the connection works again (no 24-hour wait)
budget_over / budget_underattentionFrom day 7: forecast above 103 % / below 85 % of the monthly budget
opportunityopportunityThe top recommendation with high confidence
connect_costssetupPaid visits from a platform without costs
goal_neversetupA goal never reached 7 days after it was created
record_weekinfoMost leads in 12 weeks
traffic_drop / traffic_spikeattention / infoYesterday's visits outside the band of the last 6 same weekdays (median ± 2.5 MAD, expected ≥ 20; a drop also under 70 % of the median), naming the source that moved most. Quiet while tracking is down and in the first days after the measuring start

The mail of traffic_drop shows yesterday, the usual value and the visits without ads side by side, the strongest source, „Verlauf ansehen“ and, when an ad channel moved most, „{Kanal} Kampagne prüfen“. The X3 App pushes it as „Weniger Besuche als üblich“, sharing the daily limit with its own hourly drop detection: at most one drop push per project and day.

Order: problem › attention › opportunity › setup › info, then by money at stake, then age.

Who sees what: viewers and clients see problems, attention (except budget), setup and info. Budget alerts, opportunities and connect_costs are agency-internal: they need ads:read and config:write. Closing, snoozing or reopening (PATCH /v1/alerts/{id}, MCP alerts_update) needs config:write or ads:write.

Organization notices

Some hints concern a person or the whole organization instead of a project. GET /v1/notices (scope analytics:read, signed-in people only) evaluates them live on every read, so they never show stale numbers, and they resolve themselves when the condition is gone. Notices are tasks of scope person or org (Tasks). Each notice has a scope: person notices appear once for the signed-in person, however many organizations they belong to (orgId, orgSlug, orgName are null); org notices appear once per organization.

KeyScopeTypeWhenResolves itself when
connect_aipersoninfoYou have no AI client connected yetyou connect Claude, ChatGPT or another MCP client (OAuth, any organization), or a key you created is used over MCP

A resolved notice comes back when the condition holds again (for example every AI client of yours was removed). Später (snooze, default tomorrow 08:00), Passt nicht (dismiss, stays hidden) and reopen: PATCH /v1/notices/{key} for a personal notice (only for you, every role), PATCH /v1/orgs/{org}/notices/{key} for an organization notice (shared for the organization, needs config:write). Other members keep their own personal notices. The cockpit shows them in Braucht Dich with a link to the connect card (ChatGPT, Gemini and other apps); the same organization notice of several organizations becomes one card („· 5 Kunden“).

Delivery

  • In the app: always.
  • E-mail right away: only problems, at most one mail per project and rule in 24 hours, to members who see that alert type and did not turn it off (Alerts & reports).
  • Weekly digest: Monday 08:00 in each user's time zone – all projects the user sees, numbers with change, what needs them, what was done and what it brought. The only mail that spans organizations.
  • Weekly client report: per organization, to members you choose (POST /v1/orgs/{org}/client-report with preview, send_now or weekly, scope org:admin). Never other clients, portfolio sums or agency-internal alerts; inquiries by first name and initial or "Anfrage #n", never contact data; each recipient gets their language.

Demo projects show alerts but never send mail.