How can we help?

ROI360 cost aggregation overview Premium

  • Updated

At a glance: Learn about methods for advertisers to aggregate and view marketing cost data.

Cost aggregation

ROI360 does the following:

  • Provides aggregate advertising cost data and cost-related lifetime value (LTV) performance metrics. These are available via dashboards and performance reports. The cost-related metrics available include return on investment (ROI), return on ad spend (ROAS), clicks, impressions, campaign ROI, and average effective cost per install (eCPI) over time.
  • Covers advertising costs across all platforms, including mobile apps, web browsers, connected TV (CTV), PCs, and consoles.
  • Supports different cost models used by the media source, for example, cost per install (CPI), cost per action (CPA), cost per click (CPC), and cost per mille (CPM).
  • Records advertising cost by API, Cost Import (CSV file upload), and cost on the attribution link.
  • Enables agencies to access ROI360 cost data for advertisers with an ROI360 subscription.

The following data is available to advertisers without an ROI360 subscription:

Principles of cost data aggregation

This section describes the main principles of aggregating campaign cost data.

Cost aggregation methods

AppsFlyer obtains cost data from media sources using one or more methods. If a media source reports cost through more than one method, then the cost prioritization mechanism determines which data AppsFlyer uses. This prevents cost data from being inflated.

After AppsFlyer processes the data, it shows in UTC time zone (default) or according to your app-specific time zone settings.

Cost aggregation method Cost models supported Data granularity Data freshness Remarks
API* All Level depends on the integration Intraday Data might change after the cost event because AppsFlyer tries to retrieve data up to 7 days back (depending on the media source). This lets AppsFlyer account for retroactive changes made by the media source.
Cost Import (file upload) All Level depends on the file uploaded Up to 4 hours after import You can revert the reported cost and submit corrected data for up to 90 days.
Cost on the attribution link CPI User-level

Minimum: real time

Maximum: Up to 4 hours after the link is clicked

No change possible
* API integrations between media sources and AppsFlyer are by either Cost API or InCost API (never both). The API used and the data granularity provided are media source-dependent.

Cost data availability and reports

The table at the end of this section indicates where cost data is available.

For the purposes of understanding the table, the following explanations apply, unless otherwise indicated in the table remarks:

Cost in the UA view

AppsFlyer classifies campaign cost data as user acquisition (UA) based on matching rules that vary by media source, as shown below.

Media sources Matching rule
Google Ads, DV360, Facebook, TikTok, Apple Search Ads, and Aura AppsFlyer classifies cost as UA if it records at least one install, click, or impression within ±10 days of the install date (the date the media source reports the cost).
All other media sources AppsFlyer classifies cost as UA if it records at least one install, click, or impression on the media source's own processing date. No ±10-day window applies.

Note

This applies to both rows. AppsFlyer bases matches on the media source, campaign ID, and agency.

Cost in the Unified view

The Unified view includes cost data for all campaigns of the selected app, regardless of whether installs, clicks, or impressions exist within ±10 days of the cost reporting date (install date).

Example

The following examples show how the ±10-day window affects where cost appears:

  • If a media source that uses the ±10-day window reports the cost for campaign X on March 15, and campaign X has at least one click, install, or impression between March 5 and March 25, the cost for March 15 appears in UA and in Unified.
    • If no activity exists in that time window, the cost for March 15 appears only in Unified. For media sources that match by processing date only, the same rule applies to March 15 itself, with no ±10-day window.

Cost data availability and reports table

Reporting method View/data type Campaign name change support Remarks
Overview dashboard
  • UA
  • Unified
Yes Retargeting view doesn't display cost. Cost for retargeting displays in the Unified view.
Activity dashboard UA Yes  
Cohort dashboard
  • UA
  • Unified
Yes
  • Retargeting view doesn't display cost
  • This Unified data is available only for campaigns with at least one install, click, or impression recorded within ±10 days of the cost reporting date (install date) for Google Ads, DV360, Facebook, TikTok, Apple Search Ads, and Aura. For all other media sources, this data is available only for campaigns with activity recorded on the same processing date as the cost.
Cohort API
  • UA
  • Unified
Yes This Unified data is available only for campaigns with at least one install, click, or impression recorded within ±10 days of the cost reporting date (install date) for Google Ads, DV360, Facebook, TikTok, Apple Search Ads, and Aura. For all other media sources, this data is available only for campaigns with activity recorded on the same processing date as the cost.
SKAN dashboard SKAN No This dashboard displays SKAdNetwork (SKAN) installs, along with cost data for all installs (including non-SKAN installs).
SKAN Aggregated Performance API SKAN No This API displays SKAN installs, along with cost data for all installs (including non-SKAN installs).
Pivot dashboard UA No  
Master API UA No  
Custom dashboard UA No  
Cost ETL Unified Yes All available cost data displays.
Aggregated Pull API UA No  
Push API Raw click data (not aggregated) Not relevant  
Raw data Pull API Raw click data (not aggregated) Not relevant  
Data Locker Raw click data (not aggregated) Not relevant Data Locker Cohort doesn't support cost.

Note

The following points apply to the table:

  • Data granularity can vary by dashboard/report type. The Cost ETL reporting tool contains the complete dataset. This includes campaign hierarchy details (media source, campaign name, ad, adset, and the dimensions available from the media source, including geo, channel, site ID, and keywords).
  • Cost data reported on the attribution link is available in raw data reports.
  • If a media source doesn't support campaign name changes, both campaign names display: one with attribution data and one with cost data. Neither campaign name includes the complete data picture.

Cost prioritization mechanism

For a given media source, cost can be provided by more than one method. To avoid cost inflation, a campaign cost prioritization mechanism decides which cost data appears in the platform. AppsFlyer gives priority according to the aggregation method. The priority from lowest to highest is: Cost on the attribution link > Cost API > Cost Import.

Diagram showing the cost prioritization order: Cost on the attribution link, then Cost API, then Cost Import

The cost prioritization mechanism impacts aggregate data reports and dashboards. It doesn't impact attribution link cost data in raw data reports, as noted above.

Considerations:

  • The priority mechanism works at the campaign level. This means that if you get two cost inputs for one campaign via different mechanisms, then they compete and the higher priority wins for the entire campaign.
    • On any day, when there's cost data for a specific app and media source (or agency) via Cost API, AppsFlyer ignores cost data on the attribution link.
  • If you change cost aggregation methods, the change has a retroactive impact. Historical aggregate cost data can change.
  • A change to the cost aggregation method affects agency-generated traffic the same way. This includes both transparent and non-transparent agencies.

Example

Scenario: A media source reports cost on the attribution link, but you decide to enable the media source's Cost API.

Result: AppsFlyer aggregates cost from both the attribution link and the Cost API. Because the Cost API has priority, AppsFlyer ignores the cost on the attribution link.

Cost split

Some media sources report the campaign cost data without an associated app ID. When this happens, AppsFlyer completes the app ID(s) using engagement and attribution data.

AppsFlyer matches apps based on those associated with the campaign's clicks, impressions, and conversions within a ±10-day window around the reported cost date.

If the app completion process results in multiple matched apps, AppsFlyer distributes the campaign cost across those apps as follows:

Proportional split (by conversions)

If conversions (installs, reattributions, and re-engagements) exist on the reported cost date, AppsFlyer splits the cost proportionally based on each app's number of conversions.

Example: If the total cost on Day 1 is $100, and the campaign drives 60 installs on iOS and 40 installs on Android, then:

  • iOS: $60
  • Android: $40

Note

The proportional (conversion-based) split applies only when the conversion granularity available in attribution exactly matches the granularity the media source reports for its cost data. When the two only partially match, AppsFlyer can't map the cost to each app's conversions, so it applies the equal split across the matched apps instead.

Equal split (no conversions)

If no conversions exist on the reported cost date, AppsFlyer splits the cost equally across the matched apps.

Example: If the total cost on Day 1 is $100 and the campaign has impressions but no conversions on that date, then:

  • iOS: $50
  • Android: $50

Limitations

The following limitations apply to this feature:

  • AppsFlyer supports this feature for Google, TikTok, and DV360 cross-platform and web-to-app (W2A) campaigns (campaigns with a campaign objective that is different from mobile/app).
  • Google Performance Max (PMAX) campaigns: The proportional (conversion-based) split doesn't apply. Google's API doesn't report Ad ID or Geo granularity for PMAX campaigns, so AppsFlyer splits the cost equally across the matched apps, regardless of the number of conversions per app. At the campaign level, when all platforms (iOS, Android, etc.) are selected in the dashboard, the total cost still matches Google's reported cost.

Additional information

List of media sources supporting the Cost API

The downloadable table below lists all media sources supporting Cost API, with the data granularity available for each:

  • Dimensions
  • Supported features and their characteristics
  • Metrics (as reported by the media sources)

Download file: CSV, XLSX

Changing campaign names

AppsFlyer displays campaigns using the campaign ID as the key.

To avoid display anomalies, make sure that:

  • Each campaign has a unique campaign ID.
  • You don't use the same campaign name with different campaign IDs.

Learn more about campaign name changes

Costs without installs

Why do I see cost data with no installs? This occurs when a media source provides cost at a higher level in the hierarchy (for example, the campaign level) but provides performance information (clicks and installs) at a lower level in the advertising hierarchy (for example, the ad adset level).

AppsFlyer completes the cost data for missing dimensions from an upper-level hierarchy. This guarantees a full view of the cost data at any level and minimizes internal discrepancies.

Example

An advertiser runs a campaign. The advertising hierarchy is as follows:

  • Media source: media_eg
  • Campaign: campaign_eg
  • Adsets: adset_1, adset_2

The following table shows information relating to the media source.

Hierarchy: All Media Sources > media_eg

Campaign Cost Installs
campaign_eg $100 100
campaign_yy $200 1000
campaign_zz $300 2000

Drilling down into campaign_eg shows the adset level.

Hierarchy: All Media Sources > media_eg > campaign_eg

Adset Cost Installs
None $100  
adset_1 N/A 30
adset_2 N/A 70

In this case, AppsFlyer provides the $100 cost of campaign_eg at the campaign level. When drilling down to the adset level, which in this case is the lowest level of the hierarchy, AppsFlyer can't break down the cost by adset.

To overcome this, AppsFlyer breaks down the cost from the campaign level and displays it in a separate row. In this case, the adset displays as None, and the installs field stays blank.

Cost currency conversion

If the campaign cost currency provided by the media source differs from the app-defined currency on the platform, AppsFlyer converts the cost to the app-defined currency as follows:

  • AppsFlyer gets the rates from openexchangerates.org.
  • AppsFlyer updates exchange rates hourly for data up to seven days back.
  • AppsFlyer performs currency conversions using the last known rate.

Traits and limitations

Trait Description
Agencies
  • When transparent agencies run campaigns, advertisers can see costs displayed in dashboards and reports, providing a unified view. Learn more about cost data availability and reports
  • If an advertiser ends their relationship with an agency and the agency has cost configured for the app, AppsFlyer continues to pull cost data even if the advertiser disables the agency permissions at the app level. To prevent this, the advertiser must ask the agency to deactivate their cost integration in AppsFlyer before disabling the agency permissions.
  • For some media sources, agencies must contact the advertiser to activate the integration, and the AppsFlyer UI prompts them to do so. For these media sources, agencies and advertisers must make sure that when the media source sends data, it includes the af_prt parameter, required for agency cost attribution.
  • For X Ads, cost data for SKAN-only campaigns (those with only SKAN installs and no "regular" installs) isn't available to agencies. The advertiser must set up the cost integration. Only the advertiser can view the data.
API data freshness
  • Intraday (except for Moloco)
  • Mintegral data is available via the API the following day, approximately 4 hours after the previous day ends. For example, if the event occurred on Day 1, cost data is available by Day 2, at approximately 4:00.
Campaign name changes Ad spend data displays the most recent reported campaign name. This applies to aggregate data only, not to the raw data itself.
Time zone If a media source supports only one time zone, and that time zone differs from the one set in your app settings, AppsFlyer uses the media source's time zone.
CTV, PC, and console platforms

For apps on these platforms, send cost data via Ad Spend Ingestion using the upload-by-email method.

You can also send data via API for Google, Meta, or TikTok for the following platforms:

  • Steam
  • Native PC
  • Smart Cast
  • Windows Phone
  • Tizen
  • Quest
Cross-platform Cost data isn't available for cross-platform clicks and impressions, meaning the impression/click might occur on one platform and the app install on another.
Out-of-store apps Cost data from Mintegral isn't available for out-of-store apps (apps from platforms other than Google Play and App Store).
Geo Geo/country breakdown isn't available for Mistplay bundled campaigns (campaigns targeted to several countries). For such campaigns, geo displays as N/A.
Smadex Dashboards and Cost ETL reports might show cost and attribution data separately. This occurs when Smadex includes additional elements (such as an inventory ID) in the site ID value.
Apple Search Ads (ASA) For SKAN-only reporting, ASA cost data isn't available in the SKAN dashboard or the Pull API because Apple doesn't include campaign-level data in SKAN postbacks. However, cost data is available in single-source-of-truth (SSOT) reports via AppsFlyer's classic integration.
Cost data dimension character limit

For the media sources listed below, the following dimensions must not exceed the specified character lengths. If you don't comply with these limits, AppsFlyer excludes the dimension values from the report.

  • app_id: up to 100 characters
  • publisher: up to 250 characters
  • partner: up to 250 characters
  • campaign: up to 250 characters
  • campaign_id: up to 250 characters
  • adset: up to 250 characters
  • adset_id: up to 250 characters
  • ad: up to 250 characters
  • ad_id: up to 250 characters
  • site_id: up to 250 characters
  • site_name: up to 250 characters
  • channel: up to 250 characters
  • ad_account: up to 250 characters
  • ad_account_name: up to 250 characters

The limitations apply only to the following media sources:

  • mintegral_int
  • moloco_int
  • applovin_int
  • liftoff_int
  • aura_int
  • tiktokglobal_int
  • pinterest_int
  • vungle_int
  • iossearchads_int
API Cost data availability

AppsFlyer displays API cost data only for customers with an active ROI360 asset. If ROI360 is deactivated, cost data from API sources becomes unavailable, and the dashboard shows only CPI-based cost data.

Mintegral: ad-level granularity To get cost reporting with ad-level granularity from Mintegral, each ad account requires the following ad network permissions: Sub/Package × Creative dimension.