Docs

TURN and STUN Statistics

Updated

On this page

The Statistics API returns usage rollups for the entire account or for a specific channel. Reporting data is rolled up hourly, so very recent traffic may not appear immediately.

Use GET /_stats for account-wide usage. Add a channel name, as in GET /_stats/{channel}, to limit the results to that channel. Authenticate both forms with HTTP Basic authentication from a trusted backend.

Request Parameters

GET/_stats
GET/_stats/{channel}
Parameter Description
l Measurement to return. Use one of the supported names below.
gs Inclusive UTC start date of the requested period as YYYY:MM:DD.
ge Inclusive UTC end date of the requested period as YYYY:MM:DD.
break=1 Return the period as grouped intervals instead of only an aggregate.

Supported measurement names:

  • turn:session: TURN session duration in seconds
  • turn:recv: bytes received by TURN
  • turn:sent: bytes sent by TURN
  • stun:session: STUN session duration in seconds

Use the singular names exactly as shown. A query URL has one ?; join additional parameters with &.

Example

Omit the channel name to return an aggregate for the entire account:

Account-wide requestShell
curl --user "$XIRSYS_IDENT:$XIRSYS_SECRET" \
  "https://global.xirsys.net/_stats?l=turn:sent&gs=2026:05:01&ge=2026:05:24"

Include the complete channel name to limit the results to one channel. This example also requests grouped intervals:

Channel request with intervalsShell
curl --user "$XIRSYS_IDENT:$XIRSYS_SECRET" \
  "https://global.xirsys.net/_stats/myChannel?l=turn:sent&gs=2026:05:01&ge=2026:05:24&break=1"

The channel-specific request from Node.js 18 or later:

Node.js backendJS
const channel = process.env.XIRSYS_CHANNEL;
const encodedChannel = encodeURIComponent(channel);
const auth = Buffer.from(
  `${process.env.XIRSYS_IDENT}:${process.env.XIRSYS_SECRET}`
).toString('base64');

const params = new URLSearchParams({
  l: 'turn:sent',
  gs: '2026:05:01',
  ge: '2026:05:24',
  break: '1'
});

const response = await fetch(
  `https://global.xirsys.net/_stats/${encodedChannel}?${params}`,
  { headers: { Authorization: `Basic ${auth}` } }
);
const data = await response.json();

if (!response.ok || data.s !== 'ok') {
  throw new Error(`Statistics request failed (${response.status})`);
}

console.log(data.v);

URL-encode the complete channel name. Choose a reporting range that includes completed hourly rollups.

Understand Aggregate Fields

An aggregate result includes count, sum, max, and min. For example:

Aggregate resultJSON
{
  "count": 100,
  "max": 2000000,
  "min": 1000,
  "sum": 100000000
}
Field Meaning
count The number of stat records included in the result: 100 in this example.
sum The total of the v values from those records: 100,000,000.
max The largest single v value: 2,000,000.
min The smallest single v value: 1,000.

For turn:recv and turn:sent, each v value is bytes. The example therefore represents 100 samples totaling 100,000,000 bytes (about 95.37 MiB), with a largest sample of 2,000,000 bytes, a smallest sample of 1,000 bytes, and a calculated average of 1,000,000 bytes per sample.

For turn:session and stun:session, each v value is a duration in seconds. sum is the total session duration in seconds, while count is the number of session records included.

Interpreting count: it is the number of stat records reduced, not always a user-visible connection count. The dashboard uses count for the STUN and TURN connections chart, but uses sum for bandwidth and session-duration reporting.

Questions about this page? Email experts@xirsys.com