BI Integration
You can read the Statistics API from a reporting tool. This page shows two ways: Power BI with a Power Query script, and Prometheus with a scrape job.
Pick your environment and the hosts on this page update to match.
Power BI
Power BI reads the API through a Power Query script. The first query reads one page, the second reads every page and combines them.
Integration Script (Power Query M)
The script below is a Power Query function. It requests a token, reads one page of /analytics for a date range and returns a record with totalPages and the rows as a table in rows. Create a blank query in Power BI Desktop under Get data, open the Advanced Editor, paste the script, and name the query GetStatisticsPage.
(page as number) =>
let
client_id = "your-client-id",
client_secret = "your-client-secret",
token_url = "https://identity-v2.metaforce.net/connect/token",
scope = "api.external",
start_date = "2026-09-01T00:00:00Z",
to_date = "2026-09-07T23:59:59Z",
Body = Text.ToBinary("grant_type=client_credentials" &
"&client_id=" & client_id &
"&client_secret=" & client_secret &
"&scope=" & scope),
TokenResponse = Json.Document(Web.Contents(token_url,
[Content = Body, Headers = [#"Content-Type" = "application/x-www-form-urlencoded"]])),
AccessToken = TokenResponse[access_token],
ApiResponse = Json.Document(Web.Contents("https://api.statistics-v2.metaforce.net/analytics",
[
Query = [
pageSize = "1000",
pageNumber = Number.ToText(page),
startDate = start_date,
toDate = to_date
],
Headers = [Authorization = "Bearer " & AccessToken]
])),
Data = ApiResponse[data],
Table1 = Table.FromList(Data, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
Expanded = Table.ExpandRecordColumn(Table1, "Column1",
{"event", "system", "date", "hour", "template", "source", "distribution", "environment", "area", "count", "eventDetail"},
{"event", "system", "date", "hour", "template", "source", "distribution", "environment", "area", "count", "eventDetail"})
in [totalPages = ApiResponse[totalPages], rows = Expanded]
Set start_date and to_date to the range you want to report on. Keep the range short, see Best Practices.
Read every page
The function returns one page. The first call tells you how many pages exist in totalPages, so a second blank query can call the function for every page and combine the tables:
let
Pages = List.Numbers(1, GetStatisticsPage(1)[totalPages]),
Tables = List.Transform(Pages, each GetStatisticsPage(_)[rows]),
Combined = Table.Combine(Tables)
in CombinedLoad Combined into your report and build visuals on count, template, date and hour. A range without events gives an empty table. A company with no statistics data at all gets 404, which Power BI reports as an error for the query.
Note: Power BI Desktop stores the client secret inside the query, so anyone who has the report file can read it. Keep the file private.
Prometheus
The /analytics/prometheus endpoint returns the text format that Prometheus scrapes. It needs a bearer token, which Prometheus can fetch itself with the client credentials flow. This job is for Prometheus 3:
scrape_configs:
- job_name: docgen-statistics
scheme: https
metrics_path: /analytics/prometheus
scrape_interval: 2m
fallback_scrape_protocol: PrometheusText0.0.4
oauth2:
client_id: your-client-id
client_secret: your-client-secret
token_url: https://identity-v2.metaforce.net/connect/token
scopes: [api.external]
static_configs:
- targets: ['api.statistics-v2.metaforce.net']
fallback_scrape_protocolis needed because the endpoint sends noContent-Typeheader, and Prometheus 3 refuses a scrape without one. Prometheus 2 falls back to the text format on its own, so leave the line out there.- Keep
scrape_intervalunder five minutes. By default Prometheus looks back only five minutes for a value, so a longer interval leaves gaps in your graphs. - Without a
startDatethe endpoint counts events from today at 00:00 UTC, so the values are today’s totals so far and start again from zero at midnight UTC. Addparams: { startDate: [...] }to the job to use another start. - Each combination becomes one series named
<event>_event_count, see API Endpoints.