Create feature flags
Describes how to create and implement feature flags in Optimizely Feature Experimentation.
Feature flags, also called feature toggles, permission toggles, or simply flags, let you turn certain functionality on and off without deploying code. They give you full control over the lifecycle of a feature. With feature flags, you can:
- Release code without exposing it to users by keeping the flag off.
- Gradually roll out a feature to a portion of your user base.
- Validate functionality and performance before a full release.
When a collaborator creates a flag, they are automatically assigned theAdmin role for that flag.
Permissions required to create a flag
To create a flag in Feature Experimentation, you must have access to an environment in the project.
When a collaborator creates a flag, they are automatically assigned theAdmin role for that flag.
📘
NoteTo create a flag or audience, a collaborator must haveEditor or above access in at least one environment.
If your project does not use granular permissions, the collaborator must have anEditor or above project role.
Create a flag
With the Feature Experimentation API
Use theCreate a New Flag endpoint.
Endpoint –POST https://api.optimizely.com/flags/v1/projects/PROJECT_ID/flags
Authentication – Include your API key in theAuthorization header as a Bearer token. SeeGenerate tokens and use the REST APIs.
Request example
📘
NoteReplace placeholder text written in all caps with underscores with your information.
curl --request POST \ --url https://api.optimizely.com/flags/v1/projects/PROJECT_ID/flags \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --header 'authorization: Bearer TOKEN' \ --data '{ "outlier_filtering_enabled": BOOLEAN_VALUE, "description": "FLAG_DESCRIPTION", "key": "FLAG_KEY", "name": "FLAG_NAME"}'Response example
{ "key": "doc-test-flag", "name": "Doc test flag", "description": "Flag created via the API", "url": "/projects/PROJECT_ID/flags/doc-test-flag", "update_url": "/projects/PROJECT_ID/flags", "delete_url": "/projects/PROJECT_ID/flags/doc-test-flag", "archive_url": "/projects/PROJECT_ID/flags/archived", "variable_definitions": {}, "environments": { "production": { "key": "production", "name": "Production", "enabled": false, "has_restricted_permissions": true, "priority": 1, "rules_summary": {}, "rules_detail": [], "id": ENVIRONMENT_ID, "enable_url": "/projects/PROJECT_ID/flags/doc-test-flag/environments/production/ruleset/enabled", "created_time": "2025-04-14T19:48:26.000000Z" }, "development": { "key": "development", "name": "Development", "enabled": false, "has_restricted_permissions": false, "priority": 2, "rules_summary": {}, "rules_detail": [], "id": ENVIRONMENT_ID, "enable_url": "/projects/PROJECT_ID/flags/doc-test-flag/environments/development/ruleset/enabled", "created_time": "2025-04-14T19:48:26.000000Z" } }, "id": ID, "urn": "flags.flags.optimizely.com::ID", "archived": false, "outlier_filtering_enabled": true, "project_id": PROJECT_ID, "created_by_user_id": "[email protected]", "created_by_user_email": "[email protected]", "account_id": ACCOUNT_ID, "role": "admin", "created_time": "2025-09-12T16:16:10.260857Z", "updated_time": "2025-09-12T16:16:10.260859Z", "revision": 1}SeeCreate a New Flag API endpoint reference documentation for information on creating a flag with the Feature Experimentation API. You can also follow theREST API cookbook and seestep one to create a flag.
With the Feature Experimentation UI
SeeCreate a flag in the user documentation for a step-by-step guide.
Implement the feature flag
📘
NoteBefore implementing the flag, decide how to pass user identifiers to Feature Experimentation. This ensures each user has a consistent experience of the flag being on or off.
SeeHandle user ids for information.
After you create the flag in the Optimizely Feature Experimentation dashboard, you need to integrate it with your application code. Use theDecide method to enable or disable the flag for a user.
// Decide if user sees a feature flag variationvar user = optimizely.CreateUserContext("user123", new UserAttributes { { "logged_in", true } });var decision = user.Decide("flag_1");var enabled = decision.Enabled;// Decide if user sees a feature flag variationuser := optimizely.CreateUserContext("user123", map[string]interface{}{"logged_in": true})decision := user.Decide("flag_1", nil)enabled := decision.Enabled// Decide if user sees a feature flag variationvar user = await flutterSDK.createUserContext(userId: "user123");var decideResponse = await user.decide("product_sort");var enabled = decision.enabled;// Decide if user sees a feature flag variationOptimizelyUserContext user = optimizely.createUserContext("user123", new HashMap<String, Object>() { { put("logged_in", true); } });OptimizelyDecision decision = user.decide("flag_1");Boolean enabled = decision.getEnabled();// Decide if user sees a feature flag variationconst user = optimizely.createUserContext('user123', { logged_in: true });const decision = user.decide('flag_1');const enabled = decision.enabled;// Decide if user sees a feature flag variation$user = $optimizely->createUserContext('user123', ['logged_in' => true]);$decision = $user->decide('flag_1');$enabled = $decision->getEnabled();# Decide if user sees a feature flag variationuser = optimizely.create_user_context("user123", {"logged_in": True})decision = user.decide("flag_1")enabled = decision.enabled// Decide if user sees a feature flag variationvar decision = useDecision('flag_1', null, { overrideUserAttributes: { logged_in: true }});var enabled = decision.enabled;# Decide if user sees a feature flag variationuser = optimizely_client.create_user_context('user123', {'logged_in' => true})decision = user.decide('flag_1')decision.enabled// Decide if user sees a feature flag variationlet user = optimizely.createUserContext(userId: "user123", attributes: ["logged_in":true])let decision = user.decide(key: "flag_1")let enabled = decision.enabledFor more detailed examples of each SDK, see the following:
- Android SDK example usage
- Go SDK example usage
- C# SDK example usage
- Flutter SDK example usage
- Java SDK example usage
- JavaScript example usage – SDK versions 6.0.0 and later.
- Javascript (Browser) SDK example usage – SDK versions 5.3.5 and earlier.
- JavaScript (Node) SDK example usage – SDK versions 5.3.5 and earlier.
- PHP SDK example usage
- Python SDK example usage
- React SDK example usage
- React Native SDK example usage
- Ruby SDK example usage
- Swift SDK example usage
Adapt the integration code in your application. Show or hide the flag's functionality for a given user ID based on the boolean value your application receives.
TheDecide method separates code deployment from the decision to show a feature. The flag's rules determine the result. For example, it returns false if the user is assigned to the control or "off" variation in an experiment.
Understand the Off variation
In Feature Experimentation, theOff variation is a unique state where you explicitly disable the feature for users. Unlike other variations (such as a, b, c, d) that typically returnenabled: true, theOff variation always returnsenabled: false.
However, this does not exclude users from tracking. Users assigned to theOff variation are still tracked, which you can verify through theruleKey in the decision response.
Variation behaviors
Off variation
enabledresponse –false- Included in datafile – No
- Access method – REST API only
Baseline (non-Off) variation
enabledresponse –true- Included in datafile – Yes
- Access method – Datafile and REST API
Thedecision.enabled flag does not indicate whether a variation is a baseline. Baselines are not included in the datafile but are accessible through the REST API.
If you do not use theOff variation,feature.enabled always returnstrue. Conversely, if you assign theOff variation, it returnsfalse.
TheOff variation affects tracking and decision responses. AlthoughOff is excluded from the datafile, it remains part of the experiment logic and is accessible through API calls.
Next steps
To deliver feature flag configurations, seeCreate flag variations.
Updated 17 days ago