Rules
Rules determine what value a flag returns for a specific user. They are evaluated in priority order — the first matching rule wins. If no rule matches, the flag returns false.
You can add a single rule or multiple rules — both are valid. A flag with one PERCENTAGE rule and nothing else works perfectly fine. Rules are entirely optional; a flag with no rules returns false for all users when disabled, or true for all users when enabled.
Rule evaluation order
Rules are sorted by the priority field in ascending order. Priority 0 is evaluated first. The first rule whose conditions are satisfied determines the returned value — subsequent rules are not checked.
If no rule matches and the flag is enabled, the flag returns false with matchedRuleType: null. A STATIC fallback rule makes this explicit — but it is optional. You do not need a STATIC rule unless you want the fallback behaviour to be self-documenting in your rule list.
Rule types
STATIC
A STATIC rule always matches. It has no conditions — every user satisfies it.
Fields:
| Field | Type | Description |
|---|---|---|
priority | integer | Evaluation order. Lower number = evaluated first. |
serveValue | boolean | The value returned when this rule matches. |
Example:
{
"type": "STATIC",
"priority": 1,
"serveValue": false
}Use for: Default on/off state, explicit catch-all fallback.
Because a STATIC rule always matches, place it at the highest priority number (last in the list) so other rules can match first.
A STATIC rule is optional. If no rule matches, the flag already returns false by default. Add a STATIC rule only when you want the fallback to be explicit and visible in your rule list.
SEGMENT
A SEGMENT rule matches based on whether the user's userIdentifier is a member of a specified segment. Membership is an exact string match.
Fields:
| Field | Type | Description |
|---|---|---|
priority | integer | Evaluation order. |
segmentId | string (UUID) | The segment to check membership against. |
operator | IS_IN or IS_NOT_IN | IS_IN matches users in the segment. IS_NOT_IN matches users not in the segment. |
serveValue | boolean | The value returned when this rule matches. |
Example:
{
"type": "SEGMENT",
"priority": 0,
"segmentId": "a1b2c3d4-...",
"operator": "IS_IN",
"serveValue": true
}Use for: Beta users, internal team access, allowlists, denylists, enterprise-specific features.
PERCENTAGE
A PERCENTAGE rule uses a deterministic hash of the user's identifier to assign them a stable bucket from 0 to 99999. If their bucket falls below the rolloutThreshold, the rule matches.
The hash is computed from environmentId + flagKey + userIdentifier. This means:
- The same user always gets the same result for the same flag in the same environment.
- Expanding from 10% to 50% keeps the original 10% cohort in the
truebucket — they do not flip. - Distribution is uniform across your user base.
Fields:
| Field | Type | Description |
|---|---|---|
priority | integer | Evaluation order. |
rolloutThreshold | integer (0–100) | Percentage of users who match this rule. 10 = 10% of users. |
serveValue | boolean | The value returned when this rule matches. |
Example:
{
"type": "PERCENTAGE",
"priority": 1,
"rolloutThreshold": 20,
"serveValue": true
}Use for: Gradual rollouts, canary deployments, A/B testing.
Single rule vs. multiple rules
Both are valid. Choose based on your use case:
Single rule — simplest setup, no STATIC needed:
Priority 0: PERCENTAGE 20% → trueEveryone not in the 20% bucket gets false automatically — no extra rule required.
Multiple rules — layered targeting:
Priority 0: SEGMENT IS_IN beta-users → true
Priority 1: PERCENTAGE 20% → true
Priority 2: STATIC always → false ← optional, makes fallback explicitA beta user matches priority 0 and gets true. A non-beta user in the 20% bucket matches priority 1. Everyone else reaches the STATIC rule (or falls through to the implicit false if no STATIC rule is present).
No match
If a flag is enabled but no rule matches, the response is:
{
"value": false,
"matchedRuleType": null,
"error": null
}This is the same result whether or not you have a STATIC fallback rule. The STATIC rule is purely for explicitness — it is not required.