ingestlayer/docs

docs · 04 reference

TypeScript SDK.

One package, three functions. init once, track anywhere, flush when you can't lose events. The SDK handles auth, batching, and retries on transient errors.

Install

One dep, one env var.

install
$ pnpm add @ingestlayer/sdk
# or: npm install @ingestlayer/sdk · yarn add @ingestlayer/sdk

# .env
INGESTLAYER_KEY=il_live_***

Works in Node 18+, Bun, Deno, Cloudflare Workers, and modern browsers — no dependencies, uses global fetch. Pass your key to init({ apiKey }) at startup; read it from INGESTLAYER_KEY or wherever you keep secrets.

track()

Init once, then track.

basic · one event
import { init, track } from "@ingestlayer/sdk";

init({ apiKey: process.env.INGESTLAYER_KEY! });

track({
  type: "user.signup",
  icon: "🎉",                       // optional — shown next to the event
  payload: {
    email:  user.email,
    plan:   user.intendedPlan,
    source: "marketing-site",
  },
});

track(event) enqueues one event and returns immediately — delivery happens on the next flush (by batch size, timer, or an explicit flush()). The event shape is { type, icon?, payload?, idempotencyKey?, timestamp?, entity? }.

full event · idempotent + backdated
track({
  type:    "order.placed",
  icon:    "💸",                    // emoji glyph for the dashboard + valve app
  payload: { order_id: o.id, amount: o.amount, currency: o.currency },
  idempotencyKey: o.id,            // dedupe at the gate
  timestamp:      o.created_at,    // backdate to when it happened
  entity:  { kind: "account", id: o.account_id },  // enrichment hint
});

icon is an optional emoji shown next to the event in the dashboard and the valve app. idempotencyKey dedupes at the gate over the configured window — usually 24h. timestamp overrides the received_at; defaults to now(). entity is an enrichment hint pipelines can match on.

flush()

Batch, then guarantee.

buffer + flush
import { track, flush } from "@ingestlayer/sdk";

for (const u of newUsers) {
  track({ type: "user.signup", payload: { email: u.email } });
}

// track() buffers and flushes on size/timer; await flush() to
// guarantee delivery (e.g. at the end of a cron job or before exit).
await flush();

Events batch automatically (default: 50 events or 2s). On Node and in the browser the SDK installs a best-effort flush on shutdown, but the only hard guarantee is an awaited flush() — call it in cron jobs, imports, or any path where losing events is unacceptable.

Errors

Failures surface, don't throw.

error handling
import { init } from "@ingestlayer/sdk";

init({
  apiKey: process.env.INGESTLAYER_KEY!,
  onError: (err, events) => {
    // Called for every batch that ultimately fails after retries.
    // Persist offline, alert, or drop — your call.
    console.error("ingestlayer dropped", events.length, err.message);
  },
});

Because track is fire-and-forget, delivery failures don't throw at the call site. The SDK retries transient errors (5xx, 408, 429) with exponential backoff; a batch that still fails is handed to your onError callback so you can persist offline or alert. 4xx client errors aren't retried.

Browser

The same call, with caveats.

The SDK works in browsers, but you probably don't want your INGESTLAYER_KEY in client bundles. Use a thin server proxy that forwards authenticated calls, or scope keys narrowly per-environment and accept the visibility tradeoff.


template syntaxback to docsnext: REST API