> For the complete documentation index, see [llms.txt](https://help.branch.io/llms.txt).

# Query API

The Query API is an HTTP API that you can use to programmatically query pre-aggregated analytics.

[Read the Query API overview](https://help.branch.io/apidocs/query/overview.md)

## Post query

`POST https://api2.branch.io/v1/query/analytics`

This endpoint lets you query dashboard analytics without having to access Branch.

### Parameters

- `aggregation` (enum, required) — How to count events toward the final result count. When using unique_count, each event is only counted if an event by that user hasn't already been seen. One of `unique_count`, `total_count`, `revenue`, `cost`, `cost_in_local_currency`.
- `branch_key` (string, required) — The Branch Key of the app you're pulling analytics information for.
- `branch_secret` (string, required) — The Branch Secret of the app, used for authentication.
- `data_source` (enum, required) — The type of event to query for. The values are valid Branch data sources. Here are the descriptions: * `eo_impression` - Real-time user-device level impressions/ad-views triggered via Impression Tracking Ad Links. SAN Ad Partner's impressions aren't included in this data source. * `eo_click` - Real-time user-device level link clicks recorded through user clicks on the Branch Links. SAN Ad Partner's clicks aren't included in this bucket. * `xx_impression` - Combined aggregated data source containing both real-time user-device level impressions and the SAN Ad Partner's impressions passed to Branch systems from SAN servers. * `xx_click` - Combined aggregated data source containing both real-time user-device level clicks and the SAN Ad Partner's clicks passed to Branch systems from SAN servers. One of `eo_impression`, `eo_click`, `xx_impression`, `xx_click`, `eo_web_to_app_auto_redirect`, `eo_branch_cta_view`, `eo_open`, `eo_install`, `eo_reinstall`, `eo_web_session_start`, `eo_pageview`, `eo_commerce_event`, `eo_custom_event`, `eo_content_event`, `eo_dismissal`, `eo_user_lifecycle_event`, `cost`.
- `dimensions` (array of enum, required) — List of event fields to use as splits for the query. Result counts are returned grouped with other events that have matching values for each key provided in dimensions. One of `name`, `origin`, `timestamp`, `deep_linked`, `from_desktop`, `attributed`, `last_attributed_touch_type`, `last_attributed_touch_data_tilde_tags`, `last_attributed_touch_data_tilde_secondary_publisher`, `last_attributed_touch_data_plus_current_feature`, `last_attributed_touch_data_plus_via_features`, `last_attributed_touch_data_tilde_campaign`, `last_attributed_touch_data_tilde_advertising_partner_name`, `last_attributed_touch_data_tilde_feature`, `last_attributed_touch_data_tilde_creative_name`, `last_attributed_touch_data_plus_web_format`, `last_attributed_touch_data_tilde_creative_id`, `last_attributed_touch_data_tilde_ad_name`, `last_attributed_touch_data_tilde_ad_id`, `last_attributed_touch_data_tilde_campaign_id`, `last_attributed_touch_data_tilde_placement`, `last_attributed_touch_data_tilde_stage`, `last_attributed_touch_data_tilde_channel`, `last_attributed_touch_data_tilde_ad_set_name`, `last_attributed_touch_data_tilde_ad_set_id`, `last_attributed_touch_data_tilde_keyword`, `last_attributed_touch_data_tilde_keyword_id`, `last_attributed_touch_data_tilde_journey_id`, `last_attributed_touch_data_tilde_view_name`, `last_attributed_touch_data_tilde_view_id`, `last_attributed_touch_data_tilde_customer_secondary_publisher`, `last_attributed_touch_data_tilde_customer_ad_set_name`, `last_attributed_touch_data_tilde_customer_ad_name`, `last_attributed_touch_data_tilde_customer_keyword`, `last_attributed_touch_data_tilde_customer_placement`, `last_attributed_touch_data_tilde_customer_sub_site_name`, `last_attributed_touch_data_tilde_customer_campaign`, `last_attributed_touch_data_tilde_marketing_title`, `last_attributed_touch_data_dollar_marketing_title`, `last_attributed_touch_data_dollar_3p`, `user_data_app_store`, `user_data_app_version`, `user_data_os`, `user_data_language`, `user_data_platform`, `user_data_environment`, `user_data_geo_dma_code`, `user_data_geo_country_code`, `user_data_country`, `user_data_geo_region_en`, `user_data_opted_in`, `user_data_opted_in_status`, `last_cta_view_data_tilde_ad_name`, `last_cta_view_data_tilde_secondary_publisher`, `last_cta_view_data_tilde_campaign`, `last_cta_view_data_tilde_advertising_partner_name`, `last_cta_view_data_tilde_feature`, `last_cta_view_data_tilde_ad_set_name`, `last_cta_view_data_tilde_ad_set_id`, `last_cta_view_data_tilde_campaign_id`, `last_cta_view_data_tilde_creative_name`, `last_cta_view_data_tilde_creative_id`, `last_cta_view_data_plus_via_features`, `last_cta_view_data_dollar_3p`, `last_cta_view_data_tilde_tags`, `last_cta_view_data_plus_web_format`, `last_cta_view_data_tilde_channel`, `last_cta_view_data_tilde_ad_id`, `last_cta_view_data_tilde_stage`, `days_from_last_attributed_touch_to_event`, `days_from_last_cta_view_to_event`, `event_data_product_categories`, `event_data_custom_param_1`, `event_data_custom_param_2`, `event_data_custom_param_3`, `first_event_for_user`, `customer_event_alias`.
- `end_date` (string, required) — The last timestamp (exclusive) to return data for. No events that triggered after the end_date will be counted in the query results. The time zone of the timestamp is set in your Branch configuration. Note that end_date can't be more than 7 days after the start_date.
- `start_date` (string, required) — A timestamp representing the oldest date to return data for. The time zone of the timestamp is set in your Branch configuration. Note that start_date can't be earlier than 2017-10-14.
- `after` (integer, query) — A pagination parameter indicating the index of the first result to return in the response. For example, with 100 results returned, setting "after" to 50 would return elements 51-100. 
- `enable_install_recalculation` (boolean) — This field relates to result formatting. Dedupe unattributed installs caused by duplicate events from non-opt-in users coming from paid ads.
- `filters` (object)
- `filters.<key>` (array of string) — Any additional key. Values are passed through as provided.
- `granularity` (enum) — This field relates to result formatting. Range of time to roll multiple events into a single result count. For example, with a value of "day", the counts for each day are returned independently, where "all" would return a single count for the entire time range. One of `all`, `day`.
- `limit` (integer, query) — Maximum number of results to return in the response. If granularity is set to day, Branch will pull results up to the limit for each day. So if limit is set to 1000 and 5 days' worth of data is queried with granularity=day, this API will return up to 5000 results. 
- `ordered` (enum) — This field indicates the sorting order of the output. One of `ascending`, `descending`.
- `ordered_by` (enum) — This field indicates which key of the result to sort results on. It only supports 1 sort key as of now. Possible values are any element of query "dimensions" or the value of "aggregation" in the query. One of `name`, `origin`, `timestamp`, `deep_linked`, `from_desktop`, `attributed`, `unique_count`, `total_count`, `revenue`, `cost`, `cost_in_local_currency`.
- `query_id` (string, query) — Returned as a query parameter on the "paging" object's next_url and previous_url. Locks the last event to count for a query, so new events that occur between queries aren't added to the results (prevents the count from changing over time). 
- `zero_fill` (boolean) — Whether to return result objects where the result count was 0. If set to false, results with count = 0 will be omitted from the response. If the result is empty and zero_fill=true, fields will be loaded with null/0 to provide a schema. 

### Responses

- `200` — Status of aggregate export.
- `400` — Bad request—typically an invalid or missing credential or parameter.
- `429` — Rate limit exceeded—reduce request frequency and retry.

### Returns

Status of aggregate export. Returns `400` and `429` on failure — see the response panel for the error shape.

### Example request

```bash
curl 'https://api2.branch.io/v1/query/analytics' \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
    "branch_key": "key_live_xxxx",
    "branch_secret": "secret_live_xxxx",
    "start_date": "2023-05-01",
    "end_date": "2023-05-07",
    "data_source": "eo_install",
    "aggregation": "total_count",
    "dimensions": [
      "attributed"
    ],
    "filters": {
      "!last_attributed_touch_data_plus_current_feature": [
        "MOBILE_DEEPVIEWS",
        "DESKTOP_DEEPVIEWS"
      ]
    },
    "granularity": "all",
    "ordered_by": "attributed",
    "ordered": "descending"
  }'
```

### Example responses

`200`

```json
{
  "results": [
    {
      "result": {
        "attributed": "true",
        "total_count": 129
      },
      "timestamp": "2023-05-01T00:00:00.000-08:00"
    },
    {
      "result": {
        "attributed": "true",
        "total_count": 125
      },
      "timestamp": "2023-05-04T00:00:00.000-08:00"
    },
    {
      "result": {
        "attributed": "false",
        "total_count": 95
      },
      "timestamp": "2023-05-04T00:00:00.000-08:00"
    }
  ],
  "paging": {
    "next_url": "/v1/query/analytics?limit=5&after=3",
    "total_count": 14
  }
}
```

`400`

```json
{
  "error": {
    "message": "Authentication failed.",
    "code": 400
  }
}
```

`429`

```json
{
  "error": {
    "code": 429,
    "message": "Rate limit reached."
  }
}
```
