Skip to content

Commit 96b583c

Browse files
authored
Merge pull request #571 from plausible/revenue-metrics-apiv2
Revenue metrics in APIv2
2 parents 36a9839 + aa477bb commit 96b583c

File tree

7 files changed

+171
-15
lines changed

7 files changed

+171
-15
lines changed

docs/stats-api.md

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ toc_max_heading_level: 4
55

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

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

7676
Valid metrics are:
7777

78-
| Metric name | Description |
79-
| --- | --- |
80-
| `visitors` | The number of unique visitors |
81-
| `visits` | The number of visits/sessions |
82-
| `pageviews` | The number of pageview events |
83-
| `views_per_visit` | The number of pageviews divided by the number of visits. Returns a floating point number. |
84-
| `bounce_rate` | Bounce rate percentage |
85-
| `visit_duration` | Visit duration in seconds |
86-
| `events` | The number of events (pageviews + custom events). When filtering by a goal, this metric corresponds to "Total Conversions" in the dashboard. |
87-
| `percentage` | The percentage of visitors of total who fall into this category: Requires: dimension list |
88-
| `conversion_rate` | The percentage of visitors who completed the goal. Requires: dimension list passed, an event:goal filter or event:goal dimension |
89-
| `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 |
78+
| Metric name | Type | Description | Requirements |
79+
| --- | --- | --- | --- |
80+
| `visitors` | `int` | The number of unique visitors | |
81+
| `visits` | `int` | The number of visits/sessions | |
82+
| `pageviews` | `int` | The number of pageview events | |
83+
| `views_per_visit` | `float` | The number of pageviews divided by the number of visits. | |
84+
| `bounce_rate` | `float` | Bounce rate percentage | |
85+
| `visit_duration` | `int` | Visit duration in seconds | |
86+
| `events` | `int` | The number of events (pageviews + custom events). When filtering by a goal, this metric corresponds to "Total Conversions" in the dashboard. | |
87+
| `percentage` | `float` | The percentage of visitors of total who fall into this category: Requires: dimension list | Requires non-empty `dimensions` |
88+
| `conversion_rate` | `float` | The percentage of visitors who completed the goal. | Requires non-empty `dimensions`, `event:goal` filter or dimension being set |
89+
| `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 |
90+
| `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. |
91+
| `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. |
92+
93+
94+
<details>
95+
<summary>Read more about revenue metrics</summary>
96+
97+
To use revenue metrics, users should configure [revenue goals](docs/ecommerce-revenue-tracking.md).
98+
99+
Revenue metric response type has the following structure:
100+
101+
```js
102+
{
103+
value: float,
104+
currency: string, // e.g. "USD" or "EUR"
105+
short: string, // e.g. "€500.2M"
106+
long: string, // e.g. "€500,200,700.25"
107+
}
108+
```
109+
110+
`long` and `short` options are human-friendly formatted results.
111+
112+
There are scenarios where revenue metrics can't be calculated. For example:
113+
1. When no revenue goals are configured
114+
2. No `event:goal` filter or dimension
115+
3. No revenue goal matches `event:goal` filter
116+
4. No `event:goal` dimension and filtered revenue goals have different currencies.
117+
118+
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
119+
be calculated. See [response.meta structure](#meta) and [example](#example-revenue-warning)
120+
</details>
90121

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

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

316-
317347
### meta
318348

319-
Meta information about this query. Related: [include.imports](#include.imports) and [include.time_labels](#include.time_labels).
349+
Meta information about this query, including warnings and auxiliary data. Related: [include](#include).
350+
351+
<CodeBlock language="javascript">{EXAMPLE_RESPONSE_META}</CodeBlock>
320352

321353
### query
322354

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

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

417+
418+
### Revenue metrics {#example-revenue-metrics}
419+
420+
<ApiV2Example id="example-revenue-metrics" />
421+
422+
### Revenue metrics could not be calculated {#example-revenue-warning}
423+
424+
In this example, revenue metrics could not be calculated due to different currency filters. [More information](#metrics)
425+
426+
<ApiV2Example id="example-revenue-warning" />
427+
385428
</SiteContextProvider>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
// Whether imported data was included
3+
// Only set if include.imports was set
4+
"imports_included": false,
5+
6+
// Information about why including imported data failed
7+
"imports_skip_reason": "unsupported_interval",
8+
"imports_warning": "Imported stats are not included because the time dimension (i.e. the interval) is too short.",
9+
10+
// Warnings about specific metrics
11+
// Currently only set if a revenue metric was used and was unable to be calculated
12+
"metric_warnings": {
13+
"total_revenue": {
14+
"code": "no_revenue_goals_matching",
15+
"warning": "Revenue metrics are null as there are no matching revenue goals."
16+
}
17+
},
18+
19+
// Only set if include.time_labels was set
20+
"time_labels": [
21+
"2024-09-10 00:00:00",
22+
"2024-09-10 01:00:00",
23+
"2024-09-10 02:00:00",
24+
"2024-09-10 03:00:00",
25+
"2024-09-10 04:00:00",
26+
"2024-09-10 05:00:00",
27+
"2024-09-10 06:00:00"
28+
],
29+
30+
// Only set if include.total_rows was set
31+
"total_rows": 342
32+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"site_id": "dummy.site",
3+
"metrics": ["total_revenue"],
4+
"date_range": "all",
5+
"dimensions": ["event:goal"]
6+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"results": [
3+
{
4+
"dimensions": ["North America Purchases"],
5+
"metrics": [
6+
{
7+
"short": "$96.3M",
8+
"value": 96336315,
9+
"long": "$96,336,315.00",
10+
"currency": "USD"
11+
}
12+
]
13+
},
14+
{
15+
"dimensions": ["Visit /"],
16+
"metrics": [null]
17+
}
18+
],
19+
"meta": {},
20+
"query": {
21+
"site_id": "dummy.site",
22+
"metrics": ["total_revenue"],
23+
"date_range": ["2021-12-14T00:00:00+00:00", "2024-12-11T23:59:59+00:00"],
24+
"filters": [],
25+
"dimensions": ["event:goal"],
26+
"order_by": [["total_revenue", "desc"]],
27+
"include": {},
28+
"pagination": {"offset": 0, "limit": 10000}
29+
}
30+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"site_id": "dummy.site",
3+
"metrics": ["total_revenue"],
4+
"date_range": "all",
5+
"filters": [
6+
["is", "event:goal", ["PurchaseUSD", "PurchaseEUR"]]
7+
]
8+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"results": [
3+
{"metrics": [null], "dimensions": ["Visit /"]}
4+
],
5+
"meta": {
6+
"metric_warnings": {
7+
"total_revenue": {
8+
"code": "no_single_revenue_currency",
9+
"warning": "Revenue metrics are null as there are multiple currencies for the selected event:goals."
10+
}
11+
}
12+
},
13+
"query": {
14+
"site_id": "dummy.site",
15+
"metrics": ["total_revenue"],
16+
"date_range": ["2021-12-14T00:00:00+00:00", "2024-12-11T23:59:59+00:00"],
17+
"filters": [["is", "event:goal", ["PurchaseUSD", "PurchaseEUR"]]],
18+
"dimensions": [],
19+
"order_by": [["total_revenue", "desc"]],
20+
"include": {},
21+
"pagination": {"offset": 0, "limit": 10000}
22+
}
23+
}

src/js/examples.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ function read(path: string): string {
22
return require(`!!raw-loader?esModule=false!./${path}`)
33
}
44

5+
export const EXAMPLE_RESPONSE_META = read("apiv2-examples/response-meta.json")
6+
57
const EXAMPLES = [
68
{
79
id: "example-aggregate",
@@ -74,6 +76,18 @@ const EXAMPLES = [
7476
title: "Including imported data failed",
7577
query: read("apiv2-examples/imports-bad-filter-query.json"),
7678
exampleResponse: read("apiv2-examples/imports-bad-filter-response.json"),
79+
},
80+
{
81+
id: "example-revenue-metrics",
82+
title: "Revenue metrics",
83+
query: read("apiv2-examples/revenue-metrics-query.json"),
84+
exampleResponse: read("apiv2-examples/revenue-metrics-response.json"),
85+
},
86+
{
87+
id: "example-revenue-warning",
88+
title: "Revenue metrics could not be calculated",
89+
query: read("apiv2-examples/revenue-warning-query.json"),
90+
exampleResponse: read("apiv2-examples/revenue-warning-response.json"),
7791
}
7892
]
7993

0 commit comments

Comments
 (0)