Documentation menu

Feature flags

Module: flags. See README.md for authentication.

Endpoint Scope Permission What it does
GET /apps/{app}/flags read flags.read List feature flags
PUT /apps/{app}/flags/{key} write flags.write Create or replace a flag
DELETE /apps/{app}/flags/{key} write flags.write Archive a flag

Flags are evaluated by the SDKs through POST /api/v1/flags/evaluate, which takes an ingest key, not an access token. This page is the management side.

List

?includeArchived=true&env=production

A row carries the key, name, kind (boolean or multivariate), variants, rules, per-environment settings, and a seven-day sparkline of evaluations.

Upsert

PUT /apps/{app}/flags/new-checkout
{
  "name": "New checkout",
  "description": "Rolling out the rewritten checkout",
  "kind": "multivariate",
  "variants": [{ "key": "control", "weight": 50 }, { "key": "treatment", "weight": 50 }],
  "rules": [
    { "id": "beta-users", "conditions": [{ "field": "trait.plan", "op": "eq", "value": "pro" }], "variant": "treatment" }
  ],
  "environments": {
    "production": { "enabled": true, "rolloutPercent": 25 },
    "staging":    { "enabled": true, "rolloutPercent": 100 }
  }
}

The body replaces the whole definition — send the complete set of variants, rules and environments, not a patch. An environment you omit defaults to disabled at 100%, so a production-only rollout does not have to spell out the other two.

The key comes from the path and must match ^[a-z0-9_-]{1,64}$. A multivariate flag needs at least two variants whose weights total 100. new is reserved.

Bucketing is deterministic: the same distinct id always lands in the same bucket, and the browser and the server agree because both use the same hash.

Archive

DELETE is soft. Evaluation stops, history is kept, and saving the flag again restores it — which is why the history entry says restored rather than created. Archiving an already-archived flag is a 409; an unknown key is a 404.