@lodd/node
v0.2.1
Published
Server-side tracking SDK for Lodd — API, agent, MCP, and CLI events
Downloads
395
Maintainers
Readme
@lodd/node
Server-side tracking SDK for Lodd. Built for API, MCP, agent, and CLI products — the headless stuff nothing else tracks well.
Install
npm install @lodd/nodeQuick start
import { Lodd } from "@lodd/node";
const ca = new Lodd({
apiKey: process.env.LODD_API_KEY!, // ca_... from your Lodd dashboard
siteId: process.env.CA_SITE_ID!, // UUID of the site to report to
});
ca.track("api_call", { endpoint: "/v1/search", duration_ms: 42 });
// On graceful shutdown
await ca.close();Express middleware
import express from "express";
import { Lodd } from "@lodd/node";
import { caExpress } from "@lodd/node/express";
const app = express();
const ca = new Lodd({ apiKey, siteId });
app.use(caExpress(ca, {
ignore: (req) => req.path === "/health",
}));The middleware captures path, method, status, and duration_ms. It never captures query strings, request bodies, or headers.
Options
| Option | Default | Notes |
|---|---|---|
| apiKey | — | Required. |
| siteId | — | Required. Overridable per track() call. |
| baseUrl | https://api.lodd.dev | Production proxy. Override to point at a local Supabase stack (e.g. http://127.0.0.1:54321) or an alternate deploy. |
| maxBatchSize | 50 | Events queued before forced flush. |
| flushIntervalMs | 5000 | Timer-based flush cadence. |
| onError | console.warn | Called for dropped events or failed batches. |
Guarantees
track()never throws.- Events >8KB of properties are dropped (with
onError). - Failed batches are retried up to 3× with exponential backoff; then dropped.
close()flushes any queued events.
Session granularity
Server-side events don't have natural session boundaries, so the SDK synthesises a session_id deterministically from user_id + site_id + UTC date. This makes Daily Active Users correct out of the box, but a single user active across multiple UTC days will count as multiple unique_visitors in weekly/monthly range aggregations. Supply your own session_id in a future ca.track() overload if you need different granularity.
