Skip to content

Revenue metrics in APIv2 #571

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 58 additions & 15 deletions docs/stats-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ toc_max_heading_level: 4

import { ApiV2Example, ExamplesTip } from '../src/js/apiv2-example.tsx';
import { Required, Optional } from '../src/js/api-helpers.tsx';
import { getExampleCode } from '../src/js/examples.tsx';
import { getExampleCode, EXAMPLE_RESPONSE_META } from '../src/js/examples.tsx';
import CodeBlock from '@theme/CodeBlock';
import { SiteContextProvider } from '../src/js/sites.tsx';

Expand Down Expand Up @@ -75,18 +75,49 @@ Metrics represent values to be calculated with the query.

Valid metrics are:

| Metric name | Description |
| --- | --- |
| `visitors` | The number of unique visitors |
| `visits` | The number of visits/sessions |
| `pageviews` | The number of pageview events |
| `views_per_visit` | The number of pageviews divided by the number of visits. Returns a floating point number. |
| `bounce_rate` | Bounce rate percentage |
| `visit_duration` | Visit duration in seconds |
| `events` | The number of events (pageviews + custom events). When filtering by a goal, this metric corresponds to "Total Conversions" in the dashboard. |
| `percentage` | The percentage of visitors of total who fall into this category: Requires: dimension list |
| `conversion_rate` | The percentage of visitors who completed the goal. Requires: dimension list passed, an event:goal filter or event:goal dimension |
| `group_conversion_rate` | The percentage of visitors who completed the goal with the same dimension. Requires: dimension list passed, an event:goal filter or event:goal dimension |
| Metric name | Type | Description | Requirements |
| --- | --- | --- | --- |
| `visitors` | `int` | The number of unique visitors | |
| `visits` | `int` | The number of visits/sessions | |
| `pageviews` | `int` | The number of pageview events | |
| `views_per_visit` | `float` | The number of pageviews divided by the number of visits. | |
| `bounce_rate` | `float` | Bounce rate percentage | |
| `visit_duration` | `int` | Visit duration in seconds | |
| `events` | `int` | The number of events (pageviews + custom events). When filtering by a goal, this metric corresponds to "Total Conversions" in the dashboard. | |
| `percentage` | `float` | The percentage of visitors of total who fall into this category: Requires: dimension list | Requires non-empty `dimensions` |
| `conversion_rate` | `float` | The percentage of visitors who completed the goal. | Requires non-empty `dimensions`, `event:goal` filter or dimension being set |
| `group_conversion_rate` | `float` | The percentage of visitors who completed the goal with the same dimension. Requires: dimension list passed, an event:goal filter or event:goal dimension | Requires non-empty `dimensions`, event:goal filter or dimension being set |
| `average_revenue` | `Revenue` or null | Average revenue per revenue goal conversion | Requires [revenue goals](docs/ecommerce-revenue-tracking.md), `event:goal` filter or dimension for a relevant revenue goal. |
| `total_revenue` | `Revenue` or null | Total revenue from revenue goal conversions | Requires [revenue goals](docs/ecommerce-revenue-tracking.md), `event:goal` filter or dimension for a relevant revenue goal. |


<details>
<summary>Read more about revenue metrics</summary>

To use revenue metrics, users should configure [revenue goals](docs/ecommerce-revenue-tracking.md).

Revenue metric response type has the following structure:

```js
{
value: float,
currency: string, // e.g. "USD" or "EUR"
short: string, // e.g. "€500.2M"
long: string, // e.g. "€500,200,700.25"
}
```

`long` and `short` options are human-friendly formatted results.

There are scenarios where revenue metrics can't be calculated. For example:
1. When no revenue goals are configured
2. No `event:goal` filter or dimension
3. No revenue goal matches `event:goal` filter
4. No `event:goal` dimension and filtered revenue goals have different currencies.

In these cases, revenue is returned as `null`s and `response.meta.metric_warning` value will have a warning for why the metric could not
be calculated. See [response.meta structure](#meta) and [example](#example-revenue-warning)
</details>

### dimensions <Optional /> {#dimensions}

Expand Down Expand Up @@ -313,10 +344,11 @@ Each result row contains:
- `dimensions` - values for each `dimension` listed in query. In the same order as query `dimensions`, empty if no dimensions requested.
- `metrics` - List of metric values, in the same order as query `metrics`


### meta

Meta information about this query. Related: [include.imports](#include.imports) and [include.time_labels](#include.time_labels).
Meta information about this query, including warnings and auxiliary data. Related: [include](#include).

<CodeBlock language="javascript">{EXAMPLE_RESPONSE_META}</CodeBlock>

### query

Expand Down Expand Up @@ -382,4 +414,15 @@ In this example, imported data could not be included due to dimension and filter

<ApiV2Example id="example-imports-warning" />


### Revenue metrics {#example-revenue-metrics}

<ApiV2Example id="example-revenue-metrics" />

### Revenue metrics could not be calculated {#example-revenue-warning}

In this example, revenue metrics could not be calculated due to different currency filters. [More information](#metrics)

<ApiV2Example id="example-revenue-warning" />

</SiteContextProvider>
32 changes: 32 additions & 0 deletions src/js/apiv2-examples/response-meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
// Whether imported data was included
// Only set if include.imports was set
"imports_included": false,

// Information about why including imported data failed
"imports_skip_reason": "unsupported_interval",
"imports_warning": "Imported stats are not included because the time dimension (i.e. the interval) is too short.",

// Warnings about specific metrics
// Currently only set if a revenue metric was used and was unable to be calculated
"metric_warnings": {
"total_revenue": {
"code": "no_revenue_goals_matching",
"warning": "Revenue metrics are null as there are no matching revenue goals."
}
},

// Only set if include.time_labels was set
"time_labels": [
"2024-09-10 00:00:00",
"2024-09-10 01:00:00",
"2024-09-10 02:00:00",
"2024-09-10 03:00:00",
"2024-09-10 04:00:00",
"2024-09-10 05:00:00",
"2024-09-10 06:00:00"
],

// Only set if include.total_rows was set
"total_rows": 342
}
6 changes: 6 additions & 0 deletions src/js/apiv2-examples/revenue-metrics-query.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"site_id": "dummy.site",
"metrics": ["total_revenue"],
"date_range": "all",
"dimensions": ["event:goal"]
}
30 changes: 30 additions & 0 deletions src/js/apiv2-examples/revenue-metrics-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"results": [
{
"dimensions": ["North America Purchases"],
"metrics": [
{
"short": "$96.3M",
"value": 96336315,
"long": "$96,336,315.00",
"currency": "USD"
}
]
},
{
"dimensions": ["Visit /"],
"metrics": [null]
}
],
"meta": {},
"query": {
"site_id": "dummy.site",
"metrics": ["total_revenue"],
"date_range": ["2021-12-14T00:00:00+00:00", "2024-12-11T23:59:59+00:00"],
"filters": [],
"dimensions": ["event:goal"],
"order_by": [["total_revenue", "desc"]],
"include": {},
"pagination": {"offset": 0, "limit": 10000}
}
}
8 changes: 8 additions & 0 deletions src/js/apiv2-examples/revenue-warning-query.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"site_id": "dummy.site",
"metrics": ["total_revenue"],
"date_range": "all",
"filters": [
["is", "event:goal", ["PurchaseUSD", "PurchaseEUR"]]
]
}
23 changes: 23 additions & 0 deletions src/js/apiv2-examples/revenue-warning-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"results": [
{"metrics": [null], "dimensions": ["Visit /"]}
],
"meta": {
"metric_warnings": {
"total_revenue": {
"code": "no_single_revenue_currency",
"warning": "Revenue metrics are null as there are multiple currencies for the selected event:goals."
}
}
},
"query": {
"site_id": "dummy.site",
"metrics": ["total_revenue"],
"date_range": ["2021-12-14T00:00:00+00:00", "2024-12-11T23:59:59+00:00"],
"filters": [["is", "event:goal", ["PurchaseUSD", "PurchaseEUR"]]],
"dimensions": [],
"order_by": [["total_revenue", "desc"]],
"include": {},
"pagination": {"offset": 0, "limit": 10000}
}
}
14 changes: 14 additions & 0 deletions src/js/examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ function read(path: string): string {
return require(`!!raw-loader?esModule=false!./${path}`)
}

export const EXAMPLE_RESPONSE_META = read("apiv2-examples/response-meta.json")

const EXAMPLES = [
{
id: "example-aggregate",
Expand Down Expand Up @@ -74,6 +76,18 @@ const EXAMPLES = [
title: "Including imported data failed",
query: read("apiv2-examples/imports-bad-filter-query.json"),
exampleResponse: read("apiv2-examples/imports-bad-filter-response.json"),
},
{
id: "example-revenue-metrics",
title: "Revenue metrics",
query: read("apiv2-examples/revenue-metrics-query.json"),
exampleResponse: read("apiv2-examples/revenue-metrics-response.json"),
},
{
id: "example-revenue-warning",
title: "Revenue metrics could not be calculated",
query: read("apiv2-examples/revenue-warning-query.json"),
exampleResponse: read("apiv2-examples/revenue-warning-response.json"),
}
]

Expand Down
Loading