Skip to content

Feature flags

The feature_flags table is a key → value store for runtime configuration. Anything you want to flip without a deploy lives here.

System → Settings (/system/settings): flags live under the “Feature flags” section.

  • Flags with a key beginning with public_ are exposed on the public endpoint GET /v1/flags (unauthenticated). The mobile app polls this at startup.
  • Flags without the prefix are admin-only (server-side reads, admin config).

Examples:

KeyWhere visiblePurpose
public_vas_enabled_egMobileShow VAS entry in EG checkout.
public_new_home_v2MobileNew For You layout gate.
admin_seed_debugAdmin onlyServer-only toggle.
push_apns_enabledServerTurn push provider on/off.

Each flag has a JSON value. Common shapes:

  • Boolean: true / false
  • String: "variant_a"
  • Number: 100
  • Object: { "enabled": true, "percentage": 25, "markets": ["EG", "PH"] }

The mobile client should treat missing keys as their default (usually false). Do not rely on flags to be atomically consistent across users at the exact same moment: the mobile app caches for a short TTL.

System → Settings → Feature flags → Set flag:

  • Key: string, unique.
  • Value: JSON.

Or via API:

Terminal window
curl -X PUT https://api.twistcue.local/v1/admin/flags \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "public_vas_enabled_eg",
"value": true
}'
Terminal window
curl -X DELETE https://api.twistcue.local/v1/admin/flags/public_vas_enabled_eg \
-H "Authorization: Bearer $ADMIN_TOKEN"

Deleting = value becomes undefined. The mobile app should fall back to the default.

Every flag set/delete writes an AuditLog entry: key, before value, after value, admin_id.

  • Renaming a flag: no atomic rename. Create the new, migrate the app to read it, delete the old.
  • JSON values must be valid JSON, not JS. Use "true" (string) or true (bool): pick and stay consistent.
  • public_ flags are cached on the mobile side. Expect ~5 min propagation.
  • Flag storms: don’t accumulate hundreds of flags. Retire them once fully rolled out. Audit periodically.
ActionEndpoint
List flags (admin)GET /v1/admin/flags
Set flagPUT /v1/admin/flags
Delete flagDELETE /v1/admin/flags/:key
Public flags (mobile)GET /v1/flags (unauthenticated, returns only public_* keys)

Full details in API, Engagement (flags live in the engagement module) and API, Public endpoints.