What this lets you do
Send the same pageviews and revenue conversions from wherever your code runs: the browser snippet’swindow.traceten global for client-side tracking, or a server SDK for delivery that ad-blockers and privacy browsers cannot strip.
Pick your SDK
The browser SDK is the right default for most sites. Reach for a server SDK when the snippet cannot run, or when you need delivery that survives ad-blockers.Browser (JavaScript)
The
window.traceten global the snippet installs. Pageviews, custom events with revenue,
identify, and consent.Node.js
@traceten/sdk-node. Node 18 or newer.Python
traceten on PyPI. Python 3.9 or newer.Go
github.com/traceten/traceten-go. Go 1.21 or newer.Browser vs server
Many sites run both: the browser SDK for standard client-side tracking, and a server SDK for the conversions that must not be lost.
The server SDKs share one contract
All three server SDKs (Node, Python, Go) implement the same contract: the same methods, the same defaults, the same batching and retry behavior. Only the naming follows each language’s idioms. Every server SDK exposes three methods that map to the three ingestion endpoints:page() and track() buffer the event and return immediately. A background worker batches, retries, and flushes without blocking your request path. You call flush() to send everything queued now, and close() to flush and stop the background worker on shutdown.
payment() is different, and deliberately so. It sends immediately, waits for the answer, and returns it. The Payment API is idempotent on the transaction id, and that answer, whether the payment was recorded or was one we already had, is the point of the call. A queue could not hand it back to you. It is also the only method that reports a delivery failure to the caller: a dropped pageview is a dropped pageview, but a dropped payment is missing revenue.
You supply the visitor id
Because a server SDK runs on your server, there is no Traceten cookie and no DOM. The two identifiers the browser snippet derives client-side,visitor_id and session_id, do not exist server-side. You supply them from your own request context. The SDK never fabricates a visitor id.
A visitorId is either a canonical UUID or the identify-hash form h:<64-hex>. It is optional on page() and on payment(), and required on track(), because a conversion cannot be attributed without it. On payment() you can supply the customer’s email instead, and if you supply neither the payment is recorded as unattributed revenue. The robust way to get these values is window.traceten.getVisitorId()/getSessionId(), called client-side and forwarded to your backend. They always resolve the current cookie, so they survive you turning cross-subdomain cookies on or off later. If you read the cookies by name instead, the name depends on the site’s cookie scope: cross-subdomain cookies are off by default, giving plain _traceten_vid/_traceten_sid; once you confirm a value under Sites → Settings → Cookies, it becomes _traceten_vid_/_traceten_sid_ followed by eight characters of your site key. Your install page and Settings show the exact current name. Read that name exactly rather than by prefix: two Traceten sites under one registered domain each set their own cookie, and a prefix match picks whichever the browser lists first.
Authentication
Every server SDK requires an API key. Set it on the constructor (apiKey in Node, api_key in Python, WithAPIKey in Go) and the SDK sends it as Authorization: Bearer <key> on every request.
The key is a secret. Keep it on your server: never in client-side code, a mobile app, or a public repository. It is not the same value as siteId, which is public and already embedded in every page that runs the snippet.
The server SDKs post to /v1/server/events, /v1/server/conversions and /v1/server/payments, which return 401 without a valid key. /v1/events and /v1/conversions remain open, because the browser snippet shares them and cannot hold a secret.
Two things the key buys you:
- Access. The authenticated endpoints reject unauthenticated requests.
- Your own ingestion quota. Traffic that arrives with a valid key is rate-limited on a bucket tied to that key, separate from the shared per-site bucket. Because
siteIdis public, anyone who can read your page source can send events under it; with a key, that traffic cannot exhaust your allowance and 429 the conversion calls that carry your revenue data.
ingest:write). New keys are created read-only by default, so tick that box when you create one, or the API will reject your calls. The key created automatically with a new site already has it. See permissions.
To rotate a key: create the new one, deploy it, then revoke the old one. Revocation normally takes effect at the edge within about a minute. If our
database is unreachable at that moment, an edge location that was already using
the key may keep honouring it for up to about fifteen minutes more, so that a
database blip cannot silently drop your events.
The same API keys also authenticate the account-level data deletion and access endpoints.
Privacy
Traceten is privacy-first, and server-side sending puts that in your hands. Two rules carry across every server SDK:- Keep
visitorIdopaque. Use a random first-party id or a salted hash you control. Never pass a baresha256(email)or any hash of an email or phone number, which is re-identifiable PII. The SDK enforces the shape (UUID orh:<64-hex>) but cannot see what you hashed. - Keep
propertiesopaque. Use ids and enums such as{ "plan": "pro" }. Do not put emails, names, or phone numbers inproperties.

