How to build AppsFlyer dashboards in Metabase
AppsFlyer is a mobile measurement and attribution platform tracking installs, in-app events, and campaign ROI across ad networks. Metabase is where you turn that marketing data into shared, trustworthy dashboards. This guide covers two complementary paths: a lightweight MCP + CLI route that pulls live data with the AppsFlyer MCP and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that syncs AppsFlyer daily stats into a database so you can build dashboards anyone can read.
How do you connect AppsFlyer to Metabase?
Most teams combine both routes: use MCP and CLI uploads for a fast first pass, then move recurring marketing reporting to a warehouse-backed model.
Live data in, quick analysis out
Pair the AppsFlyer MCP with the Metabase CLI. Use MCP for live lookups, write a scoped result to CSV, then load it into Metabase as a ready-to-query table and model.
- Quick lookups such as "show me installs by media source and campaign"
- Loading a AppsFlyer export into Metabase in seconds
- Spot-checks and one-off analyses without a warehouse
- Great for exploration, not governed recurring reporting
- Use read-only/scoped credentials wherever the MCP server supports them
- CSV uploads are snapshots — refresh or move to the pipeline for history
Durable dashboards with history
Sync AppsFlyer daily stats and entities into a database or warehouse with a connector, custom pipeline, or API, then point Metabase at it.
- AppsFlyer reporting that marketing leaders depend on
- Joining AppsFlyer data with CRM, revenue, or product data
- Long-run trends for installs by media source and campaign and cost per install and roas by network
- You own the refresh schedule and the rollup grain
- Sync daily aggregates and entities — not raw event streams
- Metric definitions must be consistent across channels and teams
What can you analyze from AppsFlyer data in Metabase?
- Installs by media source and campaign — built from attributed installs and the related in-app events, retargeting conversions, SKAN reports data your sync exposes.
- Cost per install and ROAS by network — built from attributed installs and the related in-app events, retargeting conversions, SKAN reports data your sync exposes.
- Post-install event conversion by cohort — built from attributed installs and the related in-app events, retargeting conversions, SKAN reports data your sync exposes.
- Organic vs. paid install mix — built from attributed installs and the related in-app events, retargeting conversions, SKAN reports data your sync exposes.
- Retention by acquisition source — built from attributed installs and the related in-app events, retargeting conversions, SKAN reports data your sync exposes.
Which AppsFlyer dashboards should you build in Metabase?
Activation funnel
Whether new signups reach the product's value moment.
- Signup-to-activation funnel (funnel)
- Activation rate by signup cohort (line)
- Time to activation distribution (bar)
- Activation by acquisition channel (table)
Engagement and retention
Whether activated users keep coming back.
- Weekly retention cohorts (heatmap or table)
- DAU/WAU/MAU trends (line)
- Feature adoption by segment (bar)
- Stickiness ratio DAU/MAU (line)
Channel quality
Which acquisition sources send users who stay.
- Activation rate by channel (bar)
- Day-30 retention by channel (table)
- CAC vs. LTV by channel (scatter or table)
- Signups by channel by week (stacked bar)
Growth accounting
New, retained, resurrected, and churned users in one view.
- Growth accounting waterfall (bar)
- Net user growth by month (line)
- Churned users and churn rate (combo)
- Quick ratio trend (line)
How do you use the AppsFlyer MCP with the Metabase CLI?
Pair the AppsFlyer MCP with the Metabase CLI for fast, hands-on analysis. MCP is useful for scoped lookups and summarized exports; the Metabase CLI's upload command loads CSV data into Metabase and creates a ready-to-query table and model.
Example workflow
- Ask the MCP server for daily attributed installs for your core activation events.
- Export the result as CSV, keeping stable IDs, channels, campaigns, and dates.
- Run
mb upload csvto load it into Metabase as a table and model, then build questions and dashboards on top.
Be honest about the limits
- MCP lookups are excellent for exploration, not scheduled reporting.
- A CSV upload is a snapshot; refresh it with
mb upload replaceor move to the pipeline for real history. - Daily event rollups and a stable user ID are required for funnels, retention, and activation trends.
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up AppsFlyer MCP and the Metabase CLI?
AppsFlyer MCPofficial
- Transport
- Hosted remote MCP via Streamable HTTP
- Auth
- OAuth, or an AppsFlyer MCP token for automation
- Best for
- Live scoped lookup and export
Metabase CLIofficial
- Install
npm install -g @metabase/cli- Auth
mb auth login- Load data
mb upload csv --file data.csv- Requires
- An uploads database (Admin → Settings → Uploads)
{
"mcpServers": {
"appsflyer": {
"url": "https://mcp.appsflyer.com/auth/mcp"
}
}
}In beta as of mid-2026 — AppsFlyer gates access behind an MCP beta program. It covers what your dashboards can see: campaign performance, SKAN data, and audience lists, following your existing account permissions.
# Install the Metabase CLI
npm install -g @metabase/cli
# Log in (opens your browser; requires Metabase v62+)
mb auth login --url https://your-metabase.example.com
# Load a attributed-installs export — creates a table AND a model
mb upload csv --file appsflyer-attributed-installs.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file appsflyer-attributed-installs.csvCan you generate a AppsFlyer dashboard with AI?
Yes. Use the prompt below with any assistant that can run the AppsFlyer MCP and the Metabase CLI. It works end to end: if AppsFlyer tables already exist in Metabase it analyzes those; otherwise it pulls scoped, summarized data over MCP, loads it with mb upload csv, then builds the dashboard and caveats any metric that needs missing history.
Create a polished Metabase dashboard for AppsFlyer product analytics analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help marketing and growth leaders understand activation, retention, engagement, and which acquisition channels send users who stay from AppsFlyer data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for appsflyer tables and
models). If durable AppsFlyer data is already present — synced from a warehouse
or uploaded earlier — use it and skip to Step 2.
- If nothing is there, pull a scoped, summarized export with the AppsFlyer MCP:
attributed installs, plus in-app events, retargeting conversions, SKAN reports.
Prefer daily aggregates over raw events. Write each result to a CSV,
then load it with the Metabase CLI — run "mb upload csv --file <export>.csv" so
each upload creates a table and a ready-to-query model. Use "mb upload replace
<table-id> --file <export>.csv" to refresh an existing table instead of creating
duplicates.
Step 2 — Inspect before querying:
Do not assume exact table or column names. Inspect available fields, channels,
campaigns, dates, and whether daily history exists before creating trend or
pacing cards.
Important:
- Build on whatever data is present; don't claim Metabase connects natively to
AppsFlyer — it reads a database or CLI-uploaded tables.
- Never try to load raw event or click streams into Metabase; use daily
aggregates, campaign-grain stats, and entity tables.
- Only compute rates (CTR, conversion rate, ROAS, CAC) when both numerator and
denominator exist — and state the attribution model when reporting conversions.
- Exclude test campaigns and internal traffic from headline cards, and keep
currency consistent when spend spans accounts.
- A single CSV is a point-in-time snapshot: only build trend cards if there is a
usable date column or multiple periods have been uploaded.
Dashboard title: AppsFlyer Product Analytics Overview
Sections:
1. Executive summary: Signups last 30 days; Activation rate; WAU; Day-30
retention; Churned users.
2. Activation: Signup-to-activation funnel; activation by cohort and channel.
3. Retention: Weekly cohort retention; DAU/WAU/MAU; stickiness.
4. Channels: Activation and retention by acquisition channel; CAC vs. LTV.
5. Growth accounting: New, retained, resurrected, churned by month.
Filters: Date range, Channel, Campaign, Country, Device, Segment.
Output: Build the dashboard if you have permission; otherwise provide the exact
questions, SQL, model definitions, and layout. Include caveats for any metric
that cannot be calculated from the available data.How do you sync AppsFlyer data into a database or warehouse?
For dashboards that need history and reliability, land AppsFlyer daily stats and entities in a database first, then connect Metabase to that database.
Connector options
- Managed ETL — use a connector when one covers the objects you need.
- Custom pipeline — use the AppsFlyer Pull API for control over grain, fields, and refresh cadence.
- MCP + CSV — use this for quick exploration and one-off slices.
Sync installs and in-app events with the Airbyte AppsFlyer source or Fivetran's connector, or use Data Locker for high-volume delivery straight to BigQuery, Snowflake, or cloud storage — the right path once Pull API row caps start to bite.
Notes
- Decide the rollup grain first (daily per campaign/channel is the workhorse) — it drives warehouse cost and every trend card.
- Land raw entity tables first, then build clean Metabase models on top.
- Normalize user ID, event name, event date, acquisition channel, and plan fields.
How should you model AppsFlyer data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
appsflyer_installs | one row per attributed install | appsflyer_id, install_time, media_source, campaign, adset, country, device_type, is_retargeting |
appsflyer_in_app_events | one row per in-app event | appsflyer_id, event_name, event_time, event_revenue, media_source, campaign |
appsflyer_cohort_daily | one row per media source per install-cohort day | cohort_date, media_source, installs, cost, day_7_retention, day_30_revenue |
Modeling advice
- Build a clean
event_rollupsmodel with common columns across tools, so multi-channel dashboards don't fork definitions. - Separate entity tables (campaigns, audiences, pages) from daily time-series rollups.
- Exclude test campaigns and internal traffic from headline metrics; keep channel and campaign as explicit columns.
- Use stable IDs for campaign, channel, and user joins; display names change.
Which AppsFlyer metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| Activation rate | New users reaching the value moment divided by all signups. | Define activation from behavior, not time in app. |
| Conversion rate | Users completing a step divided by users entering it. | Funnels need a stable user ID across steps. |
| Customer acquisition cost | Spend divided by new customers, joined from ad data. | Pair with LTV per channel for the full picture. |
| Churn rate | Users or accounts lost divided by those at risk in the period. | Retention cohorts explain churn better than one number. |
What SQL powers AppsFlyer dashboards in Metabase?
These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). Adjust table and column names to match your pipeline.
Signups reaching the value moment within 7 days.
SELECT
date_trunc('week', u.signup_at) AS signup_week,
COUNT(*) AS signups,
COUNT(*) FILTER (WHERE u.activated_at IS NOT NULL
AND u.activated_at <= u.signup_at + INTERVAL '7 days') AS activated_7d,
ROUND(
100.0 * COUNT(*) FILTER (WHERE u.activated_at IS NOT NULL
AND u.activated_at <= u.signup_at + INTERVAL '7 days')
/ NULLIF(COUNT(*), 0), 1
) AS activation_rate_pct
FROM users u
GROUP BY 1
ORDER BY 1;A simple cohort retention starting point.
SELECT
date_trunc('week', u.signup_at) AS cohort_week,
COUNT(DISTINCT u.user_id) AS cohort_size,
COUNT(DISTINCT e.user_id) FILTER (
WHERE e.event_date BETWEEN u.signup_at + INTERVAL '7 days'
AND u.signup_at + INTERVAL '14 days'
) AS retained_week_2
FROM users u
LEFT JOIN event_rollups_by_user e ON e.user_id = u.user_id
GROUP BY 1
ORDER BY 1;The engagement headline from event rollups.
SELECT
date_trunc('week', event_date) AS week,
COUNT(DISTINCT user_id) AS weekly_active_users
FROM event_rollups_by_user
WHERE event_date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY 1
ORDER BY 1;