# Metrics API

The Metrics API has two main purposes:
1. Integrating with your visualization tools
2. Data Activation - using your metrics data as inputs to other processes

All API calls require `x-api-token` Authentication.

In order to retrieve metric results, you'll need to know some identifiers for your filters.

---

### Retrieving filters

!!!
The `/filter-definitions` endpoint requires an API key with `Read` permissions. [Learn More](/api-keys#permissions)
!!!!

+++ `GET` Filter Definitions 
```
GET https://app.aggregations.io/api/v1/filter-definitions
```

**Example Response**

```
status: 200 OK
```

```json
[{
		"id": "abc123456",
		"filter": "@.eventName =='AppOpen' && @.environment == 'Production'",
		"groupings": [
			"@.device.type",
            "@.app.version"
		],
		"groupingItems":[
			{
				"grouping": "@.device.type", 
				"alias": "Device Type"
			},
			{
				"grouping": "@.app.version",
				"alias": null
			}
		],
		"intervalType": "MINUTE",
		"intervalCount": 15,
		"name": "App Opens by Version & Device Type",
		"organizationId": "zzZyx123",
		"aggregations": [
			{
				"id": 1,
				"calculations": [
					"APPROX_COUNT_DISTINCT"
				],
				"calculationField": "@.userId",
				"subFilter": null,
				"name": "Unique Users"
			},
			{
				"id": 2,
				"calculations": [
					"SUM",
					"MAX",
					"MIN",
					"AVG",
					"PERCENTILES"
				],
				"calculationField": "@.notificationCount",
				"subFilter": "@.notificationCount > 0",
				"name": "Notifications Count (for users with notifications)"
			},
			{
				"id": 3,
				"calculations": [
					"COUNT"
				],
				"calculationField": null,
				"subFilter": null,
				"name": "Open Count"
			}
		]
	}]
```
+++

This provides you with the relevant details you'll need to retrieve metrics.

#### Groupings

You may notice both `groupings` and `groupingItems` have similar information - `groupings` was the original field before adding in the ability for individual groupings to be aliased. It is there for backwards compatibility only, `groupingItems` should be used going forward.

In this example, an alias has been set to make `@.device.type` a little easier to use when visualizing results.

---

### Metric Results

!!!
The `/metrics/results` endpoint requires an API key with `Read` permissions. [Learn More](/api-keys#permissions)
!!!!

+++ `POST` metrics/results
```
POST https://app.aggregations.io/api/v1/metrics/results 
```

| Parameter                  | Required                     | Type                                                                              | Description                                                                                                                                                                 |
| -------------------------- | ---------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| filterId <sup>f</sup>                  | ✅                            | `string`                                                                        | `id` of filter|
| startTime                  | ✅                            | `string`                                                                        | Start time (UTC) of desired range as ISO-8601 formatted string|
| endTime                    | ✅                            | `string`                                                                        | End time (UTC) of desired range as ISO-8601 formatted string|
| aggregationId <sup>f</sup>              | ✅                            | `int`                                                                           | `id` of desired aggregation|
| calculation <sup>f</sup>                | ✅                            | `string`                                                                        | Calculation to be performed, one of `COUNT`, `SUM`, `MIN`, `MAX`, `PERCENTILES`, `APPROX_COUNT_DISTINCT` (and must be present on the corresponding aggregation) |
| percentile                 | if `PERCENTILES`           | `float`                                                                         | Number > 0 & <= 1, of percentile desired.|
| limit                      | if `limitType` is supplied | `int`                                                                           | Number of items to retrieve per  interval, if excluded all results will return.|
| limitType                  | if `limit` is supplied     | `string`                                                                        | Whether to take the `TOP` or `BOTTOM` items per interval|
| includeIncompleteIntervals | | `boolean`                  | If `false` then intervals not yet complete will be excluded, with a 10s buffer. Default is `true` |
| groupingFilters | | `groupingFilterOption[]`| Grouping filters or aggregations to perform (see below) |
| recalculatedInterval | | `interval` | Indicates how to re-calculate / rollup aggregations from initial interval. (see below)|

::: {.caption}
An <sup>`f`</sup> above indicates a value you should retrieve from the `/filter-definitions` call
:::

##### `interval` Object {#re-calculate}

{.compact}
| Parameter | Required | Type |Description |
| --- | --- | --- | --- |
type | ✅ | `string` | One of `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `YEAR` |
frequency | ✅ | `int` | The value representing how frequent you want the rollups. 

For example, if you have an hourly metric and you want to roll up to the day, your `recalculatedInterval` would be:

```json
{
	"type": "DAY",
	"frequency": 1
}
```

!!!warning
When using the `recalculatedInterval` option, you must ensure the requested rollup is greater or equal to the interval of the filter (you cannot turn a filter that is `daily` into `hourly`). Read more about intervals in the [filter docs.](/metrics/filters#intervals)
!!!

+++

---

### Grouping Filters 

The `groupingFilters` property defines how to handle any filtering / aggregating on individual groupings.

It is an array of objects like the following: 
```json
{
    "grouping": "@.device.type",
    "filters": ["ios", "android"],
    "returnGroupingValues": true
}
```
Parameter | Required    | Type     |Description 
--- | ---- | --- | ---| ---
grouping | ✅ | `string` | the grouping value as defined on your filter.
filters | | `string[]` | the list of values to be filtered as an array.  `["$__agg"]` will result in all values being aggregated. 
returnGroupingValues | ✅ | `boolean` | Whether or not to return grouping values in the response, or simply apply the filters to the provided groupings.

When considering your groupings, you can do 4 things:
1) Do not include a grouping key, the system will automatically include any defined groupings on the filter. This applies to (2-4) as well, if you do not specify behavior for a certain grouping, the default behavior is to include it.
2) Include a grouping, filtered to certain values, For example, the following value will include all `@.app.version` values where `@.device_type` is `android`
```json
[{"grouping":"@.device.type", "filters": ["ios"], "returnGroupingValues":true}]
``` 
3) Include a grouping, filtered to certain values, but do not return the filtered values. For example, the following value will include all `@.app.version` values where `@.device_type` is `android` but the response won't include a key for `@.device.type`
```json
[{"grouping":"@.device.type", "filters": ["ios"], "returnGroupingValues":false}]
``` 
4) Disregard a grouping by aggregating it. For example, the following will aggregate results per `@.app.version` only.
```json
[{"grouping":"@.device.type", "filters": ["$__agg"], "returnGroupingValues":false}]
```
!!!info
NOTE: `$__agg` as a filter value takes precedence over `returnGroupingValues`.
!!!

!!! dark
Reminder, our `@.device.type` field has been aliased to `Device Type` - which is returned in the metric results.
!!!

**Example Responses**
+++ (1) No `groupingFilters`
```json
[
	{
    "dt": "2023-10-16T19:30:00Z",
	"value": 9,
	"groupings": {
		"Device Type": "ios",
        "@.app.version":"1.0.0"
	    }
    },
	{
    "dt": "2023-10-16T19:30:00Z",
	"value": 5,
	"groupings": {
		"Device Type": "android",
        "@.app.version":"1.0.0"
	    }
    },
    {
	"dt": "2023-10-16T19:45:00Z",
	"value": 53,
	"groupings": {
		"Device Type": "ios",
        "@.app.version":"1.0.0"
        }
    },
    {     
	"dt": "2023-10-16T20:25:00Z",
	"value": 56,
	"groupings": {
		"Device Type": "ios",
        "@.app.version":"1.0.0"
	    }
    }
]
```
+++ (2) Specific `groupingFilters`
```json
[
	{
    "dt": "2023-10-16T19:30:00Z",
	"value": 9,
	"groupings": {
		"Device Type": "ios",
        "@.app.version":"1.0.0"
	    }
    },
    {
	"dt": "2023-10-16T19:45:00Z",
	"value": 53,
	"groupings": {
		"Device Type": "ios",
        "@.app.version":"1.0.0"
        }
    },
    {     
	"dt": "2023-10-16T20:25:00Z",
	"value": 56,
	"groupings": {
		"Device Type": "ios",
        "@.app.version":"1.0.0"
	    }
    }
]
```
+++ (3) Specific `groupingFilters`, No Return
```json
[
	{
    "dt": "2023-10-16T19:30:00Z",
	"value": 9,
	"groupings": {		
        "@.app.version":"1.0.0"
	    }
    },
    {
	"dt": "2023-10-16T19:45:00Z",
	"value": 53,
	"groupings": {		
        "@.app.version":"1.0.0"
        }
    },
    {     
	"dt": "2023-10-16T20:25:00Z",
	"value": 56,
	"groupings": {		
        "@.app.version":"1.0.0"
	    }
    }
]
```
+++ (4) Aggregate `groupingFilters`
```json
[
	{
    "dt": "2023-10-16T19:30:00Z",
	"value": 14,
	"groupings": {		
        "@.app.version":"1.0.0"
	    }
    },	
    {
	"dt": "2023-10-16T19:45:00Z",
	"value": 53,
	"groupings": {		
        "@.app.version":"1.0.0"
        }
    },
    {     
	"dt": "2023-10-16T20:25:00Z",
	"value": 56,
	"groupings": {		
        "@.app.version":"1.0.0"
	    }
    }
]
```
+++

---

### Rate Limits

The `/metrics/results` endpoint is limited to 150 requests every 10s per organization. If you need a limit increase, please [contact us](https://aggregations.io/contact?subject=Metrics%20API%20Rate%20Limit%Increase) us to discuss your usecase. 
