Guide

The manual AppsFlyer-to-Sheets workflow that's costing you a day a week

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

Every team that reports AppsFlyer data in Google Sheets runs some version of the same manual loop. Written down honestly, it's eleven micro-steps — and seeing them itemized is usually what makes a team finally fix it. This guide is that itemization: the loop, where the time goes, the error taxonomy, and what to fix first even if you stay manual.

The loop, itemized

  1. Open AppsFlyer; pick the app — remembering iOS and Android are separate apps
  2. Set the date range to "last week" — in whichever timezone the export decides that means
  3. Export aggregate performance (spend, installs) for the overview
  4. Export or query the in-app events report for the conversions you actually count
  5. Filter to the right countries — in the spreadsheet, after export
  6. Filter to the right campaigns — by prefix, by eye
  7. Deduplicate event rows to unique users — or, more often, forget to
  8. Reshape columns to match the report's order
  9. Find this month's section in the Sheet; paste into the next empty row
  10. Recompute CAC/CPI/ROAS; drag formulas down; fix formatting
  11. Write the Slack summary; answer "is this right?" twice

Timed across teams we've audited, the loop runs 45–90 minutes per app per week — more with reconciliation, double with both OSes.

The error taxonomy

  • Grain errors — event rows counted as users (purchases inflated 10–30% on re-engagement-heavy weeks); installs counted as customers
  • Boundary errors — the export's timezone vs the app's; Monday bleeding into Sunday; an ISO week that isn't
  • Scope leaks — an unprefixed retargeting campaign sliding into a UA-only report
  • Placement errors — last week pasted over the week before; a formula column overwritten by values
  • Window drift — this week's export run with different attribution settings than last week's, breaking the trend

None of these announce themselves. Most are discovered by a client.

If you stay manual: the three fixes that pay immediately

  1. A definitions block in the workbook — event names, prefixes, geos, timezone, dedup rule. The contract every export follows.
  2. ISO weeks, app timezone, always — write it at the top of the tab; it ends the boundary arguments.
  3. SKAN in separate columns — iOS postbacks beside, never inside, the attributed series.

These cost an hour once and remove the worst recurring errors.

What the automated version replaces

The whole loop becomes: schema re-validated → Master API pull for spend/installs → Raw Data Pull API for event-level conversions, deduplicated per user → filters applied as stored (geo, prefix, event, re-engagement excluded) → previewed append into the detected anchor → summary posted. Same report, ~4 minutes, identical logic every week.

Example: the row that gets appended

Week Spend Installs Purchases CPI CAC
Jun 8–14 $22,400 11,480 1,610 $1.95 $13.91

The interesting part isn't the row — it's that the purchases count is deduplicated, scoped to US_ campaigns and geo = US, and computed the same way it was in March.

QA checklist (manual or automated)

  • ✓ Recount one event-counter KPI from raw rows, deduplicating by user ID
  • ✓ Tie spend out against the AppsFlyer dashboard for the exact range
  • ✓ Confirm the week's boundaries in the app's timezone
  • ✓ Check that SKAN never entered the attributed columns

When the manual loop is actually fine

One app, one geo, no event-counter KPIs, and a fortnightly cadence — the loop is 20 minutes and automation is over-engineering. The moment you add markets, prefixes or weekly cadence, the math flips.

How Opera runs it

This exact workflow — both APIs, the filters, the dedup, the anchored append — is AppsFlyer reporting automation.

"Update this week's report with installs, CPI and CAC by country from AppsFlyer."

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

Why do my purchase counts differ from a colleague's?
Almost always dedup or scope: one of you counted event rows vs unique users, or included re-engagement, or used a different prefix list. The definitions block exists to end this.
Aggregate export vs raw events — which do I need?
Both, for different jobs: aggregate (Master API) for spend and installs; raw events (Raw Data Pull API) whenever the KPI counts a specific event per user.
How long should this take once automated?
Minutes per run, unattended — with the human time shifting to reviewing the preview diff and writing commentary.

Start from a clean AppsFlyer reporting structure.

Grab the free template — installs, events, CAC, CPI, ROAS and reconciliation columns — then let Opera keep it current.