Skip to main content

Overview

What is possible with the Metrics API?

The Metrics API enables you to programmatically query your games and fetch KPIs relevant for your studio. While it is possible to get game specific data from the GameAnalytics tool, the Metrics API provides new capabilities such as building BI dashboards to compare performance across games or specific user groups.

Metric data is aggregated by time and dimension. Metrics API supports most dimensions and event filters that are available in the GameAnalytics dashboards.

PRO Tier

The Metrics API is only available by subscribing to GameAnalytics Pro.

Metrics API use cases

Custom business intelligence reporting

The most popular use is creating bespoke BI reports & dashboards for an organization or game, to enable simple tracking of the metrics most relevant to the team. For instance, studios may track their global traffic, but also look in greater depth at a certain country or region. Others may look in greater detail at a certain metric - such as having reports that split user sessions by geo-location.

Health monitoring across titles

Reviewing every metric, for every game, every day can be time consuming. Getting access to key metrics like retention programmatically, and verifying that daily/weekly/monthly change is within certain parameters (e.g. +/- 10%), is the easiest way to monitor your portfolio for outliers, and to have the peace of mind that all your games are doing well at a given time.

Combining metrics across tools

When tools are fit for purpose, it makes sense to combine data to get the best overview. Want to see your retention and new users alongside CPI and app store ranking, for all your live titles? An in-house dashboard that combines data from our Metrics API with data from your attribution and ASO provider is likely to do the trick.

Get in touch with us to learn more about the Metrics API and different pricing options.

Data Availability

The data is available with a soft real-time guarantee, availability of which is checked once in an hour (e.g. the first request returns data in the latest available time interval, which is updated in an hour after the initial call). Metrics API gives the flexibility to query and retrieve the time when this data becomes available.

Integration

Metrics API provides users a way to get different data projections of the collected events across multiple games on an organization level.

Once the collected events have been processed, the service would be able to help to get a view on the games performance using a set of metrics such as ARPU, retention, session length, revenue and many others. The full list of currently supported metrics is available via metrics endpoint:

info

To get the Metrics API key go to Organization settings and after go to the Metrics API tab. Metrics API key

$ curl -H X-API-Key:<API KEY> https://metrics.gameanalytics.com/metrics/v1/metrics

[
"arpu",
"arppu",
"conversion",
"conversion_ft",
"converting_users",
"event_count",
"installs_ratio",
"new_users",
"paying_users",
"retention_retro",
"returning_users",
"revenue",
"session_length",
"session_unique",
"user_unique",
...
]

Authentication

For successful authentication service expects metrics API key provided via X-API-key HTTP header.

Example:

GET /metrics/v1/dimensions HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: close
Host: metrics.gameanalytics.com
User-Agent: HTTPie/2.1.0
X-API-Key: ek5KV6aMSl87QAFGGFAQ78lSMa6VK5ke

Request limits

Metrics API enforces requests limits per organization level. 429 error code is returned when one of the limits is breached.

For the majority of the endpoints - Metrics API allows at least 5 requests per second.

In case of hitting limits due to too many simultaneous requests, exponential backoff should be applied to the rate of requests.

Some requests can lead to big response sizes, or slower response times, due to a high number of combinations included in the response, especially when using split queries. If this happens, a workaround can be to divide the query into multiple ones (for example, by fetching groups of games per query instead of all at once).

Metrics

Each metric has a dedicated endpoint. For example /metrics/v1/metrics/arppu for ARPPU metric and /metrics/v1/metrics/session_length for session length.

To retrieve the metric the majority of the metrics endpoints accept a POST request with a payload that would look similar that what can be seen below:

{
"interval": "2020-07-01/P1W",
"granularity": "day",
"query": {
"type": "group",
"dimension": "country_code",
"limit": 100
}
}

Where:

  • interval is ISO-8601 interval that defines the time range to run the query
  • granularity defines how the metric gets aggregated across the time dimension (e.g. by day, week or all where all datapoints gets aggregated into a single bucket).
  • query specifies a kind of a query along with its parameters to execute to retrieve the metric. The example above would return the top 100 countries of the requested metric.

Please read the specific metrics endpoint documentation to see all available parameters.

Query types

Generally each metric can be retrieved using one of the following query, type of which is specified via type field in the query object.

Group Query

Group query returns a sorted set of results for the values in the provided dimension according to the given criteria. One might think of a group query as a "GROUP BY" query where the result is aggregated by a single dimension. group queries would typically be faster than split queries.

The example below would return the top 3 countries with the highest ARPPU for 1st of August 2020:

{
"interval": "2020-08-01/P1D",
"granularity": "day",
"query": {
"type": "group",
"dimension": "country_code",
"limit": 3
}
}

Result:

{
"result": [
{
"result": [
{
"arppu": 896.64,
"country_code": "GB",
"paying_users": 1,
"total_revenue": 89664
},
{
"arppu": 4.16,
"country_code": "US",
"paying_users": 1,
"total_revenue": 416
},
{
"arppu": 2.99,
"country_code": "CN",
"paying_users": 2,
"total_revenue": 598
}
],
"timestamp": "2020-08-01T00:00:00.000Z"
}
]
}
Split Query

Split query returns a list of objects with the values aggregated by the 2 specified dimensions. Roughly speaking one might think of a split query as a group query where the result is aggregated by 2 dimensions.

To have a picture on ARPPU split by country and platform the following query might be used:

{
"interval": "2020-09-01/P1D",
"granularity": "day",
"query": {
"type": "split",
"dimensions": ["country_code", "platform"]
}
}

Which returns a list of objects, aggregated by country and platform pairs for the time period specified in the query (1st of September 2020):

{
"result": [
{
"event": {
"arppu": 16273.37,
"country_code": "US",
"paying_users": 2,
"platform": "android",
"total_revenue": 3254674
},
"timestamp": "2020-09-01T00:00:00.000Z",
"version": "v1"
},
{
"event": {
"arppu": 1302.8600000000001,
"country_code": "US",
"paying_users": 5,
"platform": "ios",
"total_revenue": 651430
},
"timestamp": "2020-09-01T00:00:00.000Z",
"version": "v1"
},
{
"event": {
"arppu": 299.97,
"country_code": "UZ",
"paying_users": 1,
"platform": "android",
"total_revenue": 29997
},
"timestamp": "2020-09-01T00:00:00.000Z",
"version": "v1"
},
{
"event": {
"arppu": 1206.86,
"country_code": "YE",
"paying_users": 1,
"platform": "android",
"total_revenue": 120686
},
"timestamp": "2020-09-01T00:00:00.000Z",
"version": "v1"
}
]
}
Timeseries Query

Timeseries queries returns a specified metric with no aggregation by any dimension. Each object is aggregated based on time dimension only.

The following example shows how to get average revenue per paying user for 3 days starting from 1st of August 2020:

{
"interval": "2020-08-01/P3D",
"granularity": "day",
"query": {
"type": "timeseries"
}
}

The returned objects are bucketed with a granularity of a day and the metric is calculated based on time aggregation solely:

{
"result": [
{
"result": {
"arppu": 16.472987341772154,
"paying_users": 3555,
"total_revenue": 5856147
},
"timestamp": "2020-08-01T00:00:00.000Z"
},
{
"result": {
"arppu": 7.300213114754098,
"paying_users": 3660,
"total_revenue": 2671878
},
"timestamp": "2020-08-02T00:00:00.000Z"
},
{
"result": {
"arppu": 6.5728080229226356,
"paying_users": 4188,
"total_revenue": 2752692
},
"timestamp": "2020-08-03T00:00:00.000Z"
}
]
}
Exceptions

There are some exceptions from the query types. Some of the metrics can't be retrieved with group query (e.g. conversion).

Typically this limitation is caused by the nature of the metric itself. Such metrics would imply aggregation per game.

Such metrics would usually provide a way to use group query (along with other query types) for a particular game. In the specification the query would have a Game prefix (e.g. GameConversionQuery):

{
"game": "2923",
"granularity": "day",
"interval": "2020-08-01/P1W",
"query": {
"type": "group",
"dimension": "country_code",
"limit": 100
}
}

Alternatively, if it's necessary to split the result by game, one might use by game query. Note that the query type won't be available for a client as the request implies aggregation by game. In the specification such query type would have a suffix ByGameQuery (e.g. ConversionByGameQuery):

{
"interval": "2020-08-01/P1W",
"granularity": "all",
"split_by": "country_code"
}

Examples

The common flow of the generic use case should follow the next steps:

  1. Make sure that the interval is available to query (check data availability).
  2. Understand what metrics are available via the API.
  3. Get an idea of the what query type to use and possible filters to get the best result.
  4. Complete the result with information about games and studios in the response.

Check data availability

Using the interval endpoint, check if the data for the interval of interest is available to query:

curl -HX-API-Key:<API KEY> https://metrics.gameanalytics.com/metrics/v1/interval

Service should return the time boundaries of the data available to query:

"2020-06-14T00:00:00.000Z/2020-09-14T00:00:00.000Z"

If the data is not within the time boundaries, you might need to wait until it gets processed by the backend.

Explore the data

Supported dimensions

Using the dimensions endpoint get an idea of what dimensions the metrics can be aggregated on:

curl -HX-API-Key:<API KEY> https://metrics.gameanalytics.com/metrics/v1/dimensions

Service always returns the latest version of the supported list of dimensions. Example:

[
"game_id",
"country_code",
"platform",
"is_paying",
"is_converting"
// ...
]
Dimensions values

To get an idea of all possible dimension values submitted in a given time interval by games. This might be necessary if the query has to be refined to get the precise metrics result in a specific set.

Using dimension values endpoint list the values submitted in the provided time interval:

curl -HX-API-Key:<API KEY> 'https://metrics.gameanalytics.com/metrics/v1/dimensions/platform?interval=2020-08-01/P1M'
{
"dimension": "platform",
"values": ["android", "windows"]
}

Available games

It might be handy to have a view on a performance of a set of games under a specific studio.

If there are plenty of games and studios, it might be necessary to limit the list of games to certain studios that have any data sent in the given interval:

$ curl -HX-API-Key:<API KEY> 'https://metrics.gameanalytics.com/metrics/v1/studios?interval=2020-08-01/P1M'

[
{
"id": "238393",
"name": "Manc Ave"
},
// ...
]

Having the studio id the service then could be asked for all the games which submitted any events in the given interval:

$ curl -HX-API-Key:<API KEY> 'https://metrics.gameanalytics.com/metrics/v1/games?interval=2020-08-01/P1M&studios=238393'

[
{
"id": "3833679",
"title": "Frontnite"
},
{
"id": "83858202",
"title": "Pups vs Dragons"
},
// ...
]

The game ids are then could be used to either limit metrics to refine the search or to complete the metrics result by looking up the titles of the games from the response.

Get the metric

Once you know the metric that is in your interest get the value using flexible filtering and aggregation based on time and dimensions:

cat <<EOF |
{
"interval": "2020-08-01/P5D",
"granularity": "all",
"filter": {
"or": [
{"game_id": "3833679"},
{"platform": "windows"}
]
},
"query": {
"type": "split",
"dimensions": [
"game_id",
"platform"
]
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/new_users

Which in this example would get the number of new users for the period of 5 days from 1st of August 2020 for all games on windows platform and for any platform for the game with id "83689":

{
"result": [
{
"event": {
"game_id": "83689",
"new_users": 3449361,
"platform": "android"
},
"timestamp": "2020-08-01T00:00:00.000Z",
"version": "v1"
},
{
"event": {
"game_id": "83689",
"new_users": 576973,
"platform": "windows"
},
"timestamp": "2020-08-01T00:00:00.000Z",
"version": "v1"
},
{
"event": {
"game_id": "29284",
"new_users": 1,
"platform": "windows"
},
"timestamp": "2020-08-01T00:00:00.000Z",
"version": "v1"
}
]
}

Use cases

List highest-grossing games in a country

If a country code that one has interest in is known (GB in this example), then it's easy to get the top 3 of the game with the highest revenue for 1st of August using the flowing query:

cat <<EOF |
{
"interval": "2020-08-01/P1D",
"granularity": "day",
"filter": {
"country_code": "GB"
},
"query": {
"type": "group",
"dimension": "game_id",
"limit": 5
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/revenue

The result would be comprised of games and revenue for the specified day along with the auxiliary information:

{
"result": [
{
"result": [
{
"event_count": 19,
"game_id": "3959346",
"mean": 14.503157894736843,
"sum": 275.56,
"sum_cents": 27556.0
},
{
"event_count": 9,
"game_id": "3395936",
"mean": 11.847777777777777,
"sum": 106.63,
"sum_cents": 10663.0
},
{
"event_count": 26,
"game_id": "3985343",
"mean": 3.4899999999999998,
"sum": 90.74,
"sum_cents": 9074.0
}
],
"timestamp": "2020-08-01T00:00:00.000Z"
}
]
}

User retention per game split by country

To get the view of the percentage of users who showed up again 7 days after installing the game use the retention_retro metric endpoint:

cat <<EOF |
{
"interval": "2020-08-01/P1D",
"since_days_ago": 7,
"split_by": "country_code"
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/retention_retro

Which would show every game with returning users along with the retention percentage split by the country code as in the example below:

{
"result": [
{
"result": {
"country_code": "ID",
"game_id": "939282",
"retention": 0.07584264855239627
},
"timestamp": "2020-08-01T00:00:00Z"
},
{
"result": {
"country_code": "FR",
"game_id": "939282",
"retention": 0.10570188062186688
},
"timestamp": "2020-08-01T00:00:00Z"
},
// ...
{
"result": {
"country_code": "ID",
"game_id": "23929338",
"retention": 0.2498167752126883
},
"timestamp": "2020-08-01T00:00:00Z"
},
{
"result": {
"country_code": "FR",
"game_id": "23929338",
"retention": 0.05284202444356853
},
"timestamp": "2020-08-01T00:00:00Z"
}
// ...
]
}

Ads

The Ads metrics can provide a view on your players' ad behaviour. This section is intended to help to understand how to request one of the most common performance numbers regarding ads.

At the moment Ads metrics originates from two possible data sources:

  • Ad event.
  • Impression event (collected from different ad networks such as MoPub and Fyber).

You can read more about integration with Ad event and impression event.

Metrics API provides numerous Ad related metrics including number of impressions & clicks, top Ad placements, top network placements and Ad revenue.

Ad Impressions

This metric shows the number of times Ads were shown in a game over the specified time frame:

cat <<EOF |
{
"granularity": "day",
"interval": "2020-12-01/P2D",
"query": {
"dimension": "country_code",
"limit": 3,
"type": "group"
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/ad_impressions_count

Which lists the number of shown Ads in a game grouped by country:

{
"result": [
{
"result": [
{
"ad_impressions_count": 520150,
"country_code": "US"
},
{
"ad_impressions_count": 508736,
"country_code": "MX"
},
{
"ad_impressions_count": 448401,
"country_code": "BR"
}
],
"timestamp": "2020-12-01T00:00:00.000Z"
},
{
"result": [
{
"ad_impressions_count": 507126,
"country_code": "US"
},
{
"ad_impressions_count": 501301,
"country_code": "BR"
},
{
"ad_impressions_count": 451321,
"country_code": "MX"
}
],
"timestamp": "2020-12-02T00:00:00.000Z"
}
]
}
Ad type

To get the Ad impression number grouped by ad type one can use the following query:

cat <<EOF |
{
"granularity": "day",
"interval": "2020-12-01/P2D",
"query": {
"dimension": "ad_type",
"limit": 3,
"type": "group"
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/ad_impressions_count

Which shows the type of the Ads:

{
"result": [
{
"result": [
{
"ad_impressions_count": 3144579,
"ad_type": "interstitial"
},
{
"ad_impressions_count": 558424,
"ad_type": "rewarded_video"
}
],
"timestamp": "2020-12-01T00:00:00.000Z"
},
{
"result": [
{
"ad_impressions_count": 3031312,
"ad_type": "interstitial"
},
{
"ad_impressions_count": 536933,
"ad_type": "rewarded_video"
}
],
"timestamp": "2020-12-02T00:00:00.000Z"
}
]
}

The Ads of types video, playable, offer_wall or banner could also be seen here if the game has integration with these Ad types as well.

Ad action

To get a breakdown of the action types based on data from the ads events the query can be configured to group the result by ad_action dimension as follows:

cat <<EOF |
{
"granularity": "day",
"interval": "2020-12-01/P2D",
"filter":{
"and": [
{"category": "ads"}
]
},
"query": {
"dimension": "ad_action",
"limit": 5,
"type": "group"
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/event_count

The response should be able to tell the total number of ads shown and clicked in the provided date range with a specified granularity:

{
"result": [
{
"result": [
{
"ad_action": "failed_show",
"event_count": 232958376
},
{
"ad_action": "request",
"event_count": 5341350
},
{
"ad_action": "show",
"event_count": 3703003
},
{
"ad_action": "clicked",
"event_count": 1668764
}
],
"timestamp": "2020-12-01T00:00:00.000Z"
},
{
"result": [
{
"ad_action": "failed_show",
"event_count": 227230279
},
{
"ad_action": "request",
"event_count": 5144202
},
{
"ad_action": "show",
"event_count": 3568245
},
{
"ad_action": "clicked",
"event_count": 1690330
}
],
"timestamp": "2020-12-02T00:00:00.000Z"
}
]
}
Ad network impressions (MoPub, Fyber)

Metrics of such type would be able to show the number of times Ads were shown in games via ad network (e.g. MoPub or Fyber) as well as the revenue from the ads over a provided period of time.

timeseries query can be used to get the number of times the Ads were shown for the provided period:

cat <<EOF |
{
"granularity": "day",
"interval": "2020-12-01/P3D",
"query": {
"limit": 10,
"type": "timeseries"
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/ilrd_id_unique

The example above returns a number of unique impressions that is grouped by time with a granularity of a day:

{
"result": [
{
"result": {
"ilrd_id_unique": 54071
},
"timestamp": "2020-12-01T00:00:00.000Z"
},
{
"result": {
"ilrd_id_unique": 47965
},
"timestamp": "2020-12-02T00:00:00.000Z"
},
{
"result": {
"ilrd_id_unique": 45325
},
"timestamp": "2020-12-03T00:00:00.000Z"
}
]
}
Top network placements

To get the top network placements based on impressions events from ad networks the impressions could be grouped accordingly as follows:

cat <<EOF |
{
"granularity": "day",
"interval": "2020-12-01/P2D",
"query": {
"dimension": "ilrd_network_name",
"limit": 3,
"type": "group"
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/ilrd_id_unique

The result will be split with day granularity and show top network names by number of impressions:

{
"result": [
{
"result": [
{
"ilrd_id_unique": 17044,
"ilrd_network_name": null
},
{
"ilrd_id_unique": 11668,
"ilrd_network_name": "admob_native"
},
{
"ilrd_id_unique": 8239,
"ilrd_network_name": "applovin_sdk"
}
],
"timestamp": "2020-12-01T00:00:00.000Z"
},
{
"result": [
{
"ilrd_id_unique": 16699,
"ilrd_network_name": null
},
{
"ilrd_id_unique": 10669,
"ilrd_network_name": "admob_native"
},
{
"ilrd_id_unique": 7684,
"ilrd_network_name": "vungle"
}
],
"timestamp": "2020-12-02T00:00:00.000Z"
}
]
}
Top ad units for revenue

This query could help to find the most popular ad units based on revenue data from ad networks.

cat <<EOF |
{
"granularity": "day",
"interval": "2020-12-01/P2D",
"query": {
"dimension": "ilrd_network_name",
"limit": 3,
"type": "group"
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: <API KEY>" \
--data-binary @- \
https://metrics.gameanalytics.com/metrics/v1/metrics/ilrd_revenue

The result contains the count of impressions for each of these ad unit as well as the amount of revenue attributed to each of them:

{
"result": [
{
"result": [
{
"event_count": 418422,
"ilrd_adunit_name": "Interstitial",
"mean": 0.00015009160345297347,
"sum": 6280.162890000007,
"sum_cents": 628016.2890000007
},
{
"event_count": 62060,
"ilrd_adunit_name": "Rewarded",
"mean": 0.00033676365613922023,
"sum": 2089.9552500000004,
"sum_cents": 208995.52500000002
},
{
"event_count": 939375,
"ilrd_adunit_name": "Banner",
"mean": 6.934801517658019e-6,
"sum": 651.4379175650001,
"sum_cents": 65143.79175650001
}
],
"timestamp": "2020-12-01T00:00:00.000Z"
},
{
"result": [
{
"event_count": 391713,
"ilrd_adunit_name": "Interstitial",
"mean": 0.0001528559424885057,
"sum": 5987.565980000003,
"sum_cents": 598756.5980000003
},
{
"event_count": 55280,
"ilrd_adunit_name": "Rewarded",
"mean": 0.0003798841298842256,
"sum": 2099.9994699999993,
"sum_cents": 209999.94699999993
},
{
"event_count": 849544,
"ilrd_adunit_name": "Banner",
"mean": 7.448732017705969e-6,
"sum": 632.802559325,
"sum_cents": 63280.25593249999
}
],
"timestamp": "2020-12-02T00:00:00.000Z"
}
]
}