Intempt
  1. Server Side Experiments
Intempt
  • Installation
    • Basic Intempt Installation
    • Create source
    • Google Tag Manager
    • Environment Setup
    • Validating Installation
  • SDK
    • JS SDK
    • Android SDK
    • iOS SDK
    • Node.js SDK
  • API Reference
    • Track data
      POST
    • Consent
      POST
    • Choose API
      POST
    • Recommendations Feed API
      POST
  • Data Ingestion & Tracking
    • intempt:html / intempt:page / intempt:session
    • Product Catalog Ingestion via API
    • How Intempt Works — A One-Page Mental Model
    • Revenue & Refund Tracking
    • Recommendation events mapping
    • Track Events API (Recommendations)
  • Data Models & Event Schema
    • Event Schema Overview
  • Webhooks
    • All about Webhooks
  • Server Side Experiments
    • Overview
  1. Server Side Experiments

Overview

Server-Side Experiences in Intempt#

Overview, API Usage, Application, End-to-End Flow & Use Cases#


1. Server-Side Experiences — Overview & Mental Model#

Server-side Experiences allow you to deliver personalized Experiences and run A/B tests directly from your backend, instead of applying variations in the browser.
Unlike client-side Experiences—where variations are applied after the page loads—server-side Experiences are resolved before the response is sent to the client.
This means Intempt decides what a user should see, and your backend decides how to render it.

Why Server-Side Experiences Exist#

Server-side Experiences are designed for cases where:
UI must be rendered before the page loads
Flicker or layout shifts are unacceptable
SEO and crawler consistency are important
You want full control over rendering logic
Personalization needs to work across web, mobile, and APIs
Because the decision happens on the server, the user always receives the correct version on first paint.

Client-Side vs Server-Side (Conceptual Difference)#

Client-Side Experiences#

Variation is chosen in the browser
UI updates after JavaScript executes
Can cause flicker
Limited control over SEO and crawlers

Server-Side Experiences#

Variation is chosen before rendering
Backend applies the decision
No flicker
Fully SEO-safe
Works with SSR, APIs, and mobile backends
Intempt supports both models — this document focuses only on server-side resolution.

How Server-Side Experiences Work in Intempt#

At a high level:
1.
You configure Experiences or personalizations in Intempt
2.
Your backend calls the Choose API
3.
Intempt returns the decision
4.
Your backend applies the result before responding
⚠️ Important
Intempt does not modify your UI automatically.
It only returns a decision. Rendering is always your responsibility.

What Intempt Decides vs What You Control#

Intempt handles:
User eligibility
Experience assignment
Variation consistency
Segmentation logic
Targeting rules
Personalization logic
Your backend controls:
HTML rendering
API response structure
Feature flags
Layout selection
UI composition
This separation keeps Intempt framework-agnostic.

Identity & Context in Server-Side Experiences#

Server-side Experience decisions depend on:
userId or sourceId + profileId
sessionId
device (mobile / desktop)
Attributes & segmentation rules
Accurate identity → consistent Experience results.

When to Use Server-Side Experiences#

Ideal for:
Server-rendered pages (SSR)
Feature flags controlled from backend
Personalized API responses
SEO-sensitive landing pages
Mobile app backends
High-performance personalization

Summary#

Intempt decides what should happen.
Your backend decides how it happens.
Benefits:
Faster delivery
No flicker
SEO-safe
Predictable behavior
Full backend control

2. Choose API — Resolving Server-Side Experiences & Personalization#

The Choose API resolves server-side Experiences and personalizations before rendering.
Your backend sends identity + context → Intempt returns the decision → you apply it.

Endpoint#


Path Parameters#

ParameterDescription
orgNameIntempt organization name
projectNameProject containing the Experience
apiKeyAPI key (query parameter)

Request Body Structure#

Includes:
identification
names or groups
optional sessionId, device

Identification Methods#

Method 1: sourceId + profileId (Recommended)#

{
  "identification": {
    "sourceId": "1575686747310551XXX",
    "profileId": "profile_c2daf740e3e9f7aa48c6f6563f192XXX"
  }
}
Use when profile is known and persisted.

Method 2: userId#

{
  "identification": {
    "userId": "user_123456"
  }
}
Works only if the user already exists.

Optional Context#

sessionId
"sessionId": "my_session_1"
device
"device": "mobile"

Resolve by Experience Names#

{
  "identification": {
    "sourceId": "1575686747310551XXX",
    "profileId": "profile_c2daf740e3e9f7aa48c6f6563f192XXX"
  },
  "names": ["demo-server-side-experience"],
  "device": "mobile",
  "sessionId": "my_session_XXX"
}

Resolve by Groups#

{
  "identification": {
    "sourceId": "1575686747310551XXX",
    "profileId": "profile_c2daf740e3e9f7aa48c6f6563f192XXX"
  },
  "groups": ["my-group"]
}

Example Response#

{
  "choices": [
    {
      "name": "demo-server-side-personalization-most-popular",
      "group": "my-group",
      "body": {
        "label": "My most popular products PERSONALIZATION",
        "products": [
          {
            "price": "250.0",
            "title": "PMC Bronze 9mm",
            "category": "Ammunition"
          }
        ]
      }
    }
  ]
}

Key Rule#

⚠️ Choose API returns decisions only.
It does not modify UI or behavior.

3. Applying Server-Side Experience Results#

Intempt decides.
Your backend applies.

Response Structure#

{
  "choices": [
    {
      "name": "experience-name",
      "group": "group-name",
      "body": {}
    }
  ]
}

Application Patterns#

1. Text / Content#

{ "headline": "Try our new premium plan" }
→ Replace server-rendered copy.

2. Feature Flags#

{
  "enableNewCheckout": true,
  "layout": "v2"
}
→ Apply logic before rendering.

3. Structured Personalization#

{
  "products": [{ "title": "Product A", "price": "250.0" }]
}
→ Insert into HTML / API response / mobile payload.

Handling Multiple Choices#

Iterate over choices
Match by name
Never rely on order

Fallback Handling#

If:
API fails
No choices returned
→ Render default Experience.

4. End-to-End Server-Side Experience Flow#

1.
User Request — SSR / API / Mobile backend
2.
Identify User — userId or sourceId + profileId
3.
Call Choose API — before rendering
4.
Intempt Resolves — eligibility, targeting, allocation
5.
Backend Applies Result — layout, data, flags
6.
Respond to Client — HTML / JSON / mobile payload
7.
Consistency — same identity → same Experience
8.
Measure & Iterate — events tracked normally

Core Rule#

Experiences decide data.
Your backend decides behavior.

5. Server-Side Experience Use Cases#

Best Practices & Limitations#


1. SEO-Sensitive Pages#

Use for: landing, pricing, content pages
Why: no flicker, crawler-safe
Best Practices
Resolve before rendering
Deterministic HTML
Limitations
Avoid DOM-only mutations

2. Feature Flags#

{ "enableNewCheckout": true }
Best Practices
Treat as config
Always define defaults
Limitations
Do not encode business logic

3. Personalized Content#

{ "products": [] }
Best Practices
Structured payloads
Predictable schema
Limitations
Avoid large payloads

4. Multi-Tenant / B2B#

Best Practices
Use accountId
Separate account vs user logic
Limitations
Resolve account before Choose API

5. Mobile & API Experiences#

Best Practices
Platform-agnostic payloads
Backend-controlled rollouts
Limitations
Backend must handle fallback

Global Best Practices#

✔ Defaults always
✔ Match by name
✔ Data-only payloads
✔ Resolve before rendering

Common Mistakes#

❌ Calling Choose API after render
❌ Expecting UI injection
❌ Encoding logic in Experiences

When NOT to Use Server-Side Experiences#

Micro-interactions
DOM-only changes
Ultra-high-frequency UI events

Final Takeaway#

Server-side Experiences are best when:
Decisions must be deterministic
Performance matters
SEO must be preserved
Backend controls rendering
Decide with Intempt.
Render with confidence.
Modified at 2026-01-29 15:30:49
Previous
All about Webhooks
Built with