Skip to main content

What these SDKs do

The trodo-node and trodo-python packages send analytics from your servers to Trodo’s write API (the same HTTP surface as the browser SDK’s apiHost). They are built for:
  • API services, workers, and background jobs
  • Correlating backend actions with the same site as your web or mobile app
  • People and groups updates without loading the browser bundle
They are not a replacement for the browser SDK for web UX signals (page views, clicks). Use both where it makes sense: browser for product surface, server for authoritative backend events.

Architecture

Production traffic goes to the dedicated ingestion host:
ConceptDefault value
API base URLhttps://sdkapi.trodo.ai
Site identificationHTTP header X-Trodo-Site-Id: <your site id> (same ID as the frontend site-id)
Payload formatJSON (Content-Type: application/json)
Locally, when you run the split backend_sdk write service (see repo docs/BACKEND_SPLIT.md), point apiBase / api_base at http://localhost:8001. Under the hood, the SDKs call routes such as:
  • POST /api/sdk/track — register the server session (once per in-memory session)
  • POST /api/events — single custom event
  • POST /api/events/bulk — batched events (when batching is enabled)
  • POST /api/sdk/identify, /reset, /wallet-address
  • POST /api/sdk/people/* and POST /api/sdk/groups/*

Install

npm install trodo-node
Requirements: Node 16+; 18+ recommended (built-in fetch). On Node 17 and older, install optional node-fetch (see package peer dependency).The published package name is trodo-node. Import the client class or the default singleton-style export.

Initialize the client

Both SDKs support:
  1. TrodoClient / TrodoClient instance — explicit, testable, multiple instances if needed
  2. Module-level singletoninit(...) then forUser / for_user (mirrors the frontend pattern)
import { TrodoClient } from 'trodo-node';

const client = new TrodoClient({
  siteId: process.env.TRODO_SITE_ID!,
  apiBase: process.env.TRODO_API_BASE ?? 'https://sdkapi.trodo.ai',
  timeout: 10000,
  retries: 2,
  batchEnabled: false,
  batchSize: 50,
  batchFlushIntervalMs: 5000,
  autoEvents: false,
  onError: (err) => console.error('[trodo]', err),
  debug: false,
});
Singleton style:
import trodo from 'trodo-node';

trodo.init({ siteId: 'your-site-id' });
const user = trodo.forUser('distinct-id-123');
await user.track('server_job_completed', { job: 'sync' });

Configuration reference

OptionNode (TrodoConfig)Python (TrodoClient.__init__)Notes
Site IDsiteIdsite_idRequired
API baseapiBaseapi_baseDefault https://sdkapi.trodo.ai
HTTP timeout (seconds)timeout (ms)timeout (seconds)Node default 10000 ms; Python default 10 s
RetriesretriesretriesBackoff on network errors and 5xx
Batch modebatchEnabledbatch_enabledUses POST /api/events/bulk
Batch sizebatchSizebatch_sizeFlush when queue reaches this count
Flush intervalbatchFlushIntervalMsbatch_flush_intervalPeriodic flush (seconds in Python)
Auto error eventsautoEventsauto_eventsSee People, groups & lifecycle
Error callbackonErroron_errorInvoked after retries exhausted (Node: Error; Python: any exception)
Debug loggingdebugdebugLogs requests/errors to stderr

Primary API shape: forUser / for_user

The recommended pattern is to obtain a user-scoped context once per logical user (your distinct_id), then call track, identify, people, and groups on that context.
const user = client.forUser('user-42', {
  sessionId: optionalBrowserSessionUuid, // optional: merge with frontend session
  distinctId: optionalOverride,
});

await user.track('invoice_paid', { amount_cents: 9999 });
await user.identify('acct_01HXYZ');
await user.people.set({ plan: 'pro' });
Session correlation: pass a browser session id (from your cookie or header) as sessionId / session_id so backend events attach to the same session as the web SDK when possible. There is also a direct-call style on TrodoClient (e.g. track(distinctId, eventName, ...), people_set, set_group) for concise one-off calls. Behavior matches the user context API.

Naming conventions

  • Node uses camelCase for methods and options (forUser, batchFlushIntervalMs).
  • Python uses snake_case (for_user, batch_flush_interval).
Concepts (distinct id, session id, event names) are the same across languages and match the browser documentation in Events and properties and Identify.

Next steps