Skip to content

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

Terminal window
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

FieldTypeDescription
keystringUnique identifier for the flag
enabledbooleanMaster kill switch

Optional fields

FieldTypeDescription
valueanyOverride value (boolean, string, number, or JSON)
targetingobjectTargeting rules and rollout configuration
environmentsobjectPer-environment overrides
active_fromstringISO 8601 timestamp — flag inactive before this time
active_untilstringISO 8601 timestamp — flag inactive after this time

Evaluating a flag

Terminal window
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:

Terminal window
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:

PropertyTypeDescription
user_idstringUnique user identifier
emailstringUser email address
phonestringUser phone number
planstringSubscription plan
segmentsstring[]Explicit segment membership
environmentstringEnvironment name (for environment overrides)
customobjectAny custom attributes

Evaluation priority

Flags are evaluated in this order:

  1. Disabled check — if enabled is false, returns false with reason disabled
  2. Time-based activation — if outside active_from/active_until window, returns false with reason disabled
  3. Environment override — if context.environment matches an override, uses that override’s settings
  4. Explicit value — if value is set, returns it with reason override
  5. Targeting rules — evaluates rules in order; first matching rule wins (reason targeting)
  6. Rollout percentage — if no rule matched but a rollout is configured, uses percentage-based inclusion (reason rollout)
  7. Feature default — falls back to the feature’s default_value (reason default)

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.

Terminal window
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

Terminal window
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

Terminal window
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"https://edgeflags.net/api/v1/flags/new_checkout/environments/staging"

Updating a flag

Terminal window
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:

Terminal window
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

Terminal window
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"https://edgeflags.net/api/v1/flags/new_checkout"

Listing flags

Terminal window
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
}