Flags Management
Most customers create and configure flags via the Console UI. The management API is for infrastructure-as-code, CI/CD pipelines, setup scripts, and automated testing. Management operations are stateless HTTP calls — no WebSocket or connect() needed.
Create a Boolean Flag
Create a boolean flag with a default value. The flag is created locally — nothing hits the server until save() is called.
checkout_flag = client.flags.management.newBooleanFlag(
"checkout-v2",
default=False,
description="Controls rollout of the new checkout experience.",
)
await checkout_flag.save()Create a String Flag
String flags can be constrained (closed set of allowed values) or unconstrained. The values parameter defines the allowed set — the Console UI shows dropdowns for value selection.
banner_flag = client.flags.management.newStringFlag(
"banner-color",
default="red",
name="Banner Color",
description="Controls the banner color shown to users.",
values=[
{"name": "Red", "value": "red"},
{"name": "Green", "value": "green"},
{"name": "Blue", "value": "blue"},
],
)
await banner_flag.save()Create a Number Flag
Omitting the values parameter creates an unconstrained flag — any number is valid. Useful for tunables like thresholds, retry counts, and timeouts.
retry_flag = client.flags.management.newNumberFlag(
"max-retries",
default=3,
description="Maximum number of API retries before failing.",
)
await retry_flag.save()Create a JSON Flag
JSON flags serve complex configuration objects. Like string flags, they can be constrained to a set of predefined values.
theme_flag = client.flags.management.newJsonFlag(
"ui-theme",
default={"mode": "light", "accent": "#0066cc"},
description="Controls the UI theme configuration.",
values=[
{"name": "Light", "value": {"mode": "light", "accent": "#0066cc"}},
{"name": "Dark", "value": {"mode": "dark", "accent": "#66ccff"}},
{"name": "High Contrast", "value": {"mode": "dark", "accent": "#ffffff"}},
],
)
await theme_flag.save()Environment Configuration
Each flag can be independently enabled/disabled per environment, with an optional environment-specific default. All mutations are local until save().
checkout_flag.setEnvironmentEnabled("staging", True)
checkout_flag.setEnvironmentEnabled("production", False)
checkout_flag.setEnvironmentDefault("production", False)
await checkout_flag.save()Targeting Rules
Rules define conditions under which a flag serves a specific value. Build rules with the fluent Rule builder. Multiple .when() calls are AND'd. Supported operators: ==, !=, >, <, >=, <=, in, contains.
Single Condition Rule
rule = (
Rule("Blue for enterprise users")
.environment("staging")
.when("user.plan", "==", "enterprise")
.serve("blue")
.build()
)Multi-Condition Rule
rule = (
Rule("Enable for enterprise users in US region")
.environment("staging")
.when("user.plan", "==", "enterprise")
.when("account.region", "==", "us")
.serve(True)
.build()
)Adding Rules to a Flag
addRule() is a local mutation — the rule is appended to the flag's environment rules. Call save() to persist.
checkout_flag.addRule(
Rule("Enable for beta testers")
.environment("staging")
.when("user.beta_tester", "==", True)
.serve(True)
.build()
)
await checkout_flag.save()List and Get Flags
flags = await client.flags.management.list()
for f in flags:
print(f"{f.key} ({f.type}) — default={f.default}")
fetched = await client.flags.management.get("checkout-v2")
print(f"key={fetched.key}, name={fetched.name}")Update a Flag
Fetch, mutate, save. Add values, change defaults, update descriptions. All mutations accumulate locally; a single save() persists everything.
banner_flag.description = "Controls the banner color — updated"
banner_flag.values.append({"name": "Purple", "value": "purple"})
banner_flag.default = "blue"
await banner_flag.save()Clear Rules
Remove all targeting rules from an environment.
checkout_flag.clearRules("staging")
await checkout_flag.save()Delete a Flag
await client.flags.management.delete("checkout-v2")Sync Client (Python)
For synchronous applications (Django, Flask, CLI tools), use SmplClient instead of AsyncSmplClient. The API is identical but without await.
from smplkit import SmplClient, Rule
with SmplClient(environment="staging", service="my-service") as client:
flag = client.flags.management.newBooleanFlag("my-flag", default=False)
flag.save()
flag = client.flags.management.get("my-flag")
flag.setEnvironmentEnabled("staging", True)
flag.addRule(
Rule("...").environment("staging").when("user.plan", "==", "enterprise").serve(True).build()
)
flag.save()
flags = client.flags.management.list()
client.flags.management.delete("my-flag")Next Steps
- Flags Runtime — Declare flags in code, evaluate locally, react to changes
- Smpl Logging — Control log verbosity without redeploying
- API Reference — Flags — Full REST API documentation

