Query last-epoch usage stats
This example reads the latest usage snapshot embedded in GET /v0/gateways/{address}. The recent.epoch.usageStats block appears only for mobile gateways that reported usage in the most recent epoch.
Prerequisites
- Node.js 18 or newer.
- An API key exported as
HELIUMGEEK_API_KEY. - A gateway address provided via the
GATEWAY_ADDRESSenvironment variable or the first CLI argument.
Run the example
-
Download mobile-usage-last-epoch.js and save it locally.
-
Export the environment variables and run the script:
export HELIUMGEEK_API_KEY="your-api-key"
export GATEWAY_ADDRESS="your-gateway-address"
node mobile-usage-last-epoch.jsOr supply the address inline:
HELIUMGEEK_API_KEY="your-api-key" node mobile-usage-last-epoch.js <gateway-address>
Script
mobile-usage-last-epoch.js
#!/usr/bin/env node
const BASE_URL = (process.env.HELIUMGEEK_API_BASE_URL ?? 'https://api.heliumgeek.com/v0').replace(/\/$/, '');
const API_KEY = process.env.HELIUMGEEK_API_KEY;
const GATEWAY_ADDRESS =
(process.argv[2] ?? process.env.GATEWAY_ADDRESS ?? '').trim();
if (!API_KEY) {
console.error('Set HELIUMGEEK_API_KEY before running this script.');
process.exit(1);
}
if (!GATEWAY_ADDRESS) {
console.error(
'Provide the gateway address as an argument or set GATEWAY_ADDRESS.'
);
process.exit(1);
}
const byteFormatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
async function main() {
const response = await fetch(
buildUrl(`/gateways/${encodeURIComponent(GATEWAY_ADDRESS)}`),
{
headers: {
'x-api-key': API_KEY,
},
}
);
if (!response.ok) {
throw new Error(`Request failed: ${response.status} ${response.statusText}`);
}
const gateway = await response.json();
const stats = gateway?.recent?.epoch?.usageStats;
if (!stats) {
console.log(
`Gateway ${GATEWAY_ADDRESS} has no usage stats for the most recent epoch.`
);
return;
}
const epochEnd = new Date(stats.epochEndTimestamp * 1000).toISOString();
const totals = stats.transferBytes ?? {};
const serviceProviderBytes = Number(totals.serviceProvider ?? 0);
const offloadBytes = Number(totals.offload ?? 0);
const totalBytes = serviceProviderBytes + offloadBytes;
const spShare = totalBytes > 0 ? ((serviceProviderBytes / totalBytes) * 100).toFixed(2) : '0.00';
const offloadShare = totalBytes > 0 ? ((offloadBytes / totalBytes) * 100).toFixed(2) : '0.00';
console.log(`Usage stats for ${GATEWAY_ADDRESS} (epoch ending ${epochEnd})`);
const counts = stats.userCounts ?? {};
console.log(
`Users SP ${counts.serviceProvider ?? 0} Mapping ${counts.discoMapping ?? 0} Offload ${counts.offload ?? 0}`
);
console.log(
`Transfer SP ${formatBytes(serviceProviderBytes)} (${spShare}%) Offload ${formatBytes(offloadBytes)} (${offloadShare}%) Total ${formatBytes(totalBytes)}`
);
if (Array.isArray(stats.carrierTransferInfo) && stats.carrierTransferInfo.length) {
console.log('Carriers:');
for (const carrier of stats.carrierTransferInfo) {
const carrierName =
carrier.carrier?.name ?? carrier.carrier?.idString ?? `carrier_${carrier.carrier?.id ?? '?'}`;
const transfer = formatBytes(carrier.transferBytes ?? 0);
const userCount = carrier.userCount ?? 0;
console.log(` ${carrierName}: ${transfer} transfer, ${userCount} users`);
}
}
}
function buildUrl(path, query = {}) {
const url = new URL(path.replace(/^\//, ''), `${BASE_URL}/`);
Object.entries(query).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
url.searchParams.set(key, String(value));
}
});
return url.toString();
}
function formatBytes(bytes) {
const gigabytes = Number(bytes) / 1e9;
return `${byteFormatter.format(gigabytes)} GB`;
}
main().catch((error) => {
console.error(error.message);
process.exit(1);
});