--- description: flagd flag definition --- # Flag Definitions ## Flags `flags` is a **required** property. The flags property is a top-level property that contains a collection of individual flags and their corresponding flag configurations. ```json { "$schema": "https://flagd.dev/schema/v0/flags.json", "flags": { ... } } ``` ## Flag Definition `flag key` is a **required** property. The flag key **must** uniquely identify a flag so it can be used during flag evaluation. The flag key **should** convey the intent of the flag. ```json { "$schema": "https://flagd.dev/schema/v0/flags.json", "flags": { "new-welcome-banner": { ... } } } ``` ## Flag properties A fully configured flag may look like this. ```json { "$schema": "https://flagd.dev/schema/v0/flags.json", "flags": { "new-welcome-banner": { "state": "ENABLED", "variants": { "on": true, "off": false }, "defaultVariant": "off", "targeting": { "if": [ { "ends_with": [{ "var": "email" }, "@example.com"] }, "on", "off" ] }, "metadata": { "version": "17" } } }, "metadata": { "team": "user-experience", "flagSetId": "ecommerce" } } ``` See below for a detailed description of each property. ### State `state` is a **required** property. Validate states are "ENABLED" or "DISABLED". When the state is set to "DISABLED", flagd will behave like the flag doesn't exist. Example: ```json "state": "ENABLED" ``` ### Variants `variants` is a **required** property. It is an object containing the possible variations supported by the flag. All the values of the object **must** be the same type (e.g. boolean, numbers, string, JSON). The type used as the variant value will correspond directly affects how the flag is accessed. For example, to use a flag configured with boolean values the `/flagd.evaluation.v1.Service/ResolveBoolean` path should be used. If another path, such as `/flagd.evaluation.v1.Service/ResolveString` is called, a type mismatch occurs and an error is returned. Example: ```json "variants": { "red": "c05543", "green": "2f5230", "blue": "0d507b" } ``` Example: ```json "variants": { "on": true, "off": false } ``` Example of an invalid configuration: ```json "variants": { "on": true, "off": "false" } ``` ### Default Variant `defaultVariant` is a **required** property. The value **must** match the name of one of the variants defined above. The default variant is always used unless a targeting rule explicitly overrides it. Example: ```json "variants": { "on": true, "off": false }, "defaultVariant": "off" ``` Example: ```json "variants": { "red": "c05543", "green": "2f5230", "blue": "0d507b" }, "defaultVariant": "red" ``` Example of an invalid configuration: ```json "variants": { "red": "c05543", "green": "2f5230", "blue": "0d507b" }, "defaultVariant": "purple" ``` ### Targeting Rules `targeting` is an **optional** property. A targeting rule **must** be valid JSON. Flagd uses a modified version of [JsonLogic](https://jsonlogic.com/), as well as some custom pre-processing, to evaluate these rules. If no targeting rules are defined, the response reason will always be `STATIC`, this allows for the flag values to be cached, this behavior is described [here](specifications/providers.md#flag-evaluation-caching). #### Variants Returned From Targeting Rules The output of the targeting rule **must** match the name of one of the defined variants. One exception to the above is that rules may return `true` or `false` which will map to the variant indexed by the equivalent string (`"true"`, `"false"`). If a null value is returned by the targeting rule, the `defaultVariant` is used. This can be useful for conditionally "exiting" targeting rules and falling back to the default (in this case the returned reason will be `DEFAULT`). If an invalid variant is returned (not a string, `true`, or `false`, or a string that is not in the set of variants) the evaluation is considered erroneous. See [Boolean Variant Shorthand](#boolean-variant-shorthand). #### Evaluation Context Evaluation context is included as part of the evaluation request. For example, when accessing flagd via HTTP, the POST body may look like this: ```json { "flagKey": "booleanFlagKey", "context": { "email": "noreply@example.com" } } ``` The evaluation context can be accessed in targeting rules using the `var` operation followed by the evaluation context property name. The evaluation context can be appended by arbitrary key value pairs via the `-X` command line flag. | Description | Example | | -------------------------------------------------------------- | ---------------------------------------------------- | | Retrieve property from the evaluation context | `#!json { "var": "email" }` | | Retrieve property from the evaluation context or use a default | `#!json { "var": ["email", "noreply@example.com"] }` | | Retrieve a nested property from the evaluation context | `#!json { "var": "user.email" }` | > For more information, see the `var` section in the [JsonLogic documentation](https://jsonlogic.com/operations.html#var). #### Conditions Conditions can be used to control the logical flow and grouping of targeting rules. | Conditional | Example | | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | If | Logic: `#!json {"if" : [ true, "yes", "no" ]}`
Result: `"yes"`

Logic: `#!json {"if" : [ false, "yes", "no" ]}`
Result: `"no"` | | If else | Logic: `#!json {"if" : [ false, "yes", false, "no", "maybe" ]}`
Result: `"maybe"`

Logic: `#!json {"if" : [ false, "yes", false, "no", false, "maybe", "who knows" ]}`
Result: `"who knows"` | | Or | Logic: `#!json {"or" : [ true, false ]}`
Result: `true`

Logic: `#!json {"or" : [ false, false ]}`
Result: `false` | | And | Logic: `#!json {"and" : [ true, false ]}`
Result: `false`

Logic: `#!json {"and" : [ true, true ]}`
Result: `true` | #### Operations Operations are used to take action on or compare properties retrieved from the context. These are provided out-of-the-box by JsonLogic. It's worth noting that JsonLogic operators never throw exceptions or abnormally terminate due to invalid input. As long as a JsonLogic operator is structurally valid, it will return a falsy/nullish value. | Operator | Description | Context attribute type | Example | | ---------------------- | -------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Equals | Attribute equals the specified value, with type coercion. | any | Logic: `#!json { "==" : [1, 1] }`
Result: `true`

Logic: `#!json { "==" : [1, "1"] }`
Result: `true` | | Strict equals | Attribute equals the specified value, with strict comparison. | any | Logic: `#!json { "===" : [1, 1] }`
Result: `true`

Logic: `#!json { "===" : [1, "1"] }`
Result: `false` | | Not equals | Attribute doesn't equal the specified value, with type coercion. | any | Logic: `#!json { "!=" : [1, 2] }`
Result: `true`

Logic: `#!json { "!=" : [1, "1"] }`
Result: `false` | | Strict not equal | Attribute doesn't equal the specified value, with strict comparison. | any | Logic: `#!json { "!==" : [1, 2] }`
Result: `true`

Logic: `#!json { "!==" : [1, "1"] }`
Result: `true` | | Exists | Attribute is defined | any | Logic: `#!json { "!!": [ "mike" ] }`
Result: `true`

Logic: `#!json { "!!": [ "" ] }`
Result: `false` | | Not exists | Attribute is not defined | any | Logic: `#!json {"!": [ "mike" ] }`
Result: `false`

Logic: `#!json {"!": [ "" ] }`
Result: `true` | | Greater than | Attribute is greater than the specified value | number | Logic: `#!json { ">" : [2, 1] }`
Result: `true`

Logic: `#!json { ">" : [1, 2] }`
Result: `false` | | Greater than or equals | Attribute is greater or equal to the specified value | number | Logic: `#!json { ">=" : [2, 1] }`
Result: `true`

Logic: `#!json { ">=" : [1, 1] }`
Result: `true` | | Less than | Attribute is less than the specified value | number | Logic: `#!json { "<" : [1, 2] }`
Result: `true`

Logic: `#!json { "<" : [2, 1] }`
Result: `false` | | Less than or equals | Attribute is less or equal to the specified value | number | Logic: `#!json { "<=" : [1, 1] }`
Result: `true`

Logic: `#!json { "<=" : [2, 1] }`
Result: `false` | | Between | Attribute between the specified values | number | Logic: `#!json { "<" : [1, 5, 10]}`
Result: `true`

Logic: `#!json { "<" : [1, 11, 10] }`
Result: `false` | | Between inclusive | Attribute between or equal to the specified values | number | Logic: `#!json {"<=" : [1, 1, 10] }`
Result: `true`

Logic: `#!json {"<=" : [1, 11, 10] }`
Result: `false` | | Contains | Contains string | string | Logic: `#!json { "in": ["Spring", "Springfield"] }`
Result: `true`

Logic: `#!json { "in":["Illinois", "Springfield"] }`
Result: `false` | | Not contains | Does not contain a string | string | Logic: `#!json { "!": { "in":["Spring", "Springfield"] } }`
Result: `false`

Logic: `#!json { "!": { "in":["Illinois", "Springfield"] } }`
Result: `true` | | In | Attribute is in an array of strings | string | Logic: `#!json { "in" : [ "Mike", ["Bob", "Mike"]] }`
Result: `true`

Logic: `#!json { "in":["Todd", ["Bob", "Mike"]] }`
Result: `false` | | Not in | Attribute is not in an array of strings | string | Logic: `#!json { "!": { "in" : [ "Mike", ["Bob", "Mike"]] } }`
Result: `false`

Logic: `#!json { "!": { "in":["Todd", ["Bob", "Mike"]] } }`
Result: `true` | #### Custom Operations These are custom operations specific to flagd and flagd providers. They are purpose-built extensions to JsonLogic in order to support common feature flag use cases. Consistent with built-in JsonLogic operators, flagd's custom operators return falsy/nullish values with invalid inputs. | Function | Description | Context attribute type | Example | | ---------------------------------- | --------------------------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `fractional` (_available v0.6.4+_) | Deterministic, pseudorandom fractional distribution | string (bucketing value) | Logic: `#!json { "fractional" : [ { "var": "email" }, [ "red" , 50], [ "green" , 50 ] ] }`
Result: Pseudo randomly `red` or `green` based on the evaluation context property `email`.

Additional documentation can be found [here](./custom-operations/fractional-operation.md). | | `starts_with` | Attribute starts with the specified value | string | Logic: `#!json { "starts_with" : [ "192.168.0.1", "192.168"] }`
Result: `true`

Logic: `#!json { "starts_with" : [ "10.0.0.1", "192.168"] }`
Result: `false`
Additional documentation can be found [here](./custom-operations/string-comparison-operation.md). | | `ends_with` | Attribute ends with the specified value | string | Logic: `#!json { "ends_with" : [ "noreply@example.com", "@example.com"] }`
Result: `true`

Logic: `#!json { ends_with" : [ "noreply@example.com", "@test.com"] }`
Result: `false`
Additional documentation can be found [here](./custom-operations/string-comparison-operation.md). | | `sem_ver` | Attribute matches a semantic versioning condition | string (valid [semver](https://semver.org/)) | Logic: `#!json {"sem_ver": ["1.1.2", ">=", "1.0.0"]}`
Result: `true`

Additional documentation can be found [here](./custom-operations/semver-operation.md). | #### Targeting key flagd and flagd providers map the [targeting key](https://openfeature.dev/specification/glossary#targeting-key) into the `"targetingKey"` property of the context used in rules. For example, if the targeting key for a particular evaluation was set to `"5c3d8535-f81a-4478-a6d3-afaa4d51199e"`, the following expression would evaluate to `true`: ```json "==": [ { "var": "targetingKey" }, "5c3d8535-f81a-4478-a6d3-afaa4d51199e" ] ``` #### $flagd properties in the evaluation context Flagd adds the following properties to the evaluation context that can be used in the targeting rules. | Property | Description | From version | | ------------------ | ------------------------------------------------------- | ------------ | | `$flagd.flagKey` | the identifier for the flag being evaluated | v0.6.4 | | `$flagd.timestamp` | a Unix timestamp (in seconds) of the time of evaluation | v0.6.7 | ## Shared evaluators `$evaluators` is an **optional** property. It's a collection of shared targeting configurations used to reduce the number of duplicated targeting rules. Example: ```json { "$schema": "https://flagd.dev/schema/v0/flags.json", "flags": { "fibAlgo": { "variants": { "recursive": "recursive", "memo": "memo", "loop": "loop", "binet": "binet" }, "defaultVariant": "recursive", "state": "ENABLED", "targeting": { "if": [ { "$ref": "emailWithFaas" }, "binet", null ] } }, "headerColor": { "variants": { "red": "#FF0000", "blue": "#0000FF", "green": "#00FF00", "yellow": "#FFFF00" }, "defaultVariant": "red", "state": "ENABLED", "targeting": { "if": [ { "$ref": "emailWithFaas" }, { "fractional": [ { "var": "email" }, ["red", 25], ["blue", 25], ["green", 25], ["yellow", 25] ] }, null ] } } }, "$evaluators": { "emailWithFaas": { "in": [ "@faas.com", { "var": ["email"] } ] } } } ``` ## Metadata Metadata can be defined at both the flag set (as a sibling of [flags](#flags)) and within each flag. Flag metadata conveys arbitrary information about the flag or flag set, such as a version number, or the business unit that is responsible for the flag. When flagd resolves flags, the returned [flag metadata](https://openfeature.dev/specification/types/#flag-metadata) is a merged representation of the metadata defined in the flag set, and the metadata defined in the flag, with the metadata defined in the flag taking priority. See the [playground](/playground/?scenario-name=Flag+metadata) for an interactive example. ## Boolean Variant Shorthand Since rules that return `true` or `false` map to the variant indexed by the equivalent string (`"true"`, `"false"`), you can use shorthand for these cases. For example, this: ```json { "$schema": "https://flagd.dev/schema/v0/flags.json", "flags": { "new-welcome-banner": { "state": "ENABLED", "variants": { "true": true, "false": false }, "defaultVariant": "false", "targeting": { "if": [ { "ends_with": [{ "var": "email" }, "@example.com"] }, "true", "false" ] } } } } ``` can be shortened to this: ```json { "$schema": "https://flagd.dev/schema/v0/flags.json", "flags": { "new-welcome-banner": { "state": "ENABLED", "variants": { "true": true, "false": false }, "defaultVariant": "false", "targeting": { "ends_with": [{ "var": "email" }, "@example.com"] } } } } ``` ## Examples Sample configurations can be found at .