Skip to main content
A FlagConfig is the complete specification for how a flag behaves in a given environment. It is evaluated entirely client-side by the SDK — no round-trip required per evaluation.

Schema

type FlagConfig = {
  version: number;
  enabled: boolean; // Master kill switch — false short-circuits all rules
  defaultValue: FlagValue; // Returned when no rule matches
  rules: Rule[];
  variants?: Variant[]; // Named values for string/number flags
};

type FlagValue = boolean | string | number;

Rules

Rules are evaluated in order. The first matching rule wins and its value is returned.
type Rule = {
  id: string;
  name: string;
  enabled: boolean;
  conditions: Condition[];
  conditionOperator: "AND" | "OR"; // How conditions are combined
  value: FlagValue; // Value to return if the rule matches
  rolloutPercentage?: number; // 0–100. Pro/Enterprise only.
};
If rolloutPercentage is set, only the specified percentage of users who match the conditions will receive value — the rest fall through to the next rule.

Conditions

type Condition = {
  attribute: string; // Any key from the evaluation context
  operator: ConditionOperator;
  value: string | string[];
};

Operators

OperatorValue typeNotes
equalsstringExact match
not_equalsstring
containsstringSubstring match
not_containsstring
starts_withstring
ends_withstring
instring[]Attribute value is in the list
not_instring[]
is_setAttribute exists in context
is_not_setAttribute absent from context
gtstring (parsed as number)Numeric greater-than
ltstring (parsed as number)Numeric less-than
regexstringPro/Enterprise
geo_countrystring | string[]ISO 3166-1 alpha-2. Pro/Enterprise

Variants

Variants give names to the possible values a string or number flag can return. They are informational — the evaluation engine does not enforce that rule values match the variant list.
type Variant = {
  key: string; // e.g. "control", "treatment-a"
  value: FlagValue; // e.g. "blue", 0.05
};

Evaluation order

1. enabled === false  →  return defaultValue  (reason: DISABLED)
2. For each rule (in order):
   a. rule.enabled === false  →  skip
   b. Evaluate conditions with conditionOperator
   c. Conditions match?
      - If rolloutPercentage set: hash userId → bucket check
        - In bucket  →  return rule.value  (reason: ROLLOUT)
        - Not in bucket  →  skip
      - Else  →  return rule.value  (reason: RULE_MATCH)
3. No rule matched  →  return defaultValue  (reason: DEFAULT)

Example

Enable a flag for Pro users in the US, with a 50% rollout for everyone else:
{
  "version": 3,
  "enabled": true,
  "defaultValue": false,
  "rules": [
    {
      "id": "rule-pro-us",
      "name": "Pro users in US",
      "enabled": true,
      "conditionOperator": "AND",
      "conditions": [
        { "attribute": "plan", "operator": "equals", "value": "pro" },
        { "attribute": "country", "operator": "equals", "value": "US" }
      ],
      "value": true
    },
    {
      "id": "rule-50pct",
      "name": "50% rollout",
      "enabled": true,
      "conditionOperator": "AND",
      "conditions": [],
      "rolloutPercentage": 50,
      "value": true
    }
  ]
}