Overview
The Query API lets you use your own unique queries to fetch the particular pre-aggregated analytics data that you're interested in.
Benefits
The Branch Query API gives you access to the same pre-aggregated analytics data that is displayed in your Branch Dashboard, without needing to access the Dashboard itself.
An individual query is constructed from three types of parameters:
Authentication parameters that control the access to the data.
Data selection keys that define which events are eligible to be counted in the results (e.g. filters).
Result format specifiers that define which results are included in the HTTP response and how the results are returned (e.g. sorting).
Limits
Limitation | Details |
---|---|
Rate Limits | - 5 requests per second |
Max number of rows returned from API | 50,000 |
Max retrievable unique values for a single dimension (e.g. campaigns, ad names, etc.) | 40,000 |
Max number of days that can be queried at a time | 7 days |
Export Window | Rolling 2 year window. |
Specific Dimension Combinations | If you are pulling from SAN |
Try It!
Try out the Query API in your browser, using your Branch data:
We also strongly suggest checking out our Query Recipe Book for use cases and examples related to this API. It has screenshots of Branch Dashboard visualizations alongside the queries you would need to make to pull the same data from the API. Try it for a quick way to get up and running with this API!
Getting Started
Prerequisites
In order to use the Query API, you first need to:
Create a Branch Dashboard.
Enable Universal Ads and start running ad campaigns from your Branch account.
Implement the appropriate Branch SDK into your mobile app (iOS | Android).
Make sure you have the appropriate permissions set on your user account. See the Access section for more.
Access
General Access
To access the Query API, a user must have both Aggregate Data and Export access enabled on their account.
Agency Access
If you work with an agency that runs your advertising campaigns and want to give them access to export the subsequent data, you can provide them with access to the Export API.
To provide an agency team member with access to the Export API:
In the left-hand navigation, under Setup & Testing, click on Account Settings.
On the Account Settings page, click on the Agencies tab.
Expand the agency in question, find the agency team member you want to give access to, hover on the button in the Actions column, and click Edit.
In the Edit Agency Team Member modal:
Under Access Level, check the Export box.
Under Permissions, check the Aggregate Data box.
Add data filters (optional):
Under Data Filters, toggle any necessary data filters on/blue. Exported data will be filtered accordingly.
Click Save.
Agency-Tagged Data
If you do not enable the Only Show Agency-Tagged Data data filter, the Agency Team Member will be able to export aggregate data associated with all of your campaigns, regardless if they are associated with them or not.
Authentication
Calls to the Query API require your Branch Key and Branch Secret. Both your Branch Key and your Branch Secret can be obtained through your Branch Dashboard Account Settings.
Usage
Post Query
Request Info
Export Request
POST /v1/query/analytics
Content-Type: application/json
Host: api2.branch.io
Request Headers
Header | Description | Required |
---|---|---|
| application/json | Yes |
| application/json | Yes |
Request Query Parameters
Parameter | Type | Description | Required |
---|---|---|---|
| String | The Branch Key for the relevant application. | Yes |
| String | The Branch Secret for the relevant application, used for authentication. | Yes |
| Integer | The maximum number of results to return in the response. | No |
| Integer | A pagination parameter that indicates the index of the first result to return in the response. | No |
| String | Value passed for this parameter get returned as a query parameter within the | No |
Request Body Parameters
Parameter | Type | Description | Required |
---|---|---|---|
| Date | A timestamp representing the oldest date to return data for. Timezone of the timestamp is set in your Branch Dashboard configuration. | Yes |
| Date | A timestamp representing the most recent date to return data for. Timezone of the timestamp is set in your Branch Dashboard configuration. | Yes |
| String | The type of event to query for, prefixed with the source. | Yes |
| String | How to count events towards the final result count. | Yes |
| Array of Strings | List of event fields to use as splits for the query. | Yes |
| Array of Strings | An object where each key is a valid | No |
| Boolean | De-dupe unattributed installs caused by duplicate events from non-opt-in users coming from paid ads. | No |
| String | Range of time to roll multiple events into a single result count. | No |
| String | The result key to sort results by. | No |
| String | The direction by which to order the results. | No |
| Boolean | Whether to return result objects where the result count is 0. | No |
Response Info
Response Body Parameters
Parameter | Type | Description |
---|---|---|
| List of Objects | A list of JSON objects that contain result information. |
| Object | A JSON object containing the queried values, for example |
| Date | The date and time when the data related to the |
| Object | A JSON object that includes the total number of results from the query, called |
Example Request & Response
Total Installs
Below is an example of a basic query that pulls total number of installs per day, split by whether attributed
is true
or false
. The number of results is limited to 5.
curl -X POST -H "Content-Type: application/json" -d '{
"branch_key":"<YOUR_BRANCH_KEY>",
"branch_secret":"<YOUR_BRANCH_SECRET>",
"start_date": "2022-03-01",
"end_date": "2022-03-07",
"data_source": "eo_install",
"dimensions": [
"attributed"
],
"enable_install_recalculation": true,
"granularity": "day",
"aggregation": "total_count"
}' "https://api2.branch.io/v1/query/analytics?limit=5"
{
"results": [{
"result": {
"attributed": "false",
"total_count": 44
},
"timestamp": "2022-03-05T00:00:00.000Z"
}, {
"result": {
"attributed": "false",
"total_count": 23
},
"timestamp": "2022-03-07T00:00:00.000Z"
}, {
"result": {
"attributed": "true",
"total_count": 14
},
"timestamp": "2022-03-05T00:00:00.000Z"
}, {
"result": {
"attributed": "false",
"total_count": 12
},
"timestamp": "2022-03-03T00:00:00.000Z"
}, {
"result": {
"attributed": "false",
"total_count": 10
},
"timestamp": "2022-03-02T00:00:00.000Z"
}],
"paging": {
"next_url": "/v1/query/analytics?limit=5&after=5",
"total_count": 13
}
}
See Example Queries for more examples.
Appendix
Dimensions
General Information
Dimension | Description |
---|---|
| Name. |
| Origin of the data. |
| Timestamp of the data. |
| Is the data deep linked? Can be |
| Is the data from desktop? Can be |
| Is the data attributed? Can be |
User Information
Dimension | Description |
---|---|
| User's app store. |
| User's version of the app. |
| User's operating system. |
| User's language. |
| User's platform. |
| User's environment. |
| User's geographical Designated Market Area code. |
| User's country code. |
| User's country. |
| User's region. |
| Is user opted in? |
| User's opt-in status. |
Custom Event Information
Dimension | Description |
---|---|
| Available dimensions for custom event data. |
Click & Impression Source Definitions
Data Source | Description |
---|---|
| Real-time user device-level impressions and ad-views triggered via Impression Tracking Ad Links. |
| Real-time user device-level Branch Link clicks. |
| Combined aggregated data source containing both real-time user device-level impressions as well as SAN ad partner impressions passed to Branch from SAN servers. |
| Combined aggregated data source containing both real-time user device-level Branch Link clicks as well as the SAN ad partner's clicks passed to Branch from SAN servers. |
SAN Ad Partners List:
Facebook
Google Ads
X (formerly Twitter)
Snap
Apple Search Ads
TikTok
Example Queries
Installs Per Day Per OS
This query pulls installs per day and splits the results by OS of the device the user installed on. It limits the number of results to 5.
curl -X POST -H "Content-Type: application/json" -d '{
"branch_key":"<YOUR_BRANCH_KEY>",
"branch_secret":"<YOUR_BRANCH_SECRET>",
"start_date": "2017-12-12",
"end_date": "2017-12-18",
"data_source": "eo_install",
"dimensions": [
"user_data_os"
],
"enable_install_recalculation": true,
"granularity": "day",
"aggregation": "total_count"
}' "https://api2.branch.io/v1/query/analytics?limit=5"
{
"results": [
{
"result": {
"user_data_os": "ANDROID",
"total_count": 144
},
"timestamp": "2017-12-18T00:00:00.000Z"
},
{
"result": {
"user_data_os": "IOS",
"total_count": 142
},
"timestamp": "2017-12-18T00:00:00.000Z"
},
{
"result": {
"user_data_os": "IOS",
"total_count": 191
},
"timestamp": "2017-12-17T00:00:00.000Z"
},
{
"result": {
"user_data_os": "ANDROID",
"total_count": 194
},
"timestamp": "2017-12-17T00:00:00.000Z"
},
{
"result": {
"user_data_os": "ANDROID",
"total_count": 246
},
"timestamp": "2017-12-16T00:00:00.000Z"
}
],
"paging": {
"next_url": "/v1/query/analytics?query_id=CqdBOb&limit=5&after=5",
"total_count": 14
}
}
Unique Click Counts
Below is a more complex query for pulling unique click counts. These counts are split out by 4 different dimensions.
This query also has a filter, which filters out any clicks where last_attributed_touch_data_plus_current_feature
was MOBILE_DEEPVIEWS
or DESKTOP_DEEPVIEWS
.
A maximum of 5 results will be returned, in descending order of unique_count
. Results with days that had 0 clicks will be returned (and not filtered out) because the zero_fill
flag is set to true
:
curl -X POST -H "Content-Type: application/json" -d '{
"branch_key":"<YOUR_BRANCH_KEY>",
"branch_secret":"<YOUR_BRANCH_SECRET>",
"start_date": "2017-12-12",
"end_date": "2017-12-18",
"data_source": "eo_click",
"dimensions": [
"last_attributed_touch_data_tilde_feature",
"last_attributed_touch_data_tilde_channel",
"last_attributed_touch_data_tilde_campaign",
"last_attributed_touch_data_plus_current_feature"
],
"filters": {
"!last_attributed_touch_data_plus_current_feature": [
"MOBILE_DEEPVIEWS",
"DESKTOP_DEEPVIEWS"
]
},
"ordered": "descending",
"ordered_by": "unique_count",
"aggregation": "unique_count",
"zero_fill": true
}' "https://api2.branch.io/v1/query/analytics?limit=5"
{
"results": [
{
"timestamp": "2017-12-12T00:00:00.000Z",
"result": {
"last_attributed_touch_data_tilde_channel": "ads",
"last_attributed_touch_data_tilde_campaign": "Xmas",
"last_attributed_touch_data_tilde_feature": "paid advertising",
"last_attributed_touch_data_plus_current_feature": "ADS",
"unique_count": 750
}
},
{
"timestamp": "2017-12-12T00:00:00.000Z",
"result": {
"last_attributed_touch_data_tilde_channel": "taptica#1",
"last_attributed_touch_data_tilde_campaign": "taptica#1",
"last_attributed_touch_data_tilde_feature": "paid advertising",
"last_attributed_touch_data_plus_current_feature": "ADS",
"unique_count": 723
}
},
{
"timestamp": "2017-12-12T00:00:00.000Z",
"result": {
"last_attributed_touch_data_tilde_channel": "Journeys",
"last_attributed_touch_data_tilde_campaign": "Default Banner",
"last_attributed_touch_data_tilde_feature": "journeys",
"last_attributed_touch_data_plus_current_feature": "MOBILE_JOURNEYS",
"unique_count": 553
}
},
{
"timestamp": "2017-12-12T00:00:00.000Z",
"result": {
"last_attributed_touch_data_tilde_channel": "Apple App Store",
"last_attributed_touch_data_tilde_campaign": null,
"last_attributed_touch_data_tilde_feature": "paid advertising",
"last_attributed_touch_data_plus_current_feature": "ADS",
"unique_count": 432
}
},
{
"timestamp": "2017-12-12T00:00:00.000Z",
"result": {
"last_attributed_touch_data_tilde_channel": null,
"last_attributed_touch_data_tilde_campaign": null,
"last_attributed_touch_data_tilde_feature": "marketing",
"last_attributed_touch_data_plus_current_feature": "QUICK_LINKS",
"unique_count": 201
}
}
],
"paging": {
"next_url": "/v1/query/analytics?query_id=EDdBOb&limit=5&after=5",
"total_count": 143
}
}
Include or Omit Response Objects
When zero_fill
is set to true
, response objects with a total_count
equal to 0 will be returned alongside other results:
{
"branch_key":"<YOUR BRANCH KEY>",
"branch_secret":"<YOUR BRANCH SECRET>",
"start_date": "2022-02-01",
"end_date": "2022-02-01",
"data_source": "xx_click",
"dimensions": [
"last_attributed_touch_data_tilde_advertising_partner_name",
"last_attributed_touch_data_tilde_campaign_id"
],
"ordered": "descending",
"aggregation": "total_count",
"zero_fill": true
}
{
"result": {
"last_attributed_touch_data_tilde_advertising_partner_name": "Google AdWords",
"last_attributed_touch_data_tilde_campaign_id": "78726498102",
"total_count": 1
},
"timestamp": "2022-02-01T00:00:00.000+08:00"
},
{
"result": {
"last_attributed_touch_data_tilde_advertising_partner_name": "Google AdWords",
"last_attributed_touch_data_tilde_campaign_id": "87192837612",
"total_count": 1
},
"timestamp": "2022-02-01T00:00:00.000+08:00"
}
{
"result": {
"last_attributed_touch_data_tilde_advertising_partner_name": "Google AdWords",
"last_attributed_touch_data_tilde_campaign_id": "17384628491",
"total_count": 0
},
"timestamp": "2022-02-01T00:00:00.000+08:00"
}
When zero_fill
is set to false
, response objects with a total_count
equal to 0 are omitted:
{
"branch_key":"<YOUR BRANCH KEY>",
"branch_secret":"<YOUR BRANCH SECRET>",
"start_date": "2022-02-01",
"end_date": "2022-02-01",
"data_source": "xx_click",
"dimensions": [
"last_attributed_touch_data_tilde_advertising_partner_name",
"last_attributed_touch_data_tilde_campaign_id"
],
"ordered": "descending",
"aggregation": "total_count",
"zero_fill": false
}
{
"result": {
"last_attributed_touch_data_tilde_advertising_partner_name": "Google AdWords",
"last_attributed_touch_data_tilde_campaign_id": "78726498102",
"total_count": 1
},
"timestamp": "2022-02-01T00:00:00.000+08:00"
},
{
"result": {
"last_attributed_touch_data_tilde_advertising_partner_name": "Google AdWords",
"last_attributed_touch_data_tilde_campaign_id": "87192837612",
"total_count": 1
},
"timestamp": "2022-02-01T00:00:00.000+08:00"
}