Guide

How to send a daily AppsFlyer report to Slack automatically

A practical, no-fluff guide for performance teams and agencies.

A daily AppsFlyer report in Slack is the highest-leverage fifteen seconds in a UA team's morning — if it's designed as a pulse, not a data dump. This guide covers what belongs in a daily (and what absolutely doesn't), the message anatomy, the thresholds that make it self-triaging, and the build options from webhook-and-script to scheduled platform.

What a daily is for

Pacing and anomalies: is spend on plan, did conversions move abnormally, did anything break overnight. That's it. Cohort metrics, ROAS maturation and strategy questions belong in the weekly — a daily that tries to carry them trains the team to skim past it, which defeats the channel.

The message anatomy

Daily pulse — Tue Jun 9 (yesterday, app TZ) Spend $6,840 · pacing 98% of plan Installs 1,610 (+4% vs 7-day avg) · Purchases 228 (−2%) CPI $4.25 · Cost/purchase $30.00US_ campaigns: spend +31% vs avg — check the new ad set's budget [Open the sheet →]

Five lines: headline, the two volume series vs their 7-day baselines, the two efficiency numbers, exceptions, the link. Anything longer is a report pretending to be a pulse.

The pull behind it

  • Period: yesterday in the app's timezone — the daily that mixes UTC days produces fake anomalies twice a week
  • Master API: spend and installs by campaign for the day
  • Raw Data Pull API: the KPI event (purchases, purchases), deduplicated per user — dailies are exactly where row-counting inflates worst, because re-engagement events cluster
  • Filters as stored: geo, prefix, re-engagement excluded
  • Baselines: trailing 7-day averages computed for the comparison — a daily without baselines is just numbers

Thresholds make it self-triaging

Flag only what crosses a line you chose: spend pacing outside ±15%, volume outside ±25% of the 7-day average, efficiency beyond target. A daily with calibrated flags gets read every day; one that cries wolf gets muted by Thursday.

Build options, honestly

Script + incoming webhook — an AppsFlyer pull (or scheduled export), a formatter, a Slack webhook, a cron. Works; you now own auth refreshes, the dedup logic, timezone handling and the silent-failure problem (a daily that stops arriving looks like a quiet day).

Operations platform — the same pulse as a scheduled run with the guarantees attached: app-timezone resolution, per-user dedup, baselines maintained, loud failure alerts, and the same numbers appended to the Sheet so the pulse and the report can't disagree. (The Slack integration page covers the wiring.)

QA checklist

  • ✓ "Yesterday" verified against the app's timezone setting
  • ✓ The KPI event recounted from raw rows once, with dedup
  • ✓ Thresholds calibrated on two weeks of history before alerting anyone
  • ✓ Failure behavior tested — a broken pull must alert, not skip silently

When not to run a daily

Spend too small to act on daily, or a team that can't change anything intraday anyway. A weekly with good flags beats a daily nobody can respond to.

How Opera runs it

This is a one-line schedule on Opera — same validated pipeline as the weekly, delivered as the pulse above, with the Sheet kept in sync.

"Every weekday at 8am, post yesterday's spend, installs and purchases for US_ campaigns to #growth — flag anything outside the usual range."

See this running on your own reports.A 45-minute workflow audit maps your current process and shows exactly what Opera automates — step by step.

Frequently asked questions

Should the daily include ROAS?
No — revenue hasn't matured at day one, so daily ROAS is noise that trains people to ignore real signals. Keep efficiency to CPI / cost-per-event; save ROAS for the cohort view.
Slack message or Slack + Sheet?
Both, from the same run: the message for the skim, the Sheet for the dig. Generating them separately is how the two eventually disagree.
How do we stop alert fatigue?
Baselines plus thresholds you actually calibrated, and a rule: every flag must name the suspected cause or the cell to check. Flags without next actions get muted.

Watch Opera run a real workflow, end to end.

Three minutes: a plain-language request, a Sheet schema read, an AppsFlyer pull, a previewed append, a Slack summary — then a paused campaign launch.