---
title: Create flag variations
slug: feature-experimentation/docs/create-flag-variations
docTags: 
createdAt: 2026-08-05T20:39:59.000Z
---

A flag variation is a reusable group of flag [variable](docId\:eH-UMm_rOn_GdGDGLV6__) values (also called remote feature configuration or remote variables) that let you avoid hard coding values in your code. Instead of waiting for a deployment, you can group them in a flag variation and then update them remotely in the Optimizely Experimentation application.

Optimizely Feature Experimentation dynamically assigns those variable values to your flag based on your flag rules. For information, see [Flag variations](docId\:QKzlhWuX9v1Df6HlXHUPH).

## Create flag variations

You can create flag variations using the Feature Experimentation UI or the Feature Experimentation REST API.

### Prerequisites

You must create [variables in the flag](docId\:eH-UMm_rOn_GdGDGLV6__) before assigning them to a variation.

### With the REST API

Use the [Create a New Variation](docId:7b0zEkMP9GV4G1vum_dex) endpoint.

**Endpoint** – `POST https://api.optimizely.com/flags/v1/projects/PROJECT_ID/flags/FLAG_KEY/variations`

**Authentication** – Include your API key in the `Authorization` header as a Bearer token. See [Generate tokens and use the REST APIs](docId\:pQfa5KPTbmy6crey-nsrd).

**Request example**

```curl
curl --request POST \
     --url https://api.optimizely.com/flags/v1/projects/PROJECT_ID/flags/doc-test-flag/variations \
     --header 'accept: application/json' \
     --header 'authorization: Bearer TOKEN' \
     --header 'content-type: application/json' \
     --data '
{
  "variables": {
    "show_amounts": {
      "value": "true"
    }
  },
  "key": "on_hide_amounts",
  "name": "On Hide Amounts",
  "description": "Inventory is shown as available or unavailable."
}
'
```

**Response example**

```json
{
  "key": "on_hide_amounts",
  "name": "On Hide Amounts",
  "description": "Inventory is shown as available or unavailable.",
  "variables": {
    "show_amounts": {
      "key": "show_amounts",
      "type": "boolean",
      "value": "true",
      "is_default": false
    }
  },
  "id": ID,
  "urn": "variations.flags.optimizely.com::ID",
  "flag_key": "doc-test-flag",
  "environment_usage_count": {},
  "archived": false,
  "enabled": true,
  "in_use": false,
  "created_time": "2025-09-12T16:29:37.391963Z",
  "updated_time": "2025-09-12T16:29:37.391967Z",
  "url": "/projects/PROJECT_ID/flags/doc-test-flag/variations/on_hide_amounts",
  "update_url": "/projects/PROJECT_ID/flags/doc-test-flag/variations",
  "delete_url": "/projects/PROJECT_ID/flags/doc-test-flag/variations/on_hide_amounts",
  "archive_url": "/projects/PROJECT_ID/flags/doc-test-flag/variations/archived",
  "fetch_flag_url": "/projects/PROJECT_ID/flags/doc-test-flag",
  "revision": 1,
  "role": "admin"
}
```

See the [Create a New Variation](docId:7b0zEkMP9GV4G1vum_dex) endpoint reference for the full list of parameters. You can also follow the [REST API cookbook](docId\:hxlniGd5F_X7vj_ttanPB) and see [step one to create an A/B test](docId\:ocwFy1TPv6MUeigYwdg06).

### With the Feature Experimentation UI

See [Create flag variations](docId\:AL5ZUtJib5Fw1nN4WDQYL) in the user documentation.

## Implement flag variations

You deliver flag variations through [flag rules](docId\:DD_4RoxNZzRQHrmV0bX0f) to control the end-user's experiences. Flag rules can be a [targeted delivery](docId\:R0KSPrSRYev0Q6jXL27QK), an [A/B test](docId\:eJW6k2_6lGLnvTRoS2FIC), or a [Multi-armed bandit optimization](docId\:JaXCjRbh8BbYMGgmsuTvr).

In the [Optimizely Experimentation application](https://app.optimizely.com), you see flag variations, which let you group and reuse variable values.

In your code implementation, you can use the returned `OptimizelyDecision` variation key to execute code conditionally. But, to take full advantage of variables, you must get the values of the variation's variables directly.

The following code sample shows how you would use flag variables:

:::hint{type="info"}
**Note**
This code is indifferent about what type of flag rule the user is in (targeted delivery, A/B test, or Multi-armed bandit), so you can re-use the same code to run different rules.
:::

```csharp
/** 
 * Fetch enabled state for the "product_sort" flag.
 * Then use flag variations to expose different sorting methods and pagination. 
 */

// Define flag variable defaults (if the flag is disabled, you fall back to these values)
var sortMethod = "alphabetical";
var pageLimit = 10;

// Is the flag enabled for the user?
var user = optimizely.CreateUserContext("userId");
var decision = user.Decide("product_sort");
var enabled = decision.Enabled;

/**
 * In the online Optimizely app, go define flag variations using
 * sort_method and page_limit variables. 
 * For example, variation_1 might sort by popularity and limit results to 15 pages.
 */

if (enabled)
{
  // get flag variable values depending on the variation the user bucketed into
  sortMethod = decision.Variables.GetValue<string>("sort_method");

  pageLimit = decision.Variables.GetValue<int>("page_limit");
}


// Fetch products using the flag variables, using something like this pseudocode:
var products = productProvider.Get(sortMethod, pageLimit);
```

```dart
// Fetch enabled state for the "product_sort" flag.
// Then use flag variations to expose different sorting methods and pagination.

// Define flag variable defaults (if the flag is disabled, you fall back to these values)

var sort_method = "alphabetical";
var page_limit = 10;

// Is the flag enabled for the user?
var user = await flutterSDK.createUserContext(userId: "user123");
var decisionResponse = await user!.decide("product_sort");
var decision = decisionResponse.decision;
var enabled = decision!.enabled;

// In the online Optimizely app, go define flag variations using sort_method and page_limit variables. 
// For example, variation_1 might sort by popularity and limit results to 15 pages.

if (enabled) {
    // get flag variable values depending on the variation the user bucketed into
    sort_method = decision.variables["sort_method"];
    page_limit = decision.variables["page_limit"];
  }

// Fetch products using the flag variables, using something like this pseudocode:
var products = ProductProvider.get(sort_method, page_limit);
```

```go
// Fetch enabled state for the "product_sort" flag.
// Then use flag variations to expose different sorting methods and pagination.

//Define flag variable defaults (if the flag is disabled, you fall back to these values)
sortMethod := "alphabetical"
pageLimit := 10

// Is the flag enabled for the user?
user := optimizely.CreateUserContext(userId, nil)
decision := user.Decide("product_sort", nil)
enabled := decision.Enabled

// In the online Optimizely app, go define flag variations using
// sort_method and page_limit variables.
// For example, variation_1 might sort by popularity and limit results to 15 pages.

if enabled {
	// get flag variable values depending on the variation the user bucketed into
	err1 := decision.Variables.GetValue("sort_method", &sortMethod)
	err2 := decision.Variables.GetValue("page_limit", &pageLimit)
}

// Fetch products using the flag variables, using something like this pseudocode:
products := productProvider.get(sortMethod, pageLimit)
```

```java
/**
 * Fetch enabled state for the "product_sort" flag.
 * Then use flag variations to expose different sorting methods and pagination.
 */

// Define flag variable defaults (if the flag is disabled, you fall back to these values)
String sortMethod = "alphabetical";
int pageLimit = 10;

// Is the flag enabled for the user?
OptimizelyUserContext user = optimizely.createUserContext("userId");
OptimizelyDecision decision = user.decide("product_sort");
Boolean enabled = decision.getEnabled();

/**
 * In the online Optimizely app, go define flag variations using
 * sort_method and page_limit variables.
 * For example, variation_1 might sort by popularity and limit results to 15 pages.
 */
if (enabled)
{
  // get flag variable values depending on the variation the user bucketed into
  try {
    sortMethod = decision.getVariables().getValue("sort_method", String.class);
    pageLimit = decision.getVariables().getValue("page_limit", Integer.class);

  } catch (JsonParseException e) {
    e.printStackTrace();
  }
}


// Fetch products using the flag variables, using something like this pseudocode:
List products = productProvider.get(sortMethod, pageLimit);
```

```javascript
// Fetch enabled state for the "product_sort" flag.
// Then use flag variations to expose different sorting methods and pagination. 

// Define flag variable defaults (if the flag is disabled, you fall back to these values)
let sortMethod = 'alphabetical';
let pageLimit = 10;

// Is the flag enabled for the user?
const userId = 'user123'
const user = optimizely.createUserContext(userId);
const decision = user.decide('product_sort');
const enabled = decision.enabled;

//In the online Optimizely app, go define flag variations using
// sort_method and page_limit variables. 
// For example, variation_1 might sort by popularity and limit results to 15 pages.

if (enabled) {
  // get flag variable values depending on the variation the user bucketed into
  sortMethod = decision.variables['sort_method'];
  pageLimit = decision.variables['page_limit'];
}

// Fetch products using the flag variables, using something like this pseudocode:
const products = productProvider.get(sortMethod, pageLimit);
```

```php
/*
 * Fetch enabled state for the "product_sort" flag.
 * Then use flag variations to expose different sorting methods and pagination.
*/

// Define flag variable defaults (if the flag is disabled, you fall back to these values)
$sortMethod = 'alphabetical';
$pageLimit = 10;

// Is the flag enabled for the user?
$userId = "user123";
$user = $optimizely->createUserContext($userId);
$decision = $user->decide('product_sort');
$enabled = $decision->getEnabled();

/**
 * In the online Optimizely app, go define flag variations using
 * sort_method and page_limit variables.
 * For example, variation_1 might sort by popularity and limit results to 15 pages.
 */

if ($enabled) {
    // get flag variable values depending on the variation the user bucketed into
    $sortMethod = (string) $decision->getVariables()['sort_method'];
    $pageLimit = (int) $decision->getVariables()['page_limit'];
}

// Fetch products using the flag variables, using something like this pseudocode:
$products = $productProvider->get($sortMethod, $pageLimit);
```

```python
"""
    Fetch enabled state for the "product_sort" flag.
    Then use flag variations to expose different sorting methods and pagination.
"""

# Define flag variable defaults (if the flag is disabled, you fall back to these values)

sort_method = "alphabetical"
page_limit = 10

# Is the flag enabled for the user?
user = optimizely.create_user_context("user123")
decision = user.decide("product_sort")
enabled = decision.enabled

"""
    In the online Optimizely app, go define flag variations using
    sort_method and page_limit variables.
    For example, variation_1 might sort by popularity and limit results to 15 pages.
"""

if enabled:
    # get flag variable values depending on the variation the user bucketed into
    sort_method = decision.variables["sort_method"]
    page_limit = decision.variables["page_limit"]

# Fetch products using the flag variables, using something like this pseudocode:
products = ProductProvider.get(sort_method, page_limit)
```

```javascript
// Fetch enabled state for the "product_sort" flag.
// Then use flag variations to expose different sorting methods and pagination. 

// Define flag variable defaults (if the flag is disabled, you fall back to these values)
let sort_method = 'alphabetical';
let page_limit = 10;
 
// Is the flag enabled for the user?
const [decision] = useDecision('product_sort');
const enabled = decision.enabled;
                                                        
//In the online Optimizely app, go define flag variations using
// sort_method and page_limit variables. 
// For example, variation_1 might sort by popularity and limit results to 15 pages.
  
if (enabled) {
  // get flag variable values depending on the variation the user bucketed into
  sort_method = decision.variables['sort_method'];
  page_limit = decision.variables['page_limit'];
}

// Fetch products using the flag variables, using something like this pseudocode:
const products = productProvider.get(sort_method, page_limit);
```

```ruby
# frozen_string_literal: true

# Fetch enabled state for the "product_sort" flag.
# Then use flag variations to expose different sorting methods and pagination.

# Define flag variable defaults (if the flag is disabled, you fall back to these values)
sort_method = 'alphabetical'
page_limit = 10

# Is the flag enabled for the user?
user = optimizely.create_user_context(userId)
decision = user.decide('product_sort')
enabled = decision.enabled

# In the online Optimizely app, go define flag variations using
# sort_method and page_limit variables.
# For example, variation_1 might sort by popularity and limit results to 15 pages.

if enabled
  # get flag variable values depending on the variation the user bucketed into
  sort_method = decision.variables['sort_method']
  page_limit = decision.variables['page_limit']
end

# Fetch products using the flag variables, using something like this pseudocode:
products = productProvider.get(sort_method, page_limit)
```

```swift
/**
 * Fetch enabled state for the "product_sort" flag.
 * Then use flag variations to expose different sorting methods and pagination. 
*/


//Define flag variable defaults (if the flag is disabled, you fall back to these values)
var sort_method = "alphabetical"
var page_limit = 10
 
// Is the flag enabled for the user?
let user = optimizely.createUserContext(userId: userId)
let decision = user.decide(key: "product_sort")
let enabled = decision.enabled 

                                                        
/**
  * In the online Optimizely app, go define flag variations using
  * sort_method and page_limit variables. 
  * For example, variation_1 might sort by popularity and limit results to 15 pages.
 */
  
if enabled {
  // get flag variable values depending on the variation the user bucketed into
  let sortMethod: String? = decision.variables.getValue(jsonPath: "sort_method")
  let pageLimit: Int? = decision.variables.getValue(jsonPath: "page_limit")
	}


// Fetch products using the flag variables, using something like this pseudocode:
let products = productProvider.get(sortMethod, pageLimit)
```

For more, see the following example usage documentation:

- [Android SDK](docId:-5ZmWfucr59NAHF3L-aRO)
- [Go SDK](docId:56aBszQ4jbYcwUsHbYALk)
- [C# SDK](docId\:HL2p-_M-JuoQDTEDb4biR)
- [Flutter SDK](docId\:swAM8VY8-KOeQILCpnEqJ)
- [Java SDK](docId:9omynlCMOMwhgcsYGYfNC)
- [JavaScript SDK](docId\:RnHUkcik5UQJxEGJUrWBq) – SDK versions 6.0.0 and later.
- [JavaScript (Browser) SDK](docId\:cag4jmbMcmnKSmH0XYMT1) – SDK versions 5.3.5 and earlier.
- [JavaScript (Node) SDK](docId\:d2uYJpf-kbGu_7m99_JO2) – SDK versions 5.3.5 and earlier.
- [PHP SDK](docId\:O8lfPAO7Cz4taP7UQI_xB)
- [Python SDK](docId:1rPK1ylhrKvWPDHGQr_vc)
- [React SDK](docId\:wI4en3agv9GWyyvZwX94a)
- [Ruby SDK](docId\:v-7jrCxLumTzCT7WU1l8J)
- [Swift SDK](docId\:S-coNtNXZneLCyM4_FeY8)
