For the complete documentation index, see llms.txt. This page is also available as Markdown.

Statistics Endpoint

The Statistics endpoint provides aggregated metrics calculated from time series data, over specified time windows. This allows you to query values such as averages, minima, maxima, counts, standard deviation, etc., instead of raw data points. It is useful for downsampling data or getting summary insights over time intervals.

You can query one or multiple time series for statistics using GET requests:

curl "https://portal.raalabs.io/{ENVIRONMENT}/statistics/{domain}/{expression}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "x-api-version: 2026-09-10"
import requests

TOKEN = "YOUR_TOKEN"
ENVIRONMENT = "YOUR_ENVIRONMENT"

url = f"https://portal.raalabs.io/{ENVIRONMENT}/statistics/{domain}/{expression}"
headers = {
    "Authorization": f"Bearer {TOKEN}",
    "x-api-version": "2026-09-10",
}

response = requests.get(url, headers=headers)

...or POST requests:

curl -X POST "https://portal.raalabs.io/{ENVIRONMENT}/statistics/query" \
  -H "Authorization: Bearer $TOKEN" \
  -H "x-api-version: 2026-09-10" \
  -H "Content-Type: application/json" \
  -d '[
    "domain/expression",
    "domain/expression"
  ]'
import requests

TOKEN = "YOUR_TOKEN"
ENVIRONMENT = "YOUR_ENVIRONMENT"

url = f"https://portal.raalabs.io/{ENVIRONMENT}/statistics/query"
headers = {
    "Authorization": f"Bearer {TOKEN}",
    "x-api-version": "2026-09-10",
    "Content-Type": "application/json",
}
data = [
    "domain/expression",
    "domain/expression",
]

response = requests.post(url, headers=headers, json=data)

As with measurements, use GET for a single domain/expression query and the POST /statistics/query (with a JSON array in the body) to retrieve multiple series in one call. Only POST requests support domainIds with empty hierarchy levels.

Request

Path Parameters

Parameter
Description

domain

The contextual domain for the query (e.g. jsmea, raalabs, id, vis-3-8a).

expression

The domain-specific query expression used to select which time series to compute statistics for. This can be a specific path or include wildcards (*) to retrieve multiple tags. In many domains, the expression begins with the vessel’s IMO number.

Query Parameters

Like the measurements endpoint, the statistics query supports time range parameters and format selection. If a requested window doesn't both start and end in the past, the statistics for it are calculated using the available data, which may be incomplete.

It also introduces parameters to specify the type of aggregation and the window size for aggregation. If no time range is given, the default is from = -1h to to = now (last one hour). If no aggregation is specified, the default is mean. If no window is specified, the default window is 1 minute (1m).

  • Time Range: Use from, to, from_epoch, to_epoch, since, last, year, month, day as described in the Measurements section to define the time range of data over which statistics are computed.

  • Aggregation Functions: aggregations (string) – A comma-separated list of aggregation functions to compute for each time window. You can request multiple metrics at once. If this parameter is omitted, the API uses mean by default.

  • Window Size: window (string) – The duration of each aggregation window. This is given as a time interval literal, e.g. 1m (1 minute), 2h (2 hours), 2d (2 days), etc. All data within each window is used to calculate the aggregations. The default window is 1m if not specified.

    Windows are aligned to a fixed global timeline, so boundaries are consistent across all queries. For example, with window = 1h, windows always start at whole hours (12:00, 13:00, …). Set window = none to disable windowing. A single aggregation covering the full query range is returned.

    A window is included if its start time is within the query range, even if it extends past the end. For instance if window = 1h and the query range is from 11:30 to 16:30:

    Set window_edges = partial to use the query range exactly as given instead.

  • Window Edges: window_edges (string) – Controls what happens to the windows at each end of the query time range when the range does not align with the time windows. This parameter is ignored when window = none, which always uses the query range as given.

    • whole (default): the range is expanded to whole windows, so the leading partial window is dropped and the trailing window is returned in full — meaning it can include data from after to.

    • partial: the range is used exactly as given, and the windows at each end are returned as partial windows covering only the part that falls inside the query range.

      A partial window aggregates less data than a whole one, so compare values across windows with care. The first window carries the exact query start as its timestamp when it is partial. All other windows are aligned to the usual global timeline. For instance if window = 1h and the query range is from 11:30 to 16:30:

      With window_edges = partial the returned timestamp values are 11:30, 12:00, 13:00, 14:00, 15:00 and 16:00, where the 11:30 window covers 11:3012:00 and the 16:00 window covers 16:0016:30.

  • Format: format – Output format: json (default), ndjson, csv, or html.

  • Verbose Parameter:

    • verbose (boolean): Some domains offer more human-readable, verbose domainIds. This parameter allows you to toggle verbose domainIds on and off. If the domain does not distinguish between verbose and regular IDs, this parameter does not have any effect.

      • false (default): response includes regular domainIds

      • true: response includes verbose domainIds

  • Output Domain Parameter:

    • output_domain (string): Returns the id of each matched time series in this domain, instead of the domain that was queried. For example, query the raalabs domain with output_domain=jsmea to get JSMEA ids back. Defaults to the queried domain. A time series that has no name in the requested output domain is left out of the response, so a query can return fewer time series with output_domain set than without it. The id domain is defined for every time series, so output_domain=id never leaves anything out.

Supported Aggregations

The following aggregation functions are available to use in the aggregations parameter:

min

Minimum value in the window

max

Maximum value in the window

mean

Mean value in the window (if there is exactly one value, mean returns that value)

avg

Average (time-weighted) value in the window (if there is exactly one value, avg returns null)

count

Count of data points (sample count)

sum

Sum of all values

stddev

Standard deviation of values

var

Variance of values

skewness

Statistical skewness of the values distribution

kurtosis

Statistical kurtosis of the values distribution

first_val

The first value in the time window

last_val

The last value in the time window

integral

Integral (area under the curve) over the window

first_time

Timestamp of the first data point in the window

last_time

Timestamp of the last data point in the window

delta

Difference between the last and first value in the window (last_val - first_val). Useful for calculating the change in a measurement over the aggregation window.

You may combine multiple aggregations in one query by listing them separated with commas (e.g. aggregations=avg,max,min,count).

Note: For time series with JSON data types, only a limited set of aggregations are available: last_val, first_val, last_time, first_time, and count. Other aggregations will return null for JSON data types.

Response

If the request is valid, the API returns the computed statistics for each requested time series over the specified time range and window. The results are returned in time order, one object per time window and id, containing all requested aggregations.

Note: Similar to the measurements endpoint, the id in the results will use the domain format you queried, unless you set the output_domain query parameter.

Time Series Sharing an DomainId

A domain does not always name every time series individually, so several time series can resolve to the same id. Their statistics are then merged based on the output_domain parameter. The response holds one value per time window and id covering all of the data points of those time series, rather than one object per underlying time series.

Each aggregation is combined the way that aggregation requires:

  • count and sum are added up

  • min and max take the lowest and the highest value across the time series

  • mean, var, stddev, skewness and kurtosis are recalculated for the combined set of data points

  • first_val, first_time, last_val and last_time follow the earliest and the latest data point across the time series, and delta is the difference between those two values

avg and integral are time-weighted, and cannot be recalculated from values that are already aggregated. They are returned as null in a merged object. Request mean instead of avg for queries that can match time series sharing an id.

In the csv and html formats, merged time series likewise share a single id/aggregation column.

Query with output_domain=id to keep every time series separate, since the id domain names every time series individually.

Formats

For format=json (default), the response is a JSON array of objects. Each object represents the results of one time window and all requested aggregation types. Each object has the following fields:

  • timestamp – ISO 8601 timestamp of the measurement (UTC), which marks the timestamp for that window's result. The timestamp corresponds to the start of the aggregation window. (For example, if window=1h, a timestamp of 2025-09-10T09:00:00Z represents the window from 09:00 to 10:00.)

  • id - The identifier of the measurement in the domain you specified.

  • aggregations – an object containing the requested aggregations.

Example JSON response (for a query that requested mean, max, min, and count aggregations, and where a window size of 1 hour was chosen):

(This example shows two 1-hour windows. Between 09:00 and 10:00 on Sept 10, 2025, the mean ShaftPower was 13.12, the max was 15.47, the min was 10.85, and there were 3600 data points. The next hour shows similar statistics with slightly different values.)

For format=ndjson, the output is similar to the JSON format, but each object is written on a separate line (newline-delimited). This is helpful for streaming or incremental processing of large results.

Each line will be a JSON object identical in structure to the objects shown in the JSON example above.

Example NDJSON response:

For format=csv, the response is returned as text/csv with a header row followed by data rows. Each row corresponds to one aggregation window timestamp, and columns represent the aggregated values for each time series.

Column names follow the pattern id/aggregationName (e.g., IMO1000001/ME ShaftPower/mean). Each id in the result gets its own set of columns, and time series that were merged into one id share a single set. Columns are sorted alphabetically.

Example CSV response (for a query that requested mean, max, min, and count aggregations with a 1-hour window):

For format=html, the response is returned as text/html; charset=utf-8 containing an HTML <table> element. The structure mirrors the CSV format, with each row representing one aggregation window.

Example HTML response:

Examples

Aggregated Statistics (average & max over time)

Retrieve the average and maximum Main Engine Shaft Power for all vessels, aggregated in 1-hour windows, over the last day (note that spaces in tag names must be URL-encoded using %20):

In this example:

  • raalabs/*/ME ShaftPower targets the ShaftPower measurement for all vessels (* wildcard for IMO) in Raa Labs naming.

  • aggregations=avg,max asks for Average and Maximum values.

  • window=1h sets 1-hour aggregation windows.

  • last=1day requests data for the last full day (24 hours).

The response will be a series of time-windowed results, each with an Avg and Max for that hour, along with a timestamp for the hour.

Statistics for a Specific Vessel (multiple metrics)

Get the mean and standard deviation of fuel oil consumption (mass flow rate) for a specific vessel (IMO 1234567), calculated over daily windows for the last 30 days:

In this example:

  • The domain/expression targets the MassFlowRate in the Main Engine Fuel Oil Line for vessel 1234567 (using wildcards for any sub-levels under FuelOilLine).

  • aggregations=mean,stddev will return the daily average and daily standard deviation of that measurement.

  • window=1d uses a one-day window for each data point (each result represents one day’s stats).

  • last=30days means the last 30 full days (approximately the previous month).

The output will list one JSON object per day and aggregation type, each containing an aggregation name, and a timestamp (likely the start of the day).

Fleet-Wide Comparative Statistics

Compare minimum and maximum engine temperatures across the fleet with 15-minute aggregation windows for the past week:

In this example:

  • The expression raalabs/*/ME*Temp* uses wildcards to match any Raa Labs tag that contains "ME" and "Temp" (e.g., it could match tags like "ME ExhaustTemp" or "ME CoolingTemp" depending on naming). This effectively tries to fetch engine temperature-related metrics for all vessels.

  • aggregations=min,max will produce two values per window: the minimum and maximum temperature observed in each 15-minute interval.

  • window=15m sets the aggregation interval to 15 minutes.

  • since=7days retrieves data from one week ago up until now.

The result will show 15-minute snapshots of the lowest and highest recorded values among those temperature measurements, across the fleet, for the last week.

Last updated

Was this helpful?