Documentation

SDK, CLI, and platform reference

Install and configure @eventra_dev/eventra-sdk and @eventra_dev/eventra-cli. Runtime ingest, catalog sync, and dashboard concepts in one place.

Node 18+ESM + CJSTypeScript
Open dashboard

Create a workspace and connect your first project API key.

Reference

SDK & CLI

Select a package for install instructions, configuration options, reliability behavior, and usage examples.

Runtime SDK for browser, Node, Edge, and serverless. Track events with track() - batching, retries, and delivery are handled automatically.

Install

Add the Eventra SDK to your application.

npm i @eventra_dev/eventra-sdk
pnpm add @eventra_dev/eventra-sdk
yarn add @eventra_dev/eventra-sdk

Quick start

Only apiKey is required. The SDK handles batching, retries, queueing, flushing, and runtime adaptation automatically.

import { Eventra } from "@eventra_dev/eventra-sdk";

const tracker = new Eventra({
  apiKey: "YOUR_PROJECT_API_KEY",
});

tracker.track("checkout.completed", {
  userId: "user_123",
});

Default endpoint: https://api.eventra.dev/api/v1/ingest/batch

Runtime behavior

No extra config - the SDK detects the environment and adapts delivery.

EnvironmentBehavior
Browserbatching + persistence + retry
Node.jsbatching + retry
Serverlessimmediate flush + retry
Edgelightweight batching
Workersbatching

Event properties

Attach JSON data to any event. Validated at track() time (UTF-8 byte limits).

tracker.track("feature.used", {
  userId: "user_123",
  properties: {
    feature: "dashboard",
    plan: "pro",
  },
});

tracker.track("app.loaded");
  • Event name - trimmed to 64 characters
  • userId - trimmed to 120 characters
  • properties - max depth 8, max ~32 KB (UTF-8)
  • Batch payload - max 60 KB by default (maxPayloadBytes)

Configuration

Optional tuning for batching, retries, and error callbacks. endpoint is optional - omit it to use the production ingest URL.

const tracker = new Eventra({
  apiKey: "YOUR_PROJECT_API_KEY",
  flushInterval: 2000,
  maxBatchSize: 50,
  maxQueueSize: 10000,
  maxRetries: 3,
  retryBaseDelayMs: 300,
  maxPayloadBytes: 60000,
  onEventsDropped: (count) => {
    console.warn(`Dropped ${count} event(s) - queue full`);
  },
  onDeliveryFailed: ({ status, events }) => {
    console.error(`Ingest rejected batch (${status})`, events.length);
  },
});
OptionDescription
apiKeyProject API key (required).
endpointIngest batch URL. Defaults to production.
flushIntervalPeriodic flush interval (ms).
maxBatchSizeMax events per outgoing batch.
maxQueueSizeMax pending events before drop.
maxRetriesTotal delivery attempts per batch (default 3).
retryBaseDelayMsBase delay for exponential backoff (ms).
maxPayloadBytesMax serialized batch size (default 60 000).
fetchImplCustom fetch (older Node, tests).
autoFlushOnExitFlush on process exit. Default true.
disableTimerDisable periodic flush timer.
onEventsDroppedCallback when the queue is full.
onDeliveryFailedPermanent ingest errors (4xx except 429).
multiTabMode"independent" (default) or "leader" (browser).

Manual flush

await tracker.flush();

Shutdown

Graceful shutdown - flush first, then cleanup. For Node and serverless, prefer explicit shutdown over relying on process signals.

await tracker.flush();
await tracker.shutdown();

destroy() stops timers and listeners immediately without flushing.

Usage examples

One tab per runtime or framework. Each example is copy-ready: a single Eventra instance, track() calls, and shutdown or flush() where the environment requires it (Node, Edge, serverless).

Batching, localStorage persistence, retry, flush on tab close (keepalive).

import { Eventra } from "@eventra_dev/eventra-sdk";

const tracker = new Eventra({
  apiKey: "YOUR_PROJECT_API_KEY",
});

tracker.track("page.viewed");

// optional - attach context
tracker.track("page.viewed", {
  properties: { path: window.location.pathname },
});

// optional - single sender across tabs (browser only)
// const tracker = new Eventra({ apiKey: "YOUR_PROJECT_API_KEY", multiTabMode: "leader" });

Common patterns

Typical event shapes - same API as in Quick start above.

import { Eventra } from "@eventra_dev/eventra-sdk";

const tracker = new Eventra({ apiKey: "YOUR_PROJECT_API_KEY" });

// feature usage
tracker.track("feature.used", {
  userId: "user_123",
  properties: { feature: "dashboard" },
});

// page view (browser)
tracker.track("page.viewed", {
  properties: { path: window.location.pathname },
});

// API call
tracker.track("api.request", {
  properties: { endpoint: "/checkout", method: "POST", status: 200 },
});

// error
tracker.track("error.occurred", {
  properties: { message: "Payment failed", code: "PAYMENT_ERROR" },
});

Event format

This is what the SDK sends to /api/v1/ingest/batch. You never construct it by hand - the SDK handles batching, idempotency keys, and runtime detection.

{
  "sentAt": "2026-03-12T10:00:00Z",
  "sdk": {
    "name": "@eventra_dev/eventra-sdk",
    "version": "<sdk-version>",
    "runtime": "browser"
  },
  "events": [
    {
      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
      "name": "user_signup",
      "userId": "user_123",
      "timestamp": "2026-03-12T10:00:00Z",
      "properties": {}
    }
  ]
}

Limits enforced by the SDK at track() time:

FieldLimit
nametrimmed, ≤ 64 chars
userId≤ 120 chars
properties≤ 32,000 bytes (JSON serialized)
Property nesting depth≤ 8
Batch payloadmaxPayloadBytes (default 60,000)
Fetch timeout5,000 ms
Circuit breakeropens after 5 consecutive failures, cools down 5,000 ms

Reliability

  • Idempotency (UUID v4 per event, stable across retries)
  • Retry with exponential backoff + jitter (capped)
  • Circuit breaker with half-open recovery
  • Queue-based delivery (all runtimes)
  • Safe dequeue (events removed only after successful ingest)
  • Queue persistence (browser) with merge + cross-tab sync
  • Multi-tab leader election with re-election
  • fetch + keepalive on tab close (with x-api-key, size-checked)
  • pagehide + visibilitychange flush hooks
  • Property validation at track() (depth + size)
  • Payload byte limits per batch
  • Permanent error handling via onDeliveryFailed (401, 422, etc.)
  • Automatic requeue on network errors and 429 / 5xx
  • Oversize single events dropped via onDeliveryFailed(413)

The examples on this page are not everything Eventra supports. The SDK and CLI work with many other frameworks and runtimes - Vue, Angular, Fastify, Hono, Cloudflare Workers, and more.

Browse runnable examples on GitHub →
Data model

Platform concepts

Terms used across the dashboard, API, and documentation.

Workspace
Top-level organization that owns billing, members, and projects. Plan limits apply per workspace owner and member counts.
Project
Isolated analytics environment with its own event catalog, API keys, rollups, and dashboard views. One workspace can contain multiple projects on paid tiers.
API key
Project-scoped secret sent as x-api-key on ingest and CLI requests. Rotate keys from the dashboard without affecting other projects.
Feature
A tracked product capability derived from your event catalog. Rollups aggregate raw events into per-feature adoption and lifecycle signals.
Event
A single recorded usage signal. Delivered at runtime via the SDK (billable) or registered statically via the CLI catalog sync (non-billable).
Function wrapper
A helper function that calls Eventra.track() internally. The CLI registers wrappers and resolves propagation chains across files.
Resources

External links

API reference for authenticated dashboard routes is available via the running ingest API Swagger UI in development (/api/docs). Production ingest endpoint: https://api.eventra.dev/api/v1/ingest/batch.