Intempt Docs
GuidesGetting Started

Server-Side Experiments Implementation Guide

Call the Choose API to identify a user, resolve a server-side experiment or personalization, and apply the result in your backend.

Overview

Server-side experiments let you deliver personalized experiences and A/B test variations directly from your backend, instead of applying variations in the browser. Your backend calls the Choose API before rendering, and Intempt returns the variation or personalization to apply. This guide walks through identifying a user, calling the endpoint, and handling the result. For the concepts behind server-side delivery, see Server-Side Experiments Overview.

How it works

  1. Your backend identifies the current user.
  2. Your backend calls the Choose API before rendering.
  3. Intempt returns the matching Experience variation(s) as a choices array.
  4. Your backend applies the result before responding to the client: swap copy, set a feature flag, or insert structured data.

Getting started

  1. Identify the user. Every request needs an identification object, built one of two ways:

    sourceId and profileId:

    {
      "identification": {
        "sourceId": 1575686747310551239,
        "profileId": "profile_c2daf740e3e9f7aa48c6f6563f192b81"
      }
    }

    Or a single userId, if the user already has this identifier in Intempt:

    {
      "identification": {
        "userId": "user_123456"
      }
    }
  2. Call the Choose API.

    POST https://api.intempt.com/v1/{orgName}/projects/{projectName}/optimization/choose-api?apiKey=YOUR_API_KEY
    ParameterDescription
    orgNameYour Intempt organization name
    projectNameThe project where the Experience is configured
    apiKeyYour project API key, passed as a query parameter

    Resolve specific Experiences by name:

    curl -X POST "https://api.intempt.com/v1/{orgName}/projects/{projectName}/optimization/choose-api?apiKey=YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "identification": {
          "sourceId": 1575686747310551239,
          "profileId": "profile_c2daf740e3e9f7aa48c6f6563f192b81"
        },
        "names": ["demo-server-side-experiment", "demo-server-side-personalization-most-popular"],
        "device": "mobile",
        "sessionId": "sess_8f2a1c9d3e7b"
      }'

    Or resolve every Experience in a group:

    curl -X POST "https://api.intempt.com/v1/{orgName}/projects/{projectName}/optimization/choose-api?apiKey=YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "identification": {
          "sourceId": 1575686747310551239,
          "profileId": "profile_c2daf740e3e9f7aa48c6f6563f192b81"
        },
        "groups": ["my-group"]
      }'

    names and groups are both optional and independent: pass names to resolve specific Experiences, groups to resolve everything in a group, or both in the same request. device accepts all, desktop, or mobile. names and groups entries can only contain letters, numbers, underscores, and hyphens. See Choose API reference for the complete field list, including the optional productId and timestamp fields.

  3. Read the response. A successful call returns a choices array, one entry per matched Experience:

    {
      "choices": [
        {
          "name": "demo-server-side-personalization-most-popular",
          "group": "my-group",
          "body": {
            "label": "My most popular products",
            "products": [
              {
                "price": "250.0",
                "title": "PMC Bronze 9mm (FMJ) 124 GR. 1000 Rds.",
                "category": "Ammunition"
              }
            ]
          }
        }
      ]
    }

    choices[].body is the variation's configured payload; its shape depends on how the Experience was set up. choices is an empty array if nothing matches.

  4. Apply the result in your backend. Intempt only returns the decision. It never modifies your UI automatically. Depending on how the Experience is configured, that means:

    • Text or content replacement. Swap server-rendered copy before sending the response.
    • Feature flags. Read a flag-shaped field from body and branch your logic before rendering.
    • Structured personalization. Insert product lists or other structured data into HTML, an API response, or a mobile payload.

    Match choices entries by name, never by array index, since a request can return more than one choice.

  5. Handle errors and fallbacks.

    StatusMeaning
    400Invalid request. The response body includes an errors array with a message per issue.
    404Not found.

    If the call fails or returns no choices, render your default experience. Define a fallback for every Experience before you rely on it in production.

Where to go next

On this page