Server-side

Track from your backend. Land on the same person.

A zero-dependency Node SDK that captures events where ad blockers can't reach, and joins them to the same identity as the browser session.

server · oakdata-node
oak.capture("invoice_paid")
distinctId: user_8f3a
+$199
batch flushed
24 events · 180ms
ok
retry
1 event redelivered after timeout
ok

Same person as the browser session. Zero dependencies.

What you get

Zero dependencies

The oakdata-node SDK ships with no dependencies at all. Nothing to audit, nothing to break.

One identity, both sides

Pass the same distinctId and a backend invoice_paid lands on the person's browser-session profile.

Batching and retries

Events queue, batch, and retry automatically. A blip in connectivity doesn't lose data.

Unreachable by ad blockers

Server events never touch the visitor's browser, so blockers and privacy extensions can't drop them.

Built for webhooks

Stripe webhooks, background jobs, cron tasks. Capture the events that never had a browser session.

REST API underneath

Not on Node? The same capture endpoint is plain HTTP, so any language can send events.

Why client-side tracking isn't enough

The events that matter most increasingly don't happen in a browser. Subscriptions renew via webhook, invoices get paid from an email link, trials expire in a cron job. Client-only analytics never sees any of it. And for the events it does see, ad blockers take a growing bite out of the numbers.

Server-side tracking fixes both. Events are captured from your infrastructure, where nothing can block them, and OakData joins them to the same person as their browser history through a shared distinctId.

The whole journey, browser and backend

The payoff is one unbroken record per person. Anonymous first visit, docs session, signup in the browser. Then invoice paid, plan upgraded, seat added on the server. Funnels can span both worlds, revenue attribution stays correct even when the purchase never touched a page, and churn signals from your backend sit next to the sessions that preceded them.

Questions

Through the distinctId. Identify a user in the browser with oak.identify(), then pass the same ID when capturing from the server. Both streams land on one profile with one unbroken timeline.

None. oakdata-node is zero-dependency by design, with batching, retries, and flush control built in.

No. They're sent from your servers directly to OakData and never pass through the visitor's browser, so blockers and privacy extensions can't intercept them.

Yes. The capture endpoint is a plain REST API, so any language that can make an HTTP request can send events. The Node SDK is a convenience layer on top of it.

Related

Try it

Server-side tracking is five minutes away.

One snippet, every feature, at every tier. Free for the first 14 days.

14-day free trial