Data Model Reference

Entity relationships: Experiences, Variations, Features, Goals, Audiences, Locations, Segments

This document describes the core data entities in the Convert Fullstack SDK, their fields, and how they relate to each other. Understanding this model is essential for working with the SDK, building integrations, or implementing the SDK in other languages.

Scope: This SDK is designed for Fullstack projects. The data model documented here reflects that context: only a/b_fullstack and feature_rollout experience types, and only the fullStackFeature variation change type are relevant. Other experience types and change types exist in the broader Convert platform (for web-based projects) but are not processed by this SDK.

Entity Relationship Overview

erDiagram
    ConfigResponseData ||--o{ ConfigExperience : "experiences[]"
    ConfigResponseData ||--o{ ConfigFeature : "features[]"
    ConfigResponseData ||--o{ ConfigGoal : "goals[]"
    ConfigResponseData ||--o{ ConfigLocation : "locations[]"
    ConfigResponseData ||--o{ ConfigAudience : "audiences[]"
    ConfigResponseData ||--o{ ConfigSegment : "segments[]"

    ConfigExperience ||--o{ ExperienceVariation : "variations[]"
    ConfigExperience }o--o{ ConfigGoal : "goals[] (by ID)"
    ConfigExperience }o--o{ ConfigAudience : "audiences[] (by ID)"
    ConfigExperience }o--o{ ConfigLocation : "locations[] (by ID)"

    ExperienceVariation ||--o{ VariationChange : "changes[]"

    VariationChange ||--o| ConfigFeature : "feature_id"

    ConfigFeature ||--o{ FeatureVariable : "variables[]"

ConfigResponseData (Root)

The root configuration object returned by the Convert CDN or provided as static configuration. This is the complete project configuration that the SDK operates on.

FieldTypeDescription
account_idstringConvert account identifier
projectConfigProjectProject settings (id, name, global JS/CSS, environments, settings)
goalsArray<ConfigGoal>All goals defined in the project
locationsArray<ConfigLocation>All locations (site areas) defined in the project
audiencesArray<ConfigAudience>All audiences defined in the project
segmentsArray<ConfigSegment>All segments (segmentation audiences) defined in the project
experiencesArray<ConfigExperience>All experiences (A/B tests, feature rollouts)
archived_experiencesArray<string>IDs of archived experiences
featuresArray<ConfigFeature>All features (variables) defined in the project
is_debugbooleanWhether debug mode is enabled for this project

CDN Endpoint: https://cdn-4.convertexperiments.com/api/v1/config/{account_id}/{project_id}


ConfigExperience

An experience represents a single A/B test or feature rollout. It contains the targeting rules (who sees it, where it runs), the goal tracking configuration, and the variations (what the visitor sees).

FieldTypeDescription
idstringUnique identifier
namestringHuman-readable name
keystringUnique key identifier (used in SDK method calls)
statusExperienceStatuses'draft' | 'active' | 'paused' | 'completed' | 'scheduled'
typestring'a/b_fullstack' or 'feature_rollout' (see below)
variationsArray<ExperienceVariationConfig>List of variations (including original/control)
locationsArray<string> | nullList of location IDs where the experience runs (mutually exclusive with site_area)
site_areaRuleObject | nullInline rules defining where the experience runs (mutually exclusive with locations)
audiencesArray<string> | nullList of audience IDs that the visitor must match
goalsArray<string>List of goal IDs tracked by this experience
global_jsstringGlobal JavaScript executed before variation changes
global_cssstringGlobal stylesheet applied to all variations
versionnumberExperience version number
environmentstringEnvironment where this experience runs (e.g. 'staging', 'production')
integrationsArrayList of third-party integrations (e.g. GA, Heap)
settingsobjectExperience-level settings (outlier detection, placeholders, split URL settings)

Experience Types

TypeDescription
a/b_fullstackA standard A/B test with an original (control) and one or more test variations
feature_rolloutA gradual rollout with only one non-original variation (no control comparison)

Note: The serving API's generated types currently enumerate the web-only experience types (a/b, a/a, mvt, split_url, multipage, deploy) but do not include a/b_fullstack or feature_rollout. These Fullstack types are defined in the V2 API spec and are the values actually present in Fullstack project configurations served by the CDN. This is a known gap in the type generation.


ExperienceVariationConfig (Variation)

A variation represents one version of an experience. Each experience has at least two variations: the original (control) and one or more test variations. The traffic_allocation determines what percentage of eligible visitors see this variation.

FieldTypeDescription
idstringUnique identifier
namestringHuman-readable name
keystringUnique key identifier
traffic_allocationnumberTraffic percentage (0-10000, where 10000 = 100%). The total across all variations in an experience should sum to 10000.
statusVariationStatuses'stopped' | 'running'
changesArray<ExperienceChangeServing>List of changes applied when this variation is selected

BucketedVariation (Runtime Extension)

When the SDK selects a variation for a visitor, it returns a BucketedVariation object that extends the base variation with additional runtime context:

FieldTypeDescription
(all fields from ExperienceVariationConfig)
experienceIdstringID of the parent experience
experienceKeystringKey of the parent experience
experienceNamestringName of the parent experience
bucketingAllocationnumberThe computed hash value used for bucketing (0-9999)

ExperienceChangeServing (Variation Change)

A change describes a modification that a variation applies. Each variation can have one or more changes. In Fullstack projects, the only relevant change type is fullStackFeature.

FieldTypeDescription
idnumberUnique numeric identifier for this change
typestringMust be 'fullStackFeature' (constant: VariationChangeType.FULLSTACK_FEATURE)
dataobjectFeature flag data (see below)

fullStackFeature Data

Links a variation to a feature and provides the variable values for that feature within this variation.

FieldTypeDescription
feature_idnumberID of the linked ConfigFeature (foreign key to features[])
variables_dataRecord<string, unknown>Key-value map of variable values (variable key to its value for this variation)

SDK behavior: The FeatureManager.runFeatures() method explicitly checks each change's type and skips any change that is not fullStackFeature with a warning log. Other change types (defaultCode, customCode, defaultRedirect, richStructure, defaultCodeMultipage) exist in the enum and serving spec for web-based projects but are not processed by the Fullstack SDK.


ConfigFeature (Feature)

A feature represents a named flag or set of configuration variables. Features are defined at the project level and linked to experiences through fullStackFeature changes in variations.

FieldTypeDescription
idstringUnique identifier
namestringHuman-readable name
keystringUnique key identifier (used in runFeature('key') calls)
variablesArray<FeatureVariableItemData>List of typed variables defined for this feature

BucketedFeature (Runtime Result)

When the SDK evaluates a feature for a visitor, it returns a BucketedFeature object:

FieldTypeDescription
idstringFeature ID
keystringFeature key
namestringFeature name
statusFeatureStatus'enabled' or 'disabled'
variablesArray<{key, value}>Resolved variable values (only when enabled)
experienceKeystringKey of the experience that enabled this feature
experienceIdstringID of the experience that enabled this feature
experienceNamestringName of the experience

FeatureVariableItemData (Feature Variable)

A feature variable defines a single typed value within a feature. The variable's schema (key and type) is defined on the feature, while the actual value is set per-variation in the fullStackFeature change's variables_data.

FieldTypeDescription
keystringVariable name/identifier (unique within the feature)
typeVariableTypeData type of the variable

Variable Types

TypeDescription
booleanTrue/false value
integerWhole number
floatDecimal number
stringText value
jsonJSON object or array

How Features Are Resolved

Features are not evaluated in isolation. A feature is enabled when a visitor is bucketed into a variation (of any relevant experience) that contains a fullStackFeature change linking to that feature. Here is the resolution chain:

1. Visitor requests feature "dark-mode"

2. SDK finds all experiences whose variations
   contain a fullStackFeature change with
   feature_id matching "dark-mode"

3. For each such experience:
   a. Check targeting rules (audiences, locations)
   b. If rules pass → bucket visitor into a variation
   c. Inspect the bucketed variation's changes[]

4. Find the fullStackFeature change where
   feature_id matches "dark-mode"

5. Read variables_data from that change
   → these are the actual variable VALUES

6. Read the feature's variables[] definition
   → these define the variable TYPES

7. Cast each value to its declared type
   (if typeCasting is enabled)

8. Return BucketedFeature:
   {
     key: "dark-mode",
     status: "enabled",
     variables: [
       { key: "theme_color", value: "#1a1a2e" },
       { key: "font_size", value: 16 }
     ],
     experienceKey: "dark-mode-rollout"
   }
sequenceDiagram
    participant App as Your Code
    participant Ctx as Context
    participant FM as FeatureManager
    participant DM as DataManager
    participant RM as RuleManager
    participant BM as BucketingManager

    App->>Ctx: runFeature("dark-mode")
    Ctx->>FM: runFeature(visitorId, "dark-mode", ...)
    FM->>DM: getEntity("dark-mode", "features")
    DM-->>FM: ConfigFeature {id: 42, variables: [...]}
    FM->>DM: Find experiences with fullStackFeature changes for feature_id=42
    DM-->>FM: [Experience A, Experience B]
    loop Each relevant experience
        FM->>DM: getBucketing(visitorId, experience.key, ...)
        DM->>RM: Check audience/location rules
        RM-->>DM: Pass/Fail
        DM->>BM: Assign variation (if rules pass)
        BM-->>DM: Variation selected
        DM-->>FM: BucketedVariation (with changes[])
        Note over FM: Inspect changes[] for fullStackFeature where feature_id = 42, extract variables_data
    end
    FM-->>Ctx: BucketedFeature {status: "enabled", variables: [...]}
    Ctx-->>App: BucketedFeature

Supporting Entities

ConfigGoal

Goals track visitor conversions. They are linked to experiences via the experience's goals[] array.

FieldTypeDescription
idstringUnique identifier
namestringHuman-readable name
keystringUnique key (used in trackConversion('key') calls)
rulesRuleObjectConditions that must match for the goal to trigger
settingsobjectGoal-specific settings

ConfigAudience

Audiences define visitor targeting rules. In Fullstack projects, all audiences should be of type transient (conditions checked each time).

FieldTypeDescription
idstringUnique identifier
namestringHuman-readable name
keystringUnique key
rulesRuleObjectOR/AND/OR_WHEN rule structure (see Rule Evaluation)

ConfigLocation

Locations define where (which pages/routes) an experience runs.

FieldTypeDescription
idstringUnique identifier
namestringHuman-readable name
keystringUnique key
rulesRuleObjectOR/AND/OR_WHEN rule structure

ConfigSegment

Segments represent audiences of type segmentation. In Fullstack projects, segments do not persist unless you provide a DataStore.

FieldTypeDescription
idstringUnique identifier
namestringHuman-readable name
keystringUnique key (used in runCustomSegments(['key']) calls)
rulesRuleObjectOR/AND/OR_WHEN rule structure

Complete JSON Structure Example

A simplified example showing how all entities connect in a real configuration:

{
  "account_id": "100012345",
  "project": {
    "id": "200067890",
    "name": "My Fullstack Project",
    "settings": {
      "is_debug": false
    }
  },
  "features": [
    {
      "id": "42",
      "name": "Dark Mode",
      "key": "dark-mode",
      "variables": [
        { "key": "theme_color", "type": "string" },
        { "key": "font_size", "type": "integer" },
        { "key": "enabled", "type": "boolean" }
      ]
    }
  ],
  "experiences": [
    {
      "id": "300011111",
      "name": "Dark Mode Rollout",
      "key": "dark-mode-rollout",
      "type": "a/b_fullstack",
      "status": "active",
      "environment": "production",
      "audiences": ["400022222"],
      "locations": ["500033333"],
      "goals": ["600044444"],
      "variations": [
        {
          "id": "700055555",
          "name": "Original",
          "key": "original",
          "traffic_allocation": 5000,
          "status": "running",
          "changes": []
        },
        {
          "id": "700066666",
          "name": "Dark Theme",
          "key": "dark-theme",
          "traffic_allocation": 5000,
          "status": "running",
          "changes": [
            {
              "id": 1,
              "type": "fullStackFeature",
              "data": {
                "feature_id": 42,
                "variables_data": {
                  "theme_color": "#1a1a2e",
                  "font_size": 16,
                  "enabled": true
                }
              }
            }
          ]
        }
      ]
    }
  ],
  "goals": [
    {
      "id": "600044444",
      "name": "Sign Up",
      "key": "sign-up",
      "rules": {}
    }
  ],
  "audiences": [
    {
      "id": "400022222",
      "name": "US Desktop Users",
      "key": "us-desktop",
      "rules": {
        "OR": [
          {
            "AND": [
              {
                "OR_WHEN": [
                  {
                    "rule_type": "generic_text_key_value",
                    "key": "country",
                    "matching": { "match_type": "equals", "negated": false },
                    "value": "US"
                  }
                ]
              },
              {
                "OR_WHEN": [
                  {
                    "rule_type": "generic_text_key_value",
                    "key": "device",
                    "matching": { "match_type": "equals", "negated": false },
                    "value": "desktop"
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  ],
  "locations": [
    {
      "id": "500033333",
      "name": "Homepage",
      "key": "homepage",
      "rules": {
        "OR": [
          {
            "AND": [
              {
                "OR_WHEN": [
                  {
                    "rule_type": "generic_text_key_value",
                    "key": "url",
                    "matching": { "match_type": "equals", "negated": false },
                    "value": "/"
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  ],
  "segments": []
}

In this example:

  1. The experience "Dark Mode Rollout" has two variations (50/50 traffic split)
  2. The "Dark Theme" variation has one change of type fullStackFeature
  3. That change links to feature "Dark Mode" (id: 42) and provides variable values
  4. The feature defines three variables with their types (string, integer, boolean)
  5. The experience targets the audience "US Desktop Users" and runs on the location "Homepage"
  6. The goal "Sign Up" is tracked for this experience