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
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,dayas 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 usesmeanby 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 is1mif 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, …). Setwindow = noneto 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 = 1hand the query range is from11:30to16:30:Set
window_edges = partialto 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 whenwindow = 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 afterto.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
timestampwhen it is partial. All other windows are aligned to the usual global timeline. For instance ifwindow = 1hand the query range is from11:30to16:30:With
window_edges = partialthe returnedtimestampvalues are11:30,12:00,13:00,14:00,15:00and16:00, where the11:30window covers11:30–12:00and the16:00window covers16:00–16:30.
Format:
format– Output format:json(default),ndjson,csv, orhtml.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 domainIdstrue: response includes verbose domainIds
Output Domain Parameter:
output_domain(string): Returns theidof each matched time series in this domain, instead of the domain that was queried. For example, query theraalabsdomain withoutput_domain=jsmeato 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 withoutput_domainset than without it. Theiddomain is defined for every time series, sooutput_domain=idnever 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).
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.
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:
countandsumare added upminandmaxtake the lowest and the highest value across the time seriesmean,var,stddev,skewnessandkurtosisare recalculated for the combined set of data pointsfirst_val,first_time,last_valandlast_timefollow the earliest and the latest data point across the time series, anddeltais 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 of2025-09-10T09:00:00Zrepresents 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:
The CSV response format is an experimental feature, and is subject to change.
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):
The HTML response format is an experimental feature, and is subject to change.
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 ShaftPowertargets the ShaftPower measurement for all vessels (*wildcard for IMO) in Raa Labs naming.aggregations=avg,maxasks for Average and Maximum values.window=1hsets 1-hour aggregation windows.last=1dayrequests 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,stddevwill return the daily average and daily standard deviation of that measurement.window=1duses a one-day window for each data point (each result represents one day’s stats).last=30daysmeans 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,maxwill produce two values per window: the minimum and maximum temperature observed in each 15-minute interval.window=15msets the aggregation interval to 15 minutes.since=7daysretrieves 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?