---
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 .