---
title: "Targeting"
description: "How a flag decides what to serve in an environment, rule operators, and contexts without an attribute."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ezghcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Targeting

A flag's targeting in an environment decides which variation each **evaluation context** gets.
The context is what your code passes: a `targetingKey` (usually a user ID) and any attributes
(`plan`, `country`, `company.id`).

## The order

1. **Off:** everyone gets the **off variation**.
2. **Individual targets:** a context whose `targetingKey` is listed under a variation gets it.
3. **Rules,** top to bottom: the first rule that matches serves its variation or rollout.
4. **The default rule:** a variation or a [percentage rollout](/flags/rollouts).

The reason providers report is `DISABLED` when the flag is off, `TARGETING_MATCH` when a target, a
rule or a rollout chose the variation, `DEFAULT` when targeting has rules and none matched, and
`STATIC` when it's on with no targets or rules and its default rule serves one variation.

## Rules

A rule has up to 10 **clauses**, all of which must match (AND), and serves a variation or a
rollout. A config has up to 100 rules. A clause names a context **attribute**, an **operator** and
up to 1,000 **values**; it matches when the attribute matches any of the values.

| Operator | Matches when the attribute |
| --- | --- |
| `in` | Equals one of the values |
| `notIn` | Equals none of the values |
| `contains` | Is a string containing one of the values |
| `startsWith` | Is a string starting with one of the values |
| `endsWith` | Is a string ending with one of the values |
| `lt`, `lte`, `gt`, `gte` | Is a number less than, at most, greater than, or at least the value |
| `semverEq`, `semverLt`, `semverGt` | Is a semantic version equal to, before or after the value |
| `segmentMatch` | (no attribute) The context is in one of the [segments](/flags/segments) |
| `notSegmentMatch` | (no attribute) The context is in none of the segments |

**Values are typed, and compared strictly:** the string `"1"` doesn't match the number `1`, and
`"true"` doesn't match `true`. Pass attributes with the type your rules use. `is one of` (`in`)
and `is not one of` (`notIn`) take strings, numbers and booleans; the number operators take
numbers; `contains`, `startsWith`, `endsWith` and the segment operators take strings; the version
operators take full versions, `1.4.0` (an optional pre-release or build after it, no `v`). In the
console's editor, a number or `true`/`false` in an "is one of" list is typed as such, and quotes
make it a string (`"1"`).

**Dot paths** reach nested attributes: `company.plan` is the `plan` attribute of the `company`
object.

## Contexts without an attribute

**A clause on an attribute the context doesn't have never matches,** whatever its operator:
`notIn` and `notSegmentMatch` don't match either. `company.plan` doesn't match when `company` is
missing or isn't an object. So `country notIn US` matches contexts with another country, not
contexts without one.

## Changing targeting

In the console, open a flag's **Targeting** tab and pick the environment. Your changes are a draft
until you review the differences and save them, with a comment. **Copy from environment** loads
another environment's targeting into the editor to review and save. With the CLI:

```sh
ezgh flags toggle new-checkout --env production --on --comment "Launch"
ezgh flags config get new-checkout --env staging > checkout.json
ezgh flags config set new-checkout --env staging --file checkout.json --comment "Add a rule"
```

`config set` writes only if the config is still at the version in the file. Through the API, a
config is written whole with [UpdateFlagConfig](/flags-api/UpdateFlagConfig/), with its
version as `If-Match` (`"12"`). Changes reach connected server providers and streams within
seconds.

## Limits

| Limit | Value |
| --- | --- |
| Rules per config | 100 |
| A rule's description | 200 characters |
| Clauses per rule | 10 |
| Values per clause | 1,000 |
| Individual target values per config | 10,000 |

Source: https://docs.ezghcloud.com/flags/targeting/index.mdx
