RTN Docs

Web SDK · v0.6.0

Event Model

Understand event names, properties, identities, sessions, attribution, and the fields RTN adds automatically.

RTN represents a customer journey as a sequence of events. Your integration supplies the event name and business properties; the SDK supplies identity, session, page, campaign, and delivery metadata.

Event anatomy

This call:

rtn.track('promotion_clicked', {
  promotion_id: 'spring_homepage',
  creative: 'hero_a'
});

produces an event with the following shape. Fields under context are collected automatically.

{
  "message_id": "0192f8b5-...",
  "type": "track",
  "event": "promotion_clicked",
  "anonymous_id": "0192f8a1-...",
  "user_id": "customer_123",
  "session_id": "0192f8a4-...",
  "timestamp": "2026-10-23T12:00:00.000Z",
  "properties": {
    "promotion_id": "spring_homepage",
    "creative": "hero_a"
  },
  "context": {
    "library": { "name": "rtn-web", "version": "0.6.0" },
    "page": { "path": "/collections/spring", "title": "Spring collection" },
    "locale": "en-US",
    "timezone": "Europe/Istanbul",
    "attribution": {
      "first_touch": { "source": "google", "medium": "cpc", "click_id_type": "gclid", "landing_path": "/" },
      "last_touch": { "source": "instagram", "medium": "paid_social", "campaign": "spring", "landing_path": "/collections/spring" }
    }
  },
  "consent": {
    "analytics": "granted",
    "personalization": "pending",
    "advertising": "granted",
    "audiences": "pending",
    "replay": "pending"
  }
}

The consent block is the purpose-level snapshot taken when the event was created. See Consent.

Batch envelope

The SDK sends events in batches to POST {endpoint}/v1/batch. SDK 0.6.0 uses event contract v2:

{
  "schema_version": 2,
  "write_key": "WRITE_KEY",
  "sent_at": "2026-10-24T10:15:30.123Z",
  "batch": [ /* events */ ]
}
  • A batch holds up to 100 events and 500 KiB; a single event up to 32 KiB. The SDK keeps its batches inside these limits and drops a larger single event before sending it, reporting { type: 'event_drop', reason: 'too_large' } to onDiagnostic.
  • context.attribution is not on every event: it travels on the first event of a session, on order_completed, checkout_started and signed_up, and on every event until the ingest has accepted a new touch. The server keeps touches per anonymous ID.
  • The ingest edge answers 202 {"accepted": n, "rejected": m, "errors": [...]}. An invalid event is rejected on its own; valid events in the same batch are accepted.
  • Batches without a version and schema_version: 1 batches from older SDKs are still accepted. Unknown versions are rejected with unsupported_schema_version.
  • The edge adds received_at, ip_country, ip_city, and user_agent, and classifies attribution touches into platform and channel. Raw IP addresses are not stored.

What you provide

FieldGuidance
Event nameA completed action in lowercase snake_case, up to 64 characters
PropertiesBusiness facts needed to understand that action
Stable IDsYour product, cart, order, promotion, and customer IDs
MoneyNumeric values plus an ISO currency such as USD, EUR, or TRY

Do not generate message_id, anonymous_id, session_id, timestamps, page context, or attribution yourself.

Identity through the journey

Events begin with an anonymous ID. After identify, later events carry both the same anonymous ID and your customer ID.

// Anonymous browsing
rtn.productViewed({ product_id: 'sku_123', name: 'Everyday Backpack', price: 89.90 });

// The customer signs in
rtn.identify('customer_123', { email: 'alex@example.com' });
rtn.loggedIn('email');

// Later events now include user_id: "customer_123"
rtn.productAddedToCart({ product_id: 'sku_123', name: 'Everyday Backpack', price: 89.90 });

Call rtn.reset() at sign-out so the next visitor on the device receives a new anonymous identity.

Sessions and page context

A session renews after 30 minutes of inactivity or when a new campaign or referral starts a visit. The first event in a session includes context.session_start: true.

Page views are automatic by default. RTN observes initial loads and SPA navigation through pushState, popstate, and hash routes. Sensitive URL parameters and email-like values are redacted before delivery.

With consent pending, events remain in memory and no identity storage is written. Granting consent releases buffered events with their original timestamps; denying consent discards them.

rtn.productViewed(product);       // Buffered while consent is pending
rtn.setConsent('granted');        // Releases the buffered event
rtn.productAddedToCart(product);  // Sent normally

Delivery behavior

The SDK batches events and retries temporary network failures. Call flush() only when you must complete a send attempt before a controlled redirect.

rtn.checkoutStarted(cart);
await rtn.flush();
window.location.assign(paymentUrl);

Normal navigation does not need this; the SDK uses sendBeacon when the page becomes hidden.

Undelivered events wait in a per-tab localStorage queue (up to 1,000 events and 512 KiB). The SDK retries 408, 429, 5xx, network errors, and requests slower than 10 seconds with exponential backoff, honors Retry-After, and discards other 4xx responses and events older than 7 days. A new tab adopts the queue of a closed tab, and the backend removes duplicates by message_id.

On this page