Pull API aggregate data

At a glance: Use URIs to get your AppsFlyer aggregate reports in CSV files.


 Are you looking for Pull API raw data?

Pull API raw data

Pull API aggregate data characteristics

  • Reports return as CSV files.
  • Data freshness rates are the same as the equivalent report on the Export Data page and Overview dashboard page. Consider that cost can update with a delay of several hours and this depends on the partner providing the cost data. 
  • Filter by options available: Media source and date range.
  • Additional capabilities in Pull API are:
    • Ability to filter by attribution touch type
    • Selectable timezone 
  • Pull API is suited to use by account users and BI developers;
    • Account users get reports by pasting URIs in their browser. The URI templates are available in the Dashboard.  Go to Integration > API access.
    • BI developers get reports by embedding the URIs in scripts. 

Example URI template TemplateURL_us-en.jpg

Aggregate performance reports available via Pull API

Category  UA Retargeting* Protect360
Partners (media source)

Partners by date



Geo by date report

* For retargeting reports, add the &reattr=true to the URI. 

 Related reading:


Term Description
Pull API

Solution for downloading CSV reports using URIs.

API call or call 

Sending the URI to AppsFlyer by pasting it in the browser address bar or by using scripts.

  • Uniform resource identifier similar to a web address (URL) containing the report specification.
  • Template URIs are available on the API page in the Dashboard.

Guide for account users

About URI templates

  • URI templates available in the dev hub are populated with the app ID and report type.
  • They have placeholders for from and to dates which you must edit.
  • The portion of the URI to the right of the question mark (?) contains parameters. Each parameter begins with an ampersand (&). Parameters are used to set filters, specify additional fields to be included, currency, and timezone. For example, in aggregate reports to limit (filter by) a specific media source, use the media_source parameter: &media_source=facebook
  • To get a better understanding of Pull API, complete the tutorial that follows.

Getting your first Pull API report tutorial

Before you begin:

To download a report from dev hub: 

  1. Go to the AppsFlyer dev hub API reference.


  2. Select a report type from the left-hand menu.
    For example, Raw data reports (non-organic)Installs. 
    See the table below for a list of all report types.

  3. Fill in all the required fields 
  4. The URI template displays on the right. 
  5. Copy the URI by clicking on the copy icon.
  6. Open a new tab in your browser, and paste the URI.
  7. Click <Enter> to send the API call. 
    The report downloads.
Report Description Refresh rate
Raw data reports (non-organic)
Installs Records non-organic installs. The record is generated when a user opens the app for the first time.
In-app events Records the events performed by users.
Uninstalls Records when a user uninstalls the app.
Records users who after uninstalling the app, engage with a UA media source and reinstall the app during the re-attribution window. Real-time
Raw data reports (organic)
Organic Installs
Records when the app is opened by a user for the first time.
Organic in-app events
Records details about events performed by users.
Organic uninstalls
Records users uninstalling the app.
Organic reinstalls
Records ad revenue for users attributed to a retargeting media source during the re-engagement window.
Ad revenue raw data
Attributed ad revenue
Records ad revenue for users attributed to a media source. Daily
Organic ad revenue Records ad revenue for users not attributed to a media source. Daily
Protect360 fraud
Installs Records installs identified as fraudulent and therefore not attributed to any media source. Real-time
Post-attribution installs Records in-app events from fraudulent installs and therefore not attributed at all. Real-time
In-app events Records in-app events identified as fraudulent by Protect360. Daily
Post-attribution in-app events Records in-app events for installs identified as fraudulent after being attributed to a media source or judged fraudulent without regard to the install itself. Daily
Clicks Records clicks performed by users blocked by Protect360. Daily
Blocked install postbacks Records copies of postbacks sent to a media source resulting in a blocked install. Real-time
Install postbacks Records install events generated when a user opens the app for the first time. Daily
In-app event postbacks Records in-app event postbacks sent to the media source. Daily
Retargeting in-app event postbacks Records in-app events users performed during the re-engagement window. Real-time
Retargeting conversions postbacks Records in-app events users performed during the re-engagement window. Real-time

Aggregate data Pull API parameters

Aggregate report URI and parameters

Aggregate URI mandatory parameters

Parameter Description
api_token API bearer authorization token.
  • The date range consists of a fromand to parameter. The range is the LTV (install) date range.
  • Format: yyyy-mm-dd, 
  • Example: 2010-01-01 or 2010-01-01
to End date. As for from

Aggregate data optional filtering and display parameters excluding Protect360 reports

Parameter Description

Use to limit (filter) to a specific media source.

  • Example:media_source=facebook

Set this parameter as shown in the example to get view-through attribution (VTA) KPIs. 

Example: attribution_touch_type=impression


Currency of revenue and cost.

Aggregate Pull API reports always use the app-specific currency. 


Get retargeting conversions data.

  • [Default] If false, user acquisition data (UA) campaigns returns.
  • If true, retargeting conversion returns.
  • Example:reattr=true

[Default] Data returns using UTC.

  • Template URIs are populated with the timezone parameter set to the app-specific time zone. 
  • [Default] If the parameter is not sent, data returns using UTC.
  • If you sendtimezone=[Joda-Time], data returns using the app-specific time zone.

Notes about selecting timezones

  • Joda-Time time zone format takes into account daylight saving time.
  • The Joda-Time value must be identical to the value in the app settings page. For example, if the timezone setting is Paris, the timezone value in the Pull API URL should be timezone=Europe%2fParis.
  • Pulling data in the selected time zone is only available from the date when the time zone setting was made. Any data prior to the date of the change uses UTC as the timezone. 

Google Ads filtered report


Facebook filtered report

Optional parameters for Protect360 reports
Parameter Description
  • Ge the Protect360 URI from the dashboard.
  • Modify the URI as described here. 

To filter the report by a specific media source use the pidparameter. For example, to get the data of abc_net, pid=abc_net.


Selects the timezone used to return data.

If timezone is not sent, data is returned using UTC.

Templates including the timezone parameter. 

Example: timezone=preferred: Use to get data using the app-specific timezone.


 Protect360 parameters are the same in Pull API and Master API. 

View-through attribution (VTA) KPIs

  • To get the VTA KPIs, add the parameter attribution_touch_type=impression to the Pull API aggregate report URI as detailed in the example.
  • You can use the parameter with any of the aggregate reports available. Just copy the URI from the user interface, and append the parameter.
  • You can also add the &media_source parameter to limit the report to a specific media source as depicted in the example that follows.
  • Some VTA KPIs, like clicks, impressions, and cost APIs, don't have values associated with them and display the value N/A instead. 
Example Example URI
VTA only  https://hq.appsflyer.com/export/{app_id}/partners_report/v5?from=yyyy-mm-dd&to=yyyy-mm-dd&attribution_touch_type=impression

VTA and media source


Pull API for developers

Principles of implementation


Familiarize yourself with the Pull API guide for account users.


  • For each report type available, there is a template URI in the dev hub. Select a report type from the left-hand menu.
  • You modify the template to get the data you need, for example, by setting date ranges and filter by parameters.
  • The parameters for raw data and aggregate data reports differ and are detailed in the report sections.
Pull API basics


Path parameters


  • App identifier as found in AppsFlyer.
  • Insert the app ID exactly as found in AppsFlyer.
  • Prefix iOS apps with id


  • Defines the type of report. The list of reports and the associated URIs are in the dashboard. Go to Integration > API access. 
HTTP method


Mandatory query parameters
Parameter Description
Example URI

GET 'https://hq.appsflyer.com/export/app_id/installs_report/v5? from=2020-01-01?&to=2020-01-10&api_token=api_token&currency=preferred


api_token: Pull API token for authentication

Other parameters

Parameters differ depending 


URI call example includes additional parameters: 


Example scripts

Integrate Pull API into scripts to retrieve data.

  • As needed, edit the scripts in terms of report type, date range, and filters. 
  • These examples use the install report.
JavaNode JSPythonC#PHP
import okhttp3.*;

import java.io.BufferedWriter;
import java.io.FileWriter;

import java.util.concurrent.TimeUnit;

public class PullApi {
  public static void main(String[] args){

    String appID = "<APP_ID>";
    String reportType = "<REPORT_TYPE>";
    String from = "<FROM_DATE>";
    String to = "<TO_DATE>";
    String requestUrl = "https://hq.appsflyer.com/export/" + appID + "/" + reportType + "/v5?api_token=" + apiToken + "&from=" + from + "&to=" + to;

    OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)


    Request request = new Request.Builder()
        .addHeader("Accept", "text/csv")

    try {
      Response response = client.newCall(request).execute();

      if(response.code() != 200) {
        if(response.code() == 404) {
          System.out.println("There is a problem with the request URL. Please make sure it is correct");
        else {
          assert response.body() != null;
          System.out.println("There was a problem retrieving the data: " + response.body().string());
      } else {
        assert response.body() != null;
        String data = response.body().string();
        BufferedWriter writer;

        writer = new BufferedWriter(new FileWriter(appID + "-" + reportType + "-" + from + "-to-" + to + ".csv"));
    } catch (Exception e) {

Additional information

Traits and limitations

Trait Comments 
API token type required AppsFlyerAdmin_us-en.pngV2.0 token
Ad network access N
Agency access Y
Agency transparency Y
App-specific currency Y
App-specific timezone Y
Cost Cost data is for UA campaigns only; not for retargeting or inactive campaigns (campaigns without any installs).
Data freshness Continuous
Historical data Y
Non-organic data Y
Organic data Y
Rate limitations


Size limitations
  • API calls return a max. of 200K rows.
  • If a report has exactly 200K rows, then assume rows are missing.
  • Make multiple API calls, using from/to parameters that include the time of day.  

Note! Pull API for raw data support 1M rows. Aggregate data reports are limited to 200K rows. 

Campaign name changes Pull API reports don't support campaign name changes

API error codes and troubleshooting

Error codes and solutions
Status Code Symptom/message Solution
OK 200 Empty CSV file
  • additional_fields  appears more than once in the URI
  • Ensure that both from and to dates have the format yyyy-mm-dd



No API token found in the URI

Bad request


Raw Reports historical lookback is limited to 90 days

Use to and from to limit the date range to 3 months or less.

Bad request


Your API calls limit has been reached for the given report type



Supplied API token is invalid 

Ask an admin for the current token.


Account may be suspended

Log in to the dashboard and check the account status. 

Not found


AppsFlyer 404 error message page displays

  • Ensure that the app id is correct. iOS apps must start with id.
  • The token doesn't match the app. Are you using the correct token?