Feature Flags
Feature flags let you control feature availability at runtime without deploying code. EdgeFlags supports boolean, string, number, and JSON flag values with targeting rules, percentage rollouts, and environment overrides.
Creating a flag
curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "key": "new_checkout", "enabled": true, "value": false }' \ "https://edgeflags.net/api/v1/flags"Flag keys must match the pattern [a-z0-9][a-z0-9._-]{0,127}.
Required fields
| Field | Type | Description |
|---|---|---|
key | string | Unique identifier for the flag |
enabled | boolean | Master kill switch |
Optional fields
| Field | Type | Description |
|---|---|---|
value | any | Override value (boolean, string, number, or JSON) |
targeting | object | Targeting rules and rollout configuration |
environments | object | Per-environment overrides |
active_from | string | ISO 8601 timestamp — flag inactive before this time |
active_until | string | ISO 8601 timestamp — flag inactive after this time |
Evaluating a flag
curl -H "Authorization: Bearer $TOKEN" \ "https://edgeflags.net/api/v1/flags/new_checkout"Response:
{ "value": false, "type": "boolean", "reason": "override"}With user context
Pass a JSON-encoded context as a query parameter to evaluate targeting rules:
curl -H "Authorization: Bearer $TOKEN" \ "https://edgeflags.net/api/v1/flags/new_checkout?context=%7B%22user_id%22%3A%22u_123%22%2C%22plan%22%3A%22premium%22%7D"The context object supports these properties:
| Property | Type | Description |
|---|---|---|
user_id | string | Unique user identifier |
email | string | User email address |
phone | string | User phone number |
plan | string | Subscription plan |
segments | string[] | Explicit segment membership |
environment | string | Environment name (for environment overrides) |
custom | object | Any custom attributes |
Evaluation priority
Flags are evaluated in this order:
- Disabled check — if
enabledisfalse, returnsfalsewith reasondisabled - Time-based activation — if outside
active_from/active_untilwindow, returnsfalsewith reasondisabled - Environment override — if
context.environmentmatches an override, uses that override’s settings - Explicit value — if
valueis set, returns it with reasonoverride - Targeting rules — evaluates rules in order; first matching rule wins (reason
targeting) - Rollout percentage — if no rule matched but a rollout is configured, uses percentage-based inclusion (reason
rollout) - Feature default — falls back to the feature’s
default_value(reasondefault)
Targeting rules
Targeting lets you return different values based on user context. Rules are evaluated in order — the first matching rule wins.
Each rule has:
- conditions — an array of conditions that must ALL match (AND logic)
- value — the value to return when all conditions match
Between rules, OR logic applies: if rule 1 doesn’t match, rule 2 is tried, and so on.
curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "key": "premium_feature", "enabled": true, "targeting": { "rules": [ { "conditions": [ { "property": "plan", "operator": "in", "value": ["premium", "enterprise"] } ], "value": true }, { "conditions": [ { "property": "email", "operator": "ends_with", "value": "@acme.com" } ], "value": true } ] } }' \ "https://edgeflags.net/api/v1/flags"This flag returns true for premium/enterprise users OR anyone with an @acme.com email.
See Targeting Operators for all available operators.
Rollout percentages
Gradually roll out a feature to a percentage of users using consistent hashing (MurmurHash3). The same user always gets the same result for a given flag.
{ "key": "new_ui", "enabled": true, "targeting": { "rules": [], "rollout": { "percentage": 25, "attribute": "user_id" } }}The attribute field determines which context property to hash (defaults to user_id). The hash is computed as murmurhash3("{flag_key}:{attribute_value}") % 100. Users whose hash falls below the percentage value are included.
Time-based activation
Schedule flags to activate and deactivate at specific times:
{ "key": "holiday_sale", "enabled": true, "value": true, "active_from": "2026-12-20T00:00:00Z", "active_until": "2026-12-31T23:59:59Z"}Outside the activation window, the flag evaluates as false with reason disabled.
Environment overrides
Override flag behavior per environment. When the evaluation context includes an environment field matching an override key, that override takes priority.
{ "key": "new_checkout", "enabled": true, "value": false, "environments": { "production": { "enabled": false }, "staging": { "enabled": true, "value": true } }}Setting an environment override via API
curl -X PUT \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "enabled": true, "value": true }' \ "https://edgeflags.net/api/v1/flags/new_checkout/environments/staging"Removing an environment override
curl -X DELETE \ -H "Authorization: Bearer $TOKEN" \ "https://edgeflags.net/api/v1/flags/new_checkout/environments/staging"Updating a flag
curl -X PUT \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "enabled": false }' \ "https://edgeflags.net/api/v1/flags/new_checkout"Use the If-Match header for optimistic concurrency control:
curl -X PUT \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -H "If-Match: \"1\"" \ -d '{ "enabled": false }' \ "https://edgeflags.net/api/v1/flags/new_checkout"If the flag’s version doesn’t match, a 409 Conflict is returned.
Deleting a flag
curl -X DELETE \ -H "Authorization: Bearer $TOKEN" \ "https://edgeflags.net/api/v1/flags/new_checkout"Listing flags
curl -H "Authorization: Bearer $TOKEN" \ "https://edgeflags.net/api/v1/flags?limit=20&offset=0"Response includes pagination:
{ "flags": [ { "key": "dark_mode", "flag": { "enabled": true, "value": true, "version": 1 } } ], "total": 1, "has_more": false}