-
Notifications
You must be signed in to change notification settings - Fork 3
DataModel
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_fullstackandfeature_rolloutexperience types, and only thefullStackFeaturevariation 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.
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[]"
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.
Source: packages/types/src/config/types.gen.ts
| Field | Type | Description |
|---|---|---|
account_id |
string | Convert account identifier |
project |
ConfigProject | Project settings (id, name, global JS/CSS, environments, settings) |
goals |
Array<ConfigGoal> | All goals defined in the project |
locations |
Array<ConfigLocation> | All locations (site areas) defined in the project |
audiences |
Array<ConfigAudience> | All audiences defined in the project |
segments |
Array<ConfigSegment> | All segments (segmentation audiences) defined in the project |
experiences |
Array<ConfigExperience> | All experiences (A/B tests, feature rollouts) |
archived_experiences |
Array<string> | IDs of archived experiences |
features |
Array<ConfigFeature> | All features (variables) defined in the project |
is_debug |
boolean | Whether debug mode is enabled for this project |
CDN Endpoint: https://cdn-4.convertexperiments.com/api/v1/config/{account_id}/{project_id}
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).
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
key |
string | Unique key identifier (used in SDK method calls) |
status |
ExperienceStatuses |
'draft' | 'active' | 'paused' | 'completed' | 'scheduled'
|
type |
string |
'a/b_fullstack' or 'feature_rollout' (see below) |
variations |
Array<ExperienceVariationConfig> | List of variations (including original/control) |
locations |
Array<string> | null | List of location IDs where the experience runs (mutually exclusive with site_area) |
site_area |
RuleObject | null | Inline rules defining where the experience runs (mutually exclusive with locations) |
audiences |
Array<string> | null | List of audience IDs that the visitor must match |
goals |
Array<string> | List of goal IDs tracked by this experience |
global_js |
string | Global JavaScript executed before variation changes |
global_css |
string | Global stylesheet applied to all variations |
version |
number | Experience version number |
environment |
string | Environment where this experience runs (e.g. 'staging', 'production') |
integrations |
Array | List of third-party integrations (e.g. GA, Heap) |
settings |
object | Experience-level settings (outlier detection, placeholders, split URL settings) |
| Type | Description |
|---|---|
a/b_fullstack |
A standard A/B test with an original (control) and one or more test variations |
feature_rollout |
A gradual rollout with only one non-original variation (no control comparison) |
Note: The serving API's generated TypeScript types (
types.gen.ts) currently enumerate the web-only experience types (a/b,a/a,mvt,split_url,multipage,deploy) but do not includea/b_fullstackorfeature_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.
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.
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
key |
string | Unique key identifier |
traffic_allocation |
number | Traffic percentage (0-10000, where 10000 = 100%). The total across all variations in an experience should sum to 10000. |
status |
VariationStatuses |
'stopped' | 'running'
|
changes |
Array<ExperienceChangeServing> | List of changes applied when this variation is selected |
When the SDK selects a variation for a visitor, it returns a BucketedVariation object that extends the base variation with additional runtime context:
Source: packages/types/src/BucketedVariation.ts
| Field | Type | Description |
|---|---|---|
| (all fields from ExperienceVariationConfig) | ||
experienceId |
string | ID of the parent experience |
experienceKey |
string | Key of the parent experience |
experienceName |
string | Name of the parent experience |
bucketingAllocation |
number | The computed hash value used for bucketing (0-9999) |
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.
Source: packages/types/src/config/types.gen.ts, packages/enums/src/variation-change-type.ts
| Field | Type | Description |
|---|---|---|
id |
number | Unique numeric identifier for this change |
type |
string | Must be 'fullStackFeature' (constant: VariationChangeType.FULLSTACK_FEATURE) |
data |
object | Feature flag data (see below) |
Links a variation to a feature and provides the variable values for that feature within this variation.
| Field | Type | Description |
|---|---|---|
feature_id |
number | ID of the linked ConfigFeature (foreign key to features[]) |
variables_data |
Record<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'stypeand skips any change that is notfullStackFeaturewith 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.
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.
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
key |
string | Unique key identifier (used in runFeature('key') calls) |
variables |
Array<FeatureVariableItemData> | List of typed variables defined for this feature |
When the SDK evaluates a feature for a visitor, it returns a BucketedFeature object:
Source: packages/types/src/BucketedFeature.ts
| Field | Type | Description |
|---|---|---|
id |
string | Feature ID |
key |
string | Feature key |
name |
string | Feature name |
status |
FeatureStatus |
'enabled' or 'disabled'
|
variables |
Array<{key, value}> | Resolved variable values (only when enabled) |
experienceKey |
string | Key of the experience that enabled this feature |
experienceId |
string | ID of the experience that enabled this feature |
experienceName |
string | Name of the experience |
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.
| Field | Type | Description |
|---|---|---|
key |
string | Variable name/identifier (unique within the feature) |
type |
VariableType | Data type of the variable |
Source (enum): packages/enums/src/variable-types.ts
| Type | Description |
|---|---|
boolean |
True/false value |
integer |
Whole number |
float |
Decimal number |
string |
Text value |
json |
JSON object or array |
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<br/>where feature_id = 42<br/>Extract variables_data
end
FM-->>Ctx: BucketedFeature {status: "enabled", variables: [...]}
Ctx-->>App: BucketedFeature
Goals track visitor conversions. They are linked to experiences via the experience's goals[] array.
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
key |
string | Unique key (used in trackConversion('key') calls) |
rules |
RuleObject | Conditions that must match for the goal to trigger |
settings |
object | Goal-specific settings |
Audiences define visitor targeting rules. In Fullstack projects, all audiences should be of type transient (conditions checked each time).
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
key |
string | Unique key |
rules |
RuleObject | OR/AND/OR_WHEN rule structure (see RuleManager) |
Locations define where (which pages/routes) an experience runs.
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
key |
string | Unique key |
rules |
RuleObject | OR/AND/OR_WHEN rule structure |
Segments represent audiences of type segmentation. In Fullstack projects, segments do not persist unless you provide a DataStore.
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
key |
string | Unique key (used in runCustomSegments(['key']) calls) |
rules |
RuleObject | OR/AND/OR_WHEN rule structure |
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:
- The experience "Dark Mode Rollout" has two variations (50/50 traffic split)
- The "Dark Theme" variation has one change of type
fullStackFeature - That change links to feature "Dark Mode" (id: 42) and provides variable values
- The feature defines three variables with their types (string, integer, boolean)
- The experience targets the audience "US Desktop Users" and runs on the location "Homepage"
- The goal "Sign Up" is tracked for this experience
Copyrights © 2025 All Rights Reserved by Convert Insights, Inc.
User Guide
Core Modules
- ConvertSDK / Core
- Context
- ExperienceManager
- FeatureManager
- DataManager
- BucketingManager
- RuleManager
- ApiManager
- EventManager
- Config / Types
Integration Guides