Feature flags
Ship code behind a flag, then turn it on from the console: for previews first, then for a share of Production users, then for everyone. No deploy in between.
Create a flag
- Open Settings › Feature flagsOn the app, open the Settings tab and choose Feature flags.
- Fill in New flagEnter a Name such as
new-checkout(lowercase letters, numbers,.,_and-, starting with a letter) and an optional Description. - Select Create flagNew flags start off, for Previews only, at 0%.
Each app can have up to 100 flags. Owners, admins and builders can create and change flags; viewers can see them.
Choose who gets it
Each flag has four controls:
- On/off switch
- Off means every request gets
false. - Where
- Previews only, Production only, or Production and previews.
- Rollout
- The percentage of identities that get the flag, from 0 to 100. The same identity always gets the same answer.
- Always-on IDs
- Up to 100 identities that always get the flag while it is on, whatever the rollout. One per line. Select Save IDs.
Any change that turns a flag on for Production users, or widens how many get it, asks first. For example: Turn on new-checkout for 10% of Production users? Takes effect within 30 seconds. Select Turn on for Production or Apply to Production to confirm.
To remove a flag, open its always-on IDs and select Delete…, then confirm. Apps then get false for it within 30 seconds.
Create a read key
Your app reads flags with a read key. Each app has one.
- Select Create read keyUnder Read key, at the top of the section.
- Copy it nowAOZUMI does not show it again.
- Select Store as AOZUMI_FLAGS_KEYThis saves it as a Production variable. Deploy again so the app receives it.
Rotate… replaces the key; the old one stops working within 30 seconds, so update the app with the new one. Revoke… removes it; apps using it fall back to their defaults within 30 seconds. Both ask first.
Read flags from your app
Send a GET request with the key as a bearer token. Pass a stable user or account ID as identity, so partial rollouts give the same answer every time.
curl -H "Authorization: Bearer $AOZUMI_FLAGS_KEY" \
"https://aozumi.dev/api/flags/v1/evaluate?identity=USER_ID&environment=production"
# {"flags":{"new-checkout":true},"reasons":{"new-checkout":"rollout"}}
identity- Optional. Up to 128 characters. Needed for a rollout between 1% and 99%.
environmentproduction(the default) orpreview.flags- Optional. A comma-separated list of flag names, to read only those.
// Read every flag once per request; fall back to defaults on any error.
export async function readFlags(userId) {
try {
const url = new URL("https://aozumi.dev/api/flags/v1/evaluate");
url.searchParams.set("identity", userId);
url.searchParams.set("environment", "production");
const response = await fetch(url, { headers: { authorization: `Bearer ${process.env.AOZUMI_FLAGS_KEY}` } });
if (!response.ok) return {};
return (await response.json()).flags;
} catch {
return {};
}
}
How a flag is decided
AOZUMI checks these in order and stops at the first that applies. The reasons field names which one did.
- The flag is off:
false(disabled). - Where does not include this environment:
false(environment). - The identity is an always-on ID:
true(allow_list). - Rollout is 100%:
true(on). Rollout is 0%:false(rollout_excluded). - No identity was sent:
false(identity_required). - Otherwise the identity falls inside or outside the rollout:
rolloutorrollout_excluded.
Flags are on/off only. Values other than true and false, and targeting by user attributes, are not supported.
Questions
- How fast does a feature flag change reach my app?
- Within 30 seconds. Flags are read through a short cache, so there is no deploy and no restart.
- Is a new flag on in Production?
- No. A new flag starts off, for previews only, at 0%. Production users get it only after you choose Production and confirm.
- What happens if the flags request fails?
- Your app should use its built-in default. When flags are temporarily unavailable the endpoint answers 503 and says to use your defaults.
- Can I call the flags endpoint from the browser?
- Yes. A read key can only read this app's flags, and the endpoint allows cross-origin GET requests. Anyone who can see the key can read the flags, so keep secrets out of flag names and descriptions.
Checked against the product on .