@getfluxly/node

Node SDK

Server-side ingest from any Node.js runtime, Vercel Functions, AWS Lambda, long-running services, scripts. Batches events with retry, jitter, and X-Idempotency-Key so transient network failures never double-count.

Install

npm install @getfluxly/node

Quick start

import { initGFluxNode } from "@getfluxly/node";

const gflux = initGFluxNode({
  token: process.env.GFLUX_SERVER_TOKEN,
});

await gflux.track("subscription_started", {
  externalId: "user_42",
  properties: { plan: "pro" },
});

await gflux.identify({
  externalId: "user_42",
  traits: { email: "x@y.com", plan: "pro" },
});

await gflux.alias({
  userId: "user_42",
  anonymousId: "anon_a8f3c2",
});

await gflux.flush();

Batching defaults

| Option | Default | Notes | | --- | --- | --- | | flushAt | 20 | Events queued before forced flush | | flushIntervalMs | 5000 | Periodic flush cadence | | maxRetries | 2 | Per failed batch | | timeoutMs | 5000 | Per HTTP request | | maxQueueSize | 1000 | Hard cap, throws queue_overflow |

track() and identify() return null until a flush happens. flush() and shutdown() always return a FlushResult. In short-lived runtimes (Lambda, Vercel Functions, edge handlers) call flush() before the function exits, otherwise the batch never ships.

Errors

Every thrown error is a GFluxNodeError with code and retryable:

try {
  await gflux.track("invoice_paid", { externalId: "user_42" });
} catch (error) {
  if (error.code === "queue_overflow") {
    // Surface back-pressure to the caller; the batch is full.
  } else if (error.retryable) {
    // The SDK already retried `maxRetries` times.
  }
}

Full code table at errors.