Skip to content
Last updated

Real Time Personalization 2.0 Client Side Use Case Guide

Introduction and Overview

Real-time Personalization 2.0 (Client-side) empowers web and marketing teams to deliver instant, highly tailored experiences directly from the browser. This modern data engine enables your website or CMS to personalize content dynamically for each visitor, instantly reflecting the latest customer profile attributes, behaviors, and audience segment memberships.

Unlike traditional server-side personalization—which routes every request through an intermediary backend—client-side Real-time Personalization 2.0 allows JavaScript running in the user’s browser to securely fetch personalization payloads from Treasure Data’s API, eliminating extra network hops and reducing latency. This approach unlocks rapid UI updates and enables powerful in-page personalization scenarios—such as showing targeted offers, product recommendations, or loyalty banners as soon as the user lands or interacts with your site.

With the client-side edition, all API calls originate from the web browser and are served from CORS-enabled endpoints using public tokens, with built-in safeguards to ensure that only non-sensitive (non-PII) data is ever delivered to the front end. This guide focuses exclusively on browser-based integration, giving clear step-by-step instructions for enabling client-side personalization safely—including walkthroughs on token configuration, attribute sensitivity controls, UI setup, and best practices for privacy and compliance.

You may also explore our separate documentation for server-side integrations, but this guide is designed for developers, data engineers, and marketers who want to power direct, real-time personalization in the browser—supporting modern commerce, content, and engagement experiences on the web.

Through this step-by-step guide, you’ll learn how to build and implement client-side Real-time Personalization 2.0 use cases on your web application, from event tracking and attribute setup to audience segmentation, personalization design, and secure in-page integration.

Step 1: Data Ingestion and API Options (Client-side)

Client-side real-time personalization enables web applications to deliver fully dynamic, personalized experiences directly from the user’s browser. This section explains how to safely and effectively send event data from browser JavaScript to Treasure Data’s platform for real-time audience evaluation and personalized payload delivery—while maintaining best practices in privacy, compliance, and data architecture.

Data Flow and Event Ingestion for Client-integrated Personalization

In a client-side setup, events such as page views, clicks, signups, or product interactions are captured by browser JavaScript running on your site. These events are then transmitted directly to Treasure Data’s Personalization API via secure, CORS-enabled endpoints. No intermediary server is required, minimizing latency and unlocking “instant” UI updates for web personalization use cases.

  • Event Examples: page views, item clicks, cart additions, conversions, custom engagement milestones.

  • Typical Workflow:

    • Capture relevant events with custom JavaScript, a tag manager, or TD’s JS SDK (once updated for M2).

    • Package each event with relevant identifiers (e.g., anonymous ID, td_client_id), context (URL, path), and any non-sensitive attributes needed for personalization.

SAFE Data Submission: Only Non-Sensitive Data in the Browser

Do not send sensitive PII or confidential business logic directly from the browser.

All event data submitted client-side should be strictly non-sensitive. For sensitive data, use a server-side ingestion path instead.

  • Safe fields: anonymous user IDs, high-level behavior (e.g., td_path, product category)

  • Unsafe fields: email address, phone number, raw personal identifiers, or confidential business logic

Choosing the Right API: Personalization API vs. Ingest API

There are two main event ingestion methods:

  1. Personalization API (Client-side focus)

    • Use case:

      • Send an event and receive personalization offers instantly, in a single HTTP POST request from the browser.

      • Used for real-time, dynamic content updates on page load or user interaction.

    • Response:

      • Contains only non-sensitive attributes/segments. If any offer contains sensitive data (per attribute sensitivity in setup), it is replaced with {} in the response.
    • Endpoint:

      • Public, CORS-enabled URL (e.g., /public/{db}/{table})

      • Requires a public type token in the WP13n-Token header.

    • Security Considerations:

      • Only use public tokens in browser code. These have no IP whitelist and must be created as “public” at the service level. Private tokens will generate an error in the browser logs and will not return an offer.
  2. Ingest API

    • Use case:

      • Submit events via backend/server for storage and later segmentation.

      • Does not return a personalization payload.

    • When to use: For sensitive or regulated data that should not transit the browser, or to capture raw logs for batch analysis.

API Request and Example

A client-side “fetch” example (assuming future JS SDK support, or use with window.fetch):

fetch('https://us01.p13n.in.treasuredata.com/public/<YOUR_DB>/<YOUR_TABLE>', {  
  method: 'POST',  
  headers: {  
    'Content-Type': 'application/vnd.treasuredata.v1+json',  
    'WP13n-Token': '<ACCOUNT_ID>/<REACTOR_ID>/<PUBLIC_TOKEN>',  
    'Authorization':'TD1 <WRITE API KEY>'  
  },  
  body: JSON.stringify({  
    td_client_id: '1234-5678-9012-3456',  
    td_url: window.location.href,  
    td_path: window.location.pathname,  
    // ... additional non-sensitive event fields  
    })  
  })  
  .then(res => res.json())  
  .then(data => {  
    // data.offers: personalized sections  
  }  
);  

Notes:

  • Do not include: Private tokens in browser-side requests for any reason.

  • Validate: Token must be public, origin must be allowed, and only non-sensitive data will be returned in response.

CORS and Security Controls

  • API endpoints validate both the Origin header and the token’s public/private status.

    • With a valid public token and valid Origin, API responds with CORS headers and the offer payload.

    • With an invalid token, private token, or invalid Origin, response is 4xx and no CORS headers are sent.

  • Client-side endpoints only support public tokens; attempts to use private tokens from the browser will fail.

Segment and Table Mapping

  • As with client-side setups, each behavioral event should be mapped to a clear, separate table supporting downstream “parent segments” for real-time audience logic.

  • Parent segment and table definitions must be set up in advance within TD Console's UI.

  • All mapping, updating, and event configuration for client-side events is managed within the UI—no backend required for standard integrations.

Best Practices Checklist

  • Only publish non-sensitive data from browser JavaScript

  • Always use CORS-enabled public endpoints and public tokens

  • Map each behavioral event type to an appropriate table for clear audience segmentation

  • For any data that requires privacy, rules, or access control: use server-side ingestion, not the browser

Summary Table: Client-side Data Ingestion Comparison

OptionSourcePersonalization ResponseToken TypeEndpoint PathUse Case
Personalization APIbrowser JSYes (real-time)Public Only/public/db/tableReal-time browser UX personalization
Ingest APIbackendNo (store only)Private/recordsSensitive, server-logged, compliance data

Step 2: Configuring Real-Time Personalization in the UI (Client-side)

Configuring client-side Real-Time Personalization 2.0 in Treasure Data’s UI introduces a distinct set of requirements and workflows, focused on ensuring browser security, privacy compliance, robust governance, and seamless end-to-end enablement. This section outlines the full user experience and system constraints for creating and managing client-side personalizations.

Enabling Client-Side Personalization Features

  • In order to enable client-side (browser-based) integration, your account must have both the global Real-Time Personalization 2.0 feature flag and the M2 client-side feature flag activated (e.g., eng-lc-realtime-personalization-m2-1 for service/tokens and eng-lc-realtime-personalization-m2-2 for attribute-level PII sensitivity configuration). Without these flags, UI options for public services and sensitive attribute marking will not be visible.

Workflow: Creating a Public Personalization Service

  1. Create a Parent Segment - Start by creating or selecting a Parent Segment in Audience Studio—this segment forms the basis for your personalization logic.

  2. Create New Personalization Service (Public for Client-side) - Navigate to the "Personalization Configuration" for your segment. - Click "Create new personalized service." - In the modal, you are prompted to choose a “Service Type”: - Public (publishing) for client-side use. - Private for server-side only. - Critical: The type (public/private) is immutable—you cannot change it after service creation. Choose carefully based on your intended integration pattern.

  3. Name, Describe, and Validate - Enter a unique name (max 100 characters) and optionally a description. - Duplicate names or names exceeding the character limit will throw UI validation errors: “Name has already been taken,” “Name is too long (maximum is 100 characters),” etc. - Required fields must be completed, or the UI will block creation and show helpful error labeling.

  4. Add Tokens - After creating the public service, add one or more tokens for browser use. - Each token must also have a unique name (with similar validation). - For public services and tokens: - No Allowed IPs (IP whitelisting) can be set. Attempts to provide allowed IPs will fail with a validation error: “Allowed ips must not be set when the parent service is public”. - These tokens can be safely embedded in client JavaScript. - For private services, IP whitelisting is available.

  5. Token Format and Limits - Each API token is in the format: [ACCOUNT_INSTANCE_ID]/[REACTOR_INSTANCE_ID]/[RT_PERSONALIZATION_TOKEN] - Limits: Up to 50 tokens per service, 200 per parent segment.

Security, Immutability, and Governance

  • Public tokens are the only tokens that the browser can use. Private tokens are strictly backend/server-only.

  • Once created, public/private status cannot be changed.

  • UI restricts editing of service type post-creation (edit modal disables this field).

  • Attempting to add or edit tokens in violation of these constraints triggers explicit UI/API errors.

Token Management & UI Details

  • Manage tokens for each public service in the side panel.

  • Tokens can be deleted and re-created within allowed limits.

  • If a user’s session expires, viewing tokens triggers a password/SAML/SSO prompt before secret visibility will be re-granted (for security).

Feature Flag and Role Controls

  • Ability to create/view/edit public services or mark attributes as sensitive depends on feature flag rollout and account/user permissions.

  • Users without sufficient privileges see descriptive errors and are blocked from configuration actions: “You do not have permission to perform this action.”

Validation, Error Handling, and UI Aids

  • UI includes real-time form validation for all fields—no blank names, no duplicates, strict character limits, and clear feedback for validation failures.

  • Attempting to perform actions not permitted by the system design yields exact error messages.

  • For import and attribute management, see "Defining Events and Attributes" (next section) for per-attribute sensitivity and further compliance controls.

Summary Table: Key UI Behaviors for Client-Side Personalization Setup

TaskPublic Service/TokenPrivate Service/Token
Service Type Editable?NoNo
Allowed IPs (token)Not permittedPermitted
Token UseBrowser JS onlyBackend/server only
Delete/Add tokensAllowed, within limitAllowed, within limit
Maximum tokens/service5050
Validation: Name/DescriptionEnforcedEnforced
Session Expiry BehaviorSSO/Password promptSSO/Password prompt

Best Practices

  • Use clear naming conventions to distinguish between public (client) and private (server) services.

  • Never attempt to reuse a token or service for both environments; maintain strict separation.

  • Educate your teams and downstream integrators on the immutability of these configurations to avoid orchestration and rollout issues.

  • Leverage built-in UI validations for error-free setup.


Step 3: Defining Events and Attributes (Client-side)

After you set up your client-side Real-Time Personalization service, the next step is to define which browser events to capture and configure the set of real-time attributes that will drive your in-page personalization logic. This process is similar in spirit to the server-side approach but introduces strict privacy, UI, and governance controls to ensure non-sensitive, browser-safe operations.

Events Table and Event Definition

In the Real-Time Configuration section, you will select or register tables that represent the behavioral events sent from your website or web app. Common event examples for client-side personalization include:

  • Page views (e.g., homepage, category, product)

  • Clicks (product details, add-to-cart, banners)

  • Website signups or logins (as long as no PII is exposed)

  • Custom actions (e.g., completed video, downloaded asset)

To define a new event:

  • Click “Create new event” in the Events area of the configuration UI.

  • Choose the relevant data table that is used to store that event stream.

  • Give the event a descriptive name for downstream reference (e.g., “product_page_view”).

  • (Optional) Filter events: You may define additional filters—such as by URL path or query (e.g., td_path regex: ^/retail/./product/.)—to only include specific event types for personalization.

Best Practices: - Organize each event type in a clear, separate table to enable granular audience segmentation and easier troubleshooting. - If you are reusing batch tables for real-time, ensure no sensitive identifiers are sent from the browser.

Defining Attributes with Sensitivity

A core difference for the client-side product is the explicit requirement to classify the sensitivity for Single, List, and Imported attributes at creation (or during follow-on editing). Only non-sensitive attributes are ever returned in API payloads to the browser.

Attribute Types

  • Single: Stores the most recent value (string or numeric) for each visitor. Useful for tracking last viewed product, current page, or most recent category. Mark as Non-Sensitive only if it cannot reveal private information (e.g., avoid PII like emails or phone numbers).

  • List: Maintains a bounded array (up to 100 items) for each visitor (e.g., recent products viewed, categories viewed). Each item expires after 60 days. If the data in the list could be sensitive (e.g., user IDs, emails), mark as Sensitive; otherwise, Non-Sensitive.

  • Counter: Increments a numeric counter for event frequency (e.g., number of visits in the last 7 days). Counters are always considered Non-Sensitive and cannot be flagged as Sensitive in the UI.

  • Imported Batch: For batch attributes imported from offline or back-office sources (such as loyalty tier, batch segment membership). You must set the sensitivity flag as appropriate. Only Non-Sensitive imported attributes are returned to browser clients via the Personalization API.

Attribute Sensitivity and API Response

  • Non-Sensitive: If all referenced attributes in a “payload section” are Non-Sensitive, they may be returned to the client.

  • Sensitive: If any attribute in a personalization payload section is Sensitive, the section is redacted in the API response ({} is returned) for any client-side (public token) request.

  • UI Enforcement: The attribute creation/edit form will require explicit selection of Sensitivity.

  • Review and Audit: The UI flags which attributes are Sensitive and which are safe for client use. Double-check attribute lists before go-live.

Understanding Attribute Types and Design (Client-side)

Single Attributes

  • Track only the latest value for a property (e.g., “last_category_viewed”).
  • Avoid Single attributes that could leak PII (never store email, phone, or other identifiers you would not want exposed to front-end code).
  • Naming tip: Use clear, non-colliding names to avoid confusion with batch or server-side attributes.

List Attributes

  • Designed for session or recency use cases (e.g., “recent_products_viewed”).

  • Store string or numeric arrays only.

  • Remember: Properties (like price or URL) can be mapped as arrays, preserving entire lists, but only “flattened” for aggregations where string is the primary field.

  • If list items reference any sensitive data, the whole attribute must be marked as Sensitive.

  • To indicate the number of sensitive aggregations, use the format x/y Sensitive. For example, if you specify 1/5 Sensitive, it means that 1 out of the 5 aggregations is sensitive. If only the 4 non-sensitive aggregations are included in the payload, the response will contain those 4 attributes in the offers.

Counter Attributes

  • Count or sum event occurrences (e.g., “page_views_last_7_days”).

  • Must be Non-Sensitive; provides limited risk as they expose only aggregate behavior.

  • Supports sliding window (rolling) and total/cumulative options with fixed maximum durations.

Imported Batch Attributes

  • Added to real-time payloads only if included in the parent segment.

  • Must be explicitly configured and have their sensitivity set at import.

  • Not updated via real-time browser events; refresh only when batch segment re-runs.

  • Removing an imported batch attribute from the parent segment without updating RT config causes errors; fix this by re-adding, rerunning the parent, or creating a dummy entity if needed.

Attribute Design Best Practices (Client-side)

  • Sensitivity First: Always assume the browser API can be inspected by the end user. Never mark any attribute as Non-Sensitive if it contains or could infer PII or confidential business logic.

  • Naming Discipline: Prepend or suffix “rt” or “client” to client-side attributes for traceability.

  • Window Size Planning: Especially for lists and counters, pick durations that balance personalization value with security/compliance.

  • End-to-End Testing: Use the UI and API preview to verify only intended non-sensitive fields are exposed in the browser response.

  • Change Management: Any attribute’s sensitivity can be updated (where supported) if requirements change, but corrections require API/UI edits and may cause temporary section redactions if misconfigured.

  • Avoid Collisions: Carefully distinguish client-side vs. batch/server-side attributes to prevent confusion in Audience Studio or API payloads.

Summary Table: Attribute Types and Sensitivity Handling

Attribute TypeSensitivity Required?Client-side ExposureNotes
SingleYesNon-Sensitive onlyLast value per profile
ListYesNon-Sensitive onlyArray, 100 max, 60-day expiration
CounterAlways Non-SensitiveNon-Sensitive onlyCount/aggregate only
Imported BatchYesNon-Sensitive onlyReference, not updated via RT browser events

Step 4: Profile Unification and ID Stitching (Client-side)

Profile unification—commonly referred to as ID Stitching—ensures that all browser-driven and batch events relating to a customer are consolidated into a single, unified profile. This section details how to configure stitching for client-side integrations.

What Is Profile Unification in Client-side Personalization?

In client-side personalization, customers may interact with your website from multiple devices or browsers—sometimes anonymously, sometimes after authentication. Unifying these touchpoints provides the basis for delivering relevant, real-time personalized experiences and accurate audience segmentation, even as users switch contexts.

ID stitching connects identifiers found in events (for example: anonymous browser IDs, first-party cookies, or, where permitted, non-sensitive customer IDs) so that all browsing behavior, segment membership, and contextual attributes are resolved to a single customer profile.

How to Set Up ID Stitching (Client-side)

  1. Select Appropriate Identifiers for the Browser
  • Only use IDs that are non-sensitive and safe to expose client-side. Common examples:

    • td_client_id (anonymized, system-assigned)

    • First-party browser or session cookies (where not PII)

    • Site-specific visitor IDs

  • Do not use emails, hashed PII, or raw user information in browser events or as stitching keys for client-side personalization.

  1. Define ID Stitching Keys in the Real-Time Configuration UI
  • In the “ID Stitching Keys” section, add the non-sensitive client-side identifiers you intend to stitch on.

  • Optionally, configure regular expressions to filter or format incoming IDs for standardization.

  • Advanced: Mark keys as “workflow only” if they should be used exclusively for batch/staging, not real-time browser events.

  1. Set the Primary Key
  • After defining eligible keys, select a unique, persistent, and stable identifier as the primary key for stitching.

    • This key must be present in all (or nearly all) client events, and must not change unexpectedly.

    • Example: td_client_id serves well if set for every browser session/user.

  • The unification system will merge profiles by assigning the oldest primary key as the canonical profile, consolidating events and attributes accordingly.

  1. Save and Validate the Configuration
  • Once stitching keys and the primary key are configured, save and relaunch the profile unification workflow as prompted.

  • Caveat: Changing the primary key after activation requires reprocessing of profiles and may lead to temporary segmentation gaps.

Client-side ID Stitching: Privacy and Compliance Caveats

  • ALL identifiers used for client-side stitching should be “non-sensitive”—never include, transmit, or stitch on emails, phone numbers, addresses, or any direct/hashed PII from the browser.

  • Review local legislation (GDPR, CPRA, etc.) and your privacy policy to ensure customer consent mechanisms are honored for any cross-device/user stitching.

  • Temporarily-issued, session-only, or device-scoped identifiers are recommended for most client-side flows.

Best Practices and Common Scenarios

  • Plan ahead for cross-device users: If you want to enable identity resolution (e.g., anonymous user who later logs in), ensure any browser identifier maps cleanly to a first-party, non-sensitive key that can later be associated with an authenticated profile (in compliance with your privacy policy).

  • Audit your identifier fields: Before go-live, double-check that no field referenced as a stitching key is, or could be derived from, PII.

  • Filtering test/bad values: Use filtering regex or value exclusions to omit identifiers used for bot traffic, tests, or invalid sessions, maintaining a clean stitched population.

Example:

If a user browses anonymously with td_client_id=a123 and later logs in under a system-generated user ID (but never exposes their email in events), both sessions can be stitched and unified under the oldest known identifier if you have reliable mapping through non-sensitive keys.

System Constraints

  • Up to 200 stitching keys allowed per parent segment.

  • Each profile must always resolve to a single, unique, non-PII primary key within the segment.

  • Changing primary key post-deployment requires a re-launch of profile stitching for consistency.

Summary Table: ID Stitching in Client-side Integrations

StepClient-side Guidance
Allowed ID TypesNon-sensitive browser IDs, anonymous tokens, non-PII user IDs
Prohibited ID TypesEmails, phone numbers, hashed PII, any sensitive attributes
Config UI BehaviorsExplicit sensitivity warnings; non-editable after activation; validation in UI
Max Stitching Keys200
Key AssignmentChoose unique & stable; avoid changing after go-live
Merging LogicSystem designates oldest ID as canonical profile

Step 5: Audience Studio – Building and Managing Personalizations (Client-side)

After your event tables and real-time attributes are configured—and sensitivity has been set for each attribute—the next step is to design and launch client-ready personalization logic in Audience Studio. This phase dictates how the right offers, content, or experiences are served to each web visitor via safe, real-time API responses. For the client-side product, every workflow is optimized to maximize privacy, ensure non-sensitive payload delivery, and provide UI indicators to help you audit exposure risk.

Creating and Managing Client-Safe Personalizations

  1. Access the Parent Segment and Start a New Personalization - In Audience Studio, select your designated parent segment. - Click “Create” and select “Personalization.” Enter an intuitive name and optional description for future reference.

  2. Define Criteria and Payload for Each Section - Open the new personalization in the Personalization Canvas. - Add one or more “sections.” Each section has: - Criteria: Rules that determine when this personalization fires (e.g., “is_new_visitor = true”). - Payload: The actual data/offers sent to the browser when criteria match—built from batch segments and real-time attributes you’ve configured.

  3. Attribute Sensitivity Drives Payload Visibility - For client-side endpoints, only sections containing exclusively non-sensitive attributes will return payload data to the browser. - If ANY attribute (single, list, or imported batch) in the section is marked Sensitive, the entire section will be redacted: API returns {} for that section. - The UI displays visual cues (e.g., shield or lock icons) to warn when a section’s output will be blanked for browser/public token requests. Always use these cues to verify which offers are actually publishable to web users.

  4. UI and Workflow Tips for Privacy and Compliance - The section builder automatically checks attribute sensitivity and updates visual feedback in real time. - You can use aliases for returned fields and add audience/batch segments, but these must be configured as non-sensitive if you want them exposed client-side. - Payload size should stay under 10 KB (and ideally fewer than 20 attributes per section) to meet response SLAs and front-end snappiness. - Re-run the parent segment workflow after changing any batch segments, imported attributes, or sensitivity labels to guarantee users receive the latest output.

  5. Redaction Logic Enforcement - The redaction pattern is strict: if a browser sends a personalization request using a public token, any offer section referencing a sensitive attribute is always redacted—even if the rest of the payload is non-sensitive. - Example: If the “Recommended Coupon” section references a sensitive imported batch attribute, offers["Recommended Coupon"] will equal {} in the client response.

Consistency, Testing, and Auditability

  • Plan Personalization Logic Around Exposure: Write criteria and payloads so that offers meant to be shown publicly never reference sensitive fields.

  • Preview Mode: Use the UI’s “Preview” or “Test” function to confirm which sections/attributes will be visible to browsers.

  • Documentation and Handoffs: Annotate payload field names and use in-app descriptions or documentation to clarify which sections are client-safe for downstream engineers or product managers.

Example: Payload Redaction in Action

Suppose you configure two offer sections:

  • Welcome Banner

    • Payload: { "welcome_message": "Hello, new user!" }

    • All attributes: non-sensitive

    • Exposed to client-side API responses.

  • Loyalty Discount

    • Payload: { "discount_code": "LOYAL-15", "membership_tier": batch attribute (Sensitive) }

    • Contains at least one sensitive attribute

    • Redacted; API returns empty object for this section.

Summary Table: Personalization Section Outcomes

Section NameAttributes UsedAny Sensitive?Client API Result
Welcome Bannerwelcome_message (non-sensitive)NoReturns: { "welcome_message": ... }
Loyalty Discountdiscount_code, membership_tierYesReturns: {} (section redacted)

Best Practices

  • Audit all payload sections before go-live.

  • Update documentation so marketing/content teams know which offers can be public.

  • Avoid including unnecessary attributes in a section if there’s any chance of sensitivity confusion.

  • Use visual indicators and UI warnings—never ignore a locked/redacted status if the goal is public exposure.


Step 6: API Integration and Implementation Example (Client-side)

This section provides a practical guide for integrating client-side Real-Time Personalization 2.0 via browser JavaScript, highlighting how to safely and efficiently fetch personalization offers in real time for in-page experiences. It addresses the requirements for public tokens, CORS-enabled endpoints, request/response design patterns, and underscores the privacy and security differences from server-side implementations.

Making Personalization API Calls from the Browser

Client-side integration uses secure, CORS-enabled endpoints designed for direct calls from browser JavaScript. All requests must use a public RT Personalization token, never a private or server-side token.

Example: Browser-side Fetch Request

https://us01.p13n.in.treasuredata.com/public/<YOUR_DB_NAME>/<YOUR_TABLE_NAME>  

Notes:

  • Region-specific domains and “/public/” path must be used for client/browser calls.

  • <YOUR_DB_NAME> is your streaming event database.

  • <YOUR_TABLE_NAME> is the table with your real-time events.

API Endpoint Format

fetch('https://us01.p13n.in.treasuredata.com/public/my_shop_db/event_table', {  
  method: 'POST',  
  headers: {  
    'Content-Type': 'application/vnd.treasuredata.v1+json',  
    'WP13n-Token': '12345/3/PUBLIC_TOKEN_ABC',  
    'Authorization': 'TD1 <WRITE API KEY>'  
  },  
  body: JSON.stringify({  
    td_client_id: '1986b2a4-3957-4863-be2c-7ef36a14afee',  
    td_url: window.location.href,  
    td_path: window.location.pathname,  
    product_name: 'women’s-tank-top',  
    product_category: 'women',  
    product_list: ['women’s-running-shoes', 'kids’-hoodie', 'women’s-tank-top'],  
    category_list: ['women', 'kids']  
    // ... any other non-sensitive fields you’ve configured  
    })  
  })  
  .then(response => response.json())  
  .then(data => {  
    // Handle personalization offers here, e.g., update UI sections  
    console.log('Personalization Offers:', data.offers);  
});  

Example: Browser-side Fetch Request

fetch('https://us01.p13n.in.treasuredata.com/public/my_shop_db/event_table', {  
method: 'POST',  
headers: {  
  'Content-Type': 'application/vnd.treasuredata.v1+json',  
  'WP13n-Token': '12345/3/PUBLIC_TOKEN_ABC',  
  'Authorization': 'TD1 <WRITE API KEY>'  
  },  
body: JSON.stringify({  
  td_client_id: '1986b2a4-3957-4863-be2c-7ef36a14afee',  
  td_url: window.location.href,  
  td_path: window.location.pathname,  
  product_name: 'women’s-tank-top',  
  product_category: 'women',  
  product_list: ['women’s-running-shoes', 'kids’-hoodie', 'women’s-tank-top'],  
  category_list: ['women', 'kids']  
        // ... any other non-sensitive fields you’ve configured  
  })  
})  
.then(response => response.json())  
.then(data => {  
  // Handle personalization offers here, e.g., update UI sections  
  console.log('Personalization Offers:', data.offers);  
});  

Best Practice:

Never embed or expose private RT tokens or TD API keys in frontend/browser code. Only use tokens intended for public (publishing) use.

CORS & Security Enforcement

  • CORS headers are issued only if:

    • The request uses a valid, active public token.

    • The Origin header matches allowed browser origins (per TD configuration).

  • Attempts to use private tokens or incorrect endpoints in browser JS will return a 4xx error with no CORS headers, causing the request to fail in the browser.

  • If the request uses a valid token but the payload references any attributes marked "Sensitive", those sections will be blank (see payload examples below).

API Request and Response Examples

Example Request (JSON):

{  
  "td_client_id": "42a508e2-d9b1-4baa-9eb2-6c3fb8bd5e16",  
  "td_url": "https://treasuredemos.com/retail/shop/women",  
  "td_path": "/retail/shop/women",  
  "product_name": "women’s-tank-top",  
  "product_category": "women",  
  "product_list": [  
    "women’s-running-shoes",  
      "kids’-hoodie",  
      "women’s-tank-top"  
  ],  
  "category_list": [  
    "women",  
    "kids"  
  ]      
}  

Example Successful Response (only non-sensitive attributes)

{  
  "offers": {  
    "Welcome Banner": {  
      "attributes": {  
        "welcome_message": "Welcome to our website! Enjoy your shopping!"    
      }        
    },  
    "Silver rewards just for you!": {  
      "attributes": {  
        "first_name": "John",  
        "total_purchase": 28700,  
        "items_purchased": [],  
        "order_summary": "Here is your order summary!",  
        "thank_you_message": "Thank you for shopping with us!",  
        "promotions_message": "Enjoy your 15% discount for your next purchase!"  
      }     
    }            
  }  
}  

Example Response When Sensitive Attributes Are Present

    {  
      "offers": {  
        "Welcome Banner": {  
          "attributes": {  
            "welcome_message": "Hello, new user!"   
          }  
            
        },  
        "Loyalty Discount": {  
        } // This section references a sensitive attribute and is redacted   
      }  
        
    }  

Notes:

  • The client only receives data in sections where all attributes are non-sensitive.

  • This strict redaction ensures PII or protected data is never sent to browsers.

  • Note that if any offer section includes at least one attribute marked as Sensitive (per attribute setup in the UI), that section is redacted.

Comparing Client vs. Server Integration

AspectClient-side API CallServer-side API Call
Endpoint/public/{db}/{table}/{db}/{table} (no /public)
Token TypePublic only (publishing)Private or public (configurable)
Additional AuthAPI keys in browserAPI key in server header
CORSRequired and enforced; blocks on errorNot used/required
Sensitive AttributesRedacted; {} for affected sectionsAlways included if authorized
IP WhitelistingProhibited for public/browser tokensSupported for private/server tokens

Troubleshooting & Best Practices

  • 403/401/No CORS?

    • Double-check that you are using a valid public token for the right personalization service.

    • Make sure the Origin is allowed and the endpoint path includes /public/.

  • Empty/blank sections in response?

    • Verify attribute sensitivity in the Audience Studio UI; only non-sensitive attributes are returned for the browser.
  • Handling Future SDK Support:

Until the official TD JS SDK is updated, use the native fetch/XHR pattern described above for browser calls.