Skip to main content
The Node.js SDK tracks events from servers, jobs, and webhooks. It requires Node.js 14.17 or later.

Install

npm install @datalyr/api

Initialize

import { Datalyr } from '@datalyr/api'

const datalyr = new Datalyr({
  apiKey: process.env.DATALYR_API_KEY
})

Track an event

await datalyr.track({
  event: 'purchase',
  userId: 'user_123',
  eventId: 'order_1001',
  timestamp: new Date(),
  properties: {
    value: 99.99,
    currency: 'USD'
  }
})
Use a stable eventId for webhook events. If the source retries the webhook, Datalyr can recognize the duplicate.

Identify a user

await datalyr.identify('user_123', {
  email: '[email protected]',
  plan: 'pro'
})

Core methods

MethodUse it to
track(options)Track a backend event.
identify(userId, traits?)Attach traits to a user.
alias(newUserId, previousId?)Link two IDs for the same user.
page(userId, name?, properties?)Track a server-rendered page view.
trackPurchase(userId, properties)Track revenue with a required finite value.
flush()Send queued events immediately.
close()Flush events and stop timers before shutdown.

Shut down cleanly

await datalyr.close()
Call close() in short-lived scripts, workers, and graceful shutdown handlers so queued events have time to send.

Configuration

const datalyr = new Datalyr({
  apiKey: process.env.DATALYR_API_KEY,
  flushAt: 20,
  flushInterval: 10_000,
  timeout: 10_000,
  retryLimit: 3,
  maxQueueSize: 1_000,
  closeTimeout: 30_000,
  onError: (event, error) => console.error(error),
  onDrop: (events, reason) => console.error(reason, events)
})
OptionDefaultWhat it controls
apiKeyRequiredWorkspace API key.
flushAt20Events queued before an automatic send.
flushInterval10000Automatic flush interval in milliseconds.
timeout10000Request timeout in milliseconds.
retryLimit3Retries during a send attempt.
maxQueueSize1000Maximum queued events.
closeTimeout30000Time allowed for close() to drain the queue.
debugfalseDevelopment logging.
onErrorCalled for every delivery failure.
onDropCalled when events are permanently dropped.

Event identity

Prefer the object form of track:
await datalyr.track({
  event: 'trial_started',
  userId: 'user_123',
  anonymousId: 'anon_from_browser',
  properties: { plan: 'pro' }
})
Provide userId, anonymousId, or both. If you omit both, the SDK creates a new anonymous ID for that call, so separate calls will not form a continuous journey.

Idempotency and timestamps

For webhooks, pass the source event ID and original timestamp:
await datalyr.track({
  event: 'invoice_paid',
  userId: customer.id,
  eventId: stripeEvent.id,
  timestamp: stripeEvent.created,
  properties: { value: 49, currency: 'USD' }
})
timestamp accepts an ISO 8601 string, a Date, epoch seconds, or epoch milliseconds.

Identity methods

await datalyr.identify('user_123', { email: '[email protected]' })
await datalyr.alias('user_123', 'temporary_id')
await datalyr.page('user_123', 'Pricing', { variant: 'A' })

Track revenue

await datalyr.trackPurchase(
  'user_123',
  { value: 99.99, currency: 'USD', product_id: 'pro_yearly' },
  { eventId: 'order_1001', timestamp: new Date() }
)
value must be a finite number. Currency values are normalized to uppercase.

Serverless functions

Use flush() at the end of an invocation when the SDK instance may be reused:
await datalyr.flush()
Use close() only when the process is shutting down. Once closed, the instance cannot accept more events.