Skip to main content
A server-side SDK — you create a client, pass a user ID on every call, and a background worker handles batching and delivery over HTTP + JSONL. Zero dependencies. Data collected server-side is trustworthy and tamper-proof. Unlike the browser SDK, the Node.js SDK doesn’t auto-collect device context — you control exactly what properties are sent.

Quick start

Verify it works

In development mode (logLevel: "debug"), the SDK logs to the console when events are batched and flushed. You can also call await tell.flush() and check that no error is reported via onError.

Configuration

Two presets are available:
For custom settings:

Tracking events

Every method takes userId as its first parameter. For details on each event type and when to use them, see Events & Properties.
Pass undefined when you don’t need properties:

Standard event names

Constants cover user lifecycle, revenue, subscriptions, trials, shopping, engagement, and communication events. Custom string names always work too.

Super properties

Event-specific properties override super properties when keys conflict. See Events & Properties for more on property patterns.

Structured logging

The service parameter defaults to "app". Nine severity levels from logEmergency to logTrace. See Logs for the full level reference and when to use each. Generic logging method:

Redaction & beforeSend

Transform or drop events before they’re queued. Return null to drop an item. Supports a single function or an array of functions applied in order.

Drop health-check events

Scrub user PII from traits

redact() utility

For common patterns, use the built-in redact() factory:
You can combine redact() with custom hooks in an array:
Server-side redaction prevents sensitive data from ever leaving your infrastructure. For defense in depth, also configure pipeline redaction to catch anything that slips through.

Lifecycle

Always call close() before your process exits to avoid losing buffered events.

Error handling

Tracking calls (track, identify, group, revenue, alias) and logging calls never throw. Validation errors and network failures route through the onError callback:
Constructor and lifecycle methods (flush, close) can throw or reject — handle these in your application code.

Retry behavior

On HTTP send failure (5xx or network error), the SDK retries with exponential backoff: 1-second base delay, 1.5x multiplier, 20% jitter, capped at 30 seconds. After maxRetries attempts (default: 3), the batch is dropped and reported via onError. 4xx errors (except 413) are not retried — they indicate a client-side issue (e.g. invalid API key). On 413 (payload too large), the SDK automatically halves the batch size for future sends.

Configuration reference