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.
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:
To get the Metrics API key go to Organization settings and after go to the Metrics API tab.
$ 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 querygranularity
defines how the metric gets aggregated across the time dimension (e.g. byday
,week
orall
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:
- Make sure that the interval is available to query (check data availability).
- Understand what metrics are available via the API.
- Get an idea of the what query type to use and possible filters to get the best result.
- 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"
}
]
}