Node.js SDK integration

The GetPassive SDK is a Node.js package, @getpassive/sdk. It connects to the GetPassive gateway over a secure WebSocket, authenticates with your developer API key, and relays approved bandwidth sessions through the device the SDK is running on.

1. Prerequisites

  • Node.js 18 or newer.
  • An approved developer account at app.getpassive.io.
  • At least one app created in the console. The console returns a developer API key when the app is created.

2. Configure the private registry

The package is published on the GetPassive private npm registry. Add an .npmrc file at the root of your project that points the @getpassive scope at the registry:

@getpassive:registry=https://npm.getpassive.io/
//npm.getpassive.io/:_authToken=${GETPASSIVE_NPM_TOKEN}

Request a registry token from the console. Store it in an environment variable, not in the file itself.

3. Install the package

npm install @getpassive/sdk

The package ships ES modules and a TypeScript declaration file. Its single runtime dependency is the ws WebSocket client.

4. Quickstart

import { GetPassiveClient } from '@getpassive/sdk';

const client = new GetPassiveClient({
  devApiKey: process.env.GETPASSIVE_DEV_API_KEY,
  onStatus(status) {
    console.log('GetPassive status:', status);
  },
  onError(err) {
    console.error('GetPassive error:', err);
  },
});

await client.start();

process.on('SIGINT', async () => {
  await client.stop();
  process.exit(0);
});

5. Constructor options

OptionTypeDefaultNotes
devApiKeystringrequiredDeveloper API key from the console. Keep it server-side only.
deviceUuidstringcrypto.randomUUID()Stable identifier for this installed device. Persist it across restarts.
gatewaystringwss://sdk.getpassive.io/Gateway WebSocket URL. Override only if instructed.
publicIpstring | nullauto-detectedIf omitted the SDK detects the public IP at startup. Pass null to skip detection.
clientVersionstringSDK versionReported in the handshake for diagnostics.
logobjectconsoleLogger with info, warn, error, and debug methods.
onStatusfunctionCalled with each status change.
onErrorfunctionCalled with errors that occur during the run loop.

6. Status lifecycle

The status callback receives one of these values:

  • idle — the client has been constructed but start() has not been called.
  • connecting — the first connection attempt is in progress.
  • connected — the WebSocket is open and the handshake has been sent.
  • reconnecting — the connection dropped and the client is waiting before retrying.
  • closedstop() has completed.

7. Reconnect behaviour

The SDK keeps a long-lived secure WebSocket connection to the GetPassive gateway. If the connection closes or fails, it automatically reconnects with exponential backoff that starts at 1 second and doubles up to a maximum of 30 seconds (1s, 2s, 4s, 8s, 16s, 30s, 30s…). The backoff resets after a successful connection and handshake. Stopping the client cancels the loop.

8. Persisting deviceUuid

If deviceUuid is not provided the SDK generates one with crypto.randomUUID(). For production apps, persist this value across restarts so the same installation keeps a stable identity. A common pattern is to write the UUID to your application's data directory the first time the SDK starts and pass it back on every subsequent run:

import { readFile, writeFile, mkdir } from 'node:fs/promises';
import path from 'node:path';
import { randomUUID } from 'node:crypto';
import { GetPassiveClient } from '@getpassive/sdk';

async function loadDeviceUuid(dataDir) {
  const file = path.join(dataDir, 'getpassive-device-uuid');
  try {
    return (await readFile(file, 'utf8')).trim();
  } catch {
    const uuid = randomUUID();
    await mkdir(dataDir, { recursive: true });
    await writeFile(file, uuid, 'utf8');
    return uuid;
  }
}

const deviceUuid = await loadDeviceUuid('/var/lib/my-app');
const client = new GetPassiveClient({
  devApiKey: process.env.GETPASSIVE_DEV_API_KEY,
  deviceUuid,
});
await client.start();

9. Test mode and live mode

New developer API keys start in test mode. Test mode is for integration checks, status callbacks, restart loops, and end-to-end validation while the app is under review. Live mode is enabled by an admin after review. The same SDK code path runs in both modes — you do not need to change your integration when a key is promoted.

Last updated June 11, 2026