Create a new Holdout
1 min
POST
https://api.optimizely.com/flags/v1//projects/{project_id}/holdouts
Path Parameters
- project_idintegerrequiredExampleDescription
Body Parameters
- bodyHoldoutRequestBodyrequiredExample
{ "audience_conditions": [ "or", { "audience_id": 5340810295 } ], "description": "Holdout group to measure the overall impact of our growth experiments throughout the year", "environment_key": "production", "key": "annual_growth_holdout", "metrics": [ { "aggregator": "unique", "display_title": "Conversion Rate", "scope": "visitor", "winning_direction": "increasing" } ], "name": "Annual Growth Control Group", "project_id": 12345, "project_ids": [ 12345, 67890 ], "scope": "global", "start_time": "2024-01-01T00:00:00.000Z", "traffic_allocation": 500 }Description- audience_conditionsobject[]Description
- audience_idsinteger[]Example
[ 5340810295, 1234567890 ]
Description - descriptionstringExampleDescriptionMax Length1000
- environment_keystringExampleDescription
- exclude_targeted_deliveriesbooleanDescriptionDefaultfalse
- keystringrequiredExampleDescriptionMax Length64Pattern^[a-zA-Z0-9_\-]+$
- metricsMetric[]Description
- aggregatorstring<unique | count | sum | ratio>requiredDescriptionAlloweduniquecountsumratio
- display_titlestringDescription
- display_unitstringDescription
- event_idinteger<int64>ExampleDescriptionFormatint64
- event_propertiesobject
- filterobject
- combine_operatorstring<or | and>Allowedorand
- conditionsEventPropertyCondition[]
- namestringrequired
- operatorstring<equal_to | not_equal_to | greater_than | greater_than_or_equal_to | less_than | less_than_or_equal_to | contains | does_not_contain>requiredAllowedequal_tonot_equal_togreater_thangreater_than_or_equal_toless_thanless_than_or_equal_tocontainsdoes_not_contain
- typestring<string | number | boolean>requiredAllowedstringnumberboolean
- valuestringrequired
- event_typestring
- fieldstring<revenue | value>DescriptionAllowedrevenuevalue
- idstringDescription
- metricsSubMetric[]
- aggregatorstring
- display_titlestring
- event_idinteger
- event_typestring
- fieldstring
- rolestring<numerator | denominator>Allowednumeratordenominator
- scopestring
- project_idintegerDescription
- scopestring<session | visitor | event>DescriptionAllowedsessionvisitorevent
- visibilitystring<account | experiment | project>DescriptionAllowedaccountexperimentproject
- winning_directionstring<increasing | decreasing>requiredDescriptionAllowedincreasingdecreasing
- namestringrequiredExampleDescriptionMax Length255
- project_idinteger<int64>ExampleDescriptionFormatint64
- project_idsinteger[]Example
[ 12345, 67890 ]
Description - rule_idsinteger[]Example
[ 111, 222 ]
Description - scopestring<global | local>ExampleDescriptionDefaultglobalAllowedgloballocal
- start_timestring<date-time>ExampleDescriptionFormatdate-time
- traffic_allocationintegerExampleDescriptionMinimum0Maximum10000
Responses
201
- HoldoutExample
{ "archived": false, "audience_conditions": [ "or", { "audience_id": 5340810295 } ], "created_by_user_email": "[email protected]", "created_time": "2023-12-15T10:00:00.000Z", "description": "Holdout group to measure the overall impact of our growth experiments throughout the year", "environment_key": "production", "holdout_results_api_token": "SampleToken.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", "id": 12345, "key": "annual_growth_holdout", "metrics": [ { "aggregator": "unique", "display_title": "Conversion Rate", "scope": "visitor", "winning_direction": "increasing" } ], "name": "Annual Growth Control Group", "project_id": 98765, "revision": 3, "scope": "global", "start_time": "2024-01-01T00:00:00.000Z", "status": "running", "traffic_allocation": 1000, "updated_time": "2024-01-01T10:00:00.000Z", "urn": "holdout.flag.optimizely.com::12345" }Description- archivedbooleanDescription
- audience_conditionsobject[]ExampleDescription
- audience_idsinteger[]Example
[ 5340810295, 1234567890 ]
Description - created_by_user_emailstringExampleDescription
- created_timestring<date-time>ExampleDescriptionFormatdate-time
- descriptionstringExampleDescriptionMax Length1000
- end_timestring<date-time>ExampleDescriptionFormatdate-time
- environment_keystringExampleDescription
- environment_namestringExampleDescription
- exclude_targeted_deliveriesbooleanDescriptionDefaultfalse
- holdout_results_api_tokenstringExampleDescription
- idintegerrequiredExampleDescription
- keystringrequiredExampleDescriptionMax Length64Pattern^[a-zA-Z0-9_\-]+$
- metricsMetric[]Description
- aggregatorstring<unique | count | sum | ratio>requiredDescriptionAlloweduniquecountsumratio
- display_titlestringDescription
- display_unitstringDescription
- event_idinteger<int64>ExampleDescriptionFormatint64
- event_propertiesobject
- filterobject
- combine_operatorstring<or | and>Allowedorand
- conditionsEventPropertyCondition[]
- namestringrequired
- operatorstring<equal_to | not_equal_to | greater_than | greater_than_or_equal_to | less_than | less_than_or_equal_to | contains | does_not_contain>requiredAllowedequal_tonot_equal_togreater_thangreater_than_or_equal_toless_thanless_than_or_equal_tocontainsdoes_not_contain
- typestring<string | number | boolean>requiredAllowedstringnumberboolean
- valuestringrequired
- event_typestring
- fieldstring<revenue | value>DescriptionAllowedrevenuevalue
- idstringDescription
- metricsSubMetric[]
- aggregatorstring
- display_titlestring
- event_idinteger
- event_typestring
- fieldstring
- rolestring<numerator | denominator>Allowednumeratordenominator
- scopestring
- project_idintegerDescription
- scopestring<session | visitor | event>DescriptionAllowedsessionvisitorevent
- visibilitystring<account | experiment | project>DescriptionAllowedaccountexperimentproject
- winning_directionstring<increasing | decreasing>requiredDescriptionAllowedincreasingdecreasing
- namestringrequiredExampleDescriptionMax Length255
- project_idinteger<int64>ExampleDescriptionFormatint64
- projectsobject[]Example
[ { "id": 123 } ]Description- idinteger<int64>DescriptionFormatint64
- revisionintegerExampleDescription
- rulesobject[]Example
[ { "flag_key": "my_flag", "id": 456, "key": "experiment_rule_a", "name": "Experiment Rule A", "project_id": 123 } ]Description- flag_idinteger<int64>DescriptionFormatint64
- flag_keystringDescription
- flag_namestringDescription
- idinteger<int64>DescriptionFormatint64
- keystringDescription
- namestringDescription
- project_idinteger<int64>DescriptionFormatint64
- scopestring<global | local>ExampleDescriptionAllowedgloballocal
- start_timestring<date-time>ExampleDescriptionFormatdate-time
- statusstring<draft | running | concluded>ExampleDescriptionAlloweddraftrunningconcluded
- traffic_allocationintegerExampleDescriptionMinimum0Maximum10000
- updated_timestring<date-time>ExampleDescriptionFormatdate-time
- urlstringExampleDescription
- urnstringExampleDescription
400
- ProblemDetailExamplesDuplicate holdout key:
{ "detail": "Another entity already exists with the key 'checkout_holdout'.", "status": 400, "title": "Key checkout_holdout already exists", "type": "about:blank" }Invalid request data:{ "detail": "traffic_allocation must be between 0 and 10000", "status": 400, "title": "Invalid request data", "type": "about:blank" }Description- detailstringrequiredDescription
- statusintegerrequiredDescription
- titlestringrequiredDescription
- typestringrequiredDescription
- uuidstringDescription
401
403
curl
curl --request POST \
--url https://api.optimizely.com/flags/v1//projects/{project_id}/holdouts \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"key": "annual_growth_holdout",
"metrics": [
{
"aggregator": "",
"event_properties": {
"filter": {
"conditions": [
{
"name": "",
"operator": "",
"type": "",
"value": ""
}
]
}
},
"winning_direction": ""
}
],
"name": "Annual Growth Control Group",
"scope": "global"
}'javascript
var myHeaders = new Headers();
myHeaders.append("accept", "application/json");
myHeaders.append("content-type", "application/json");
var raw = JSON.stringify({
"key": "annual_growth_holdout",
"metrics": [
{
"aggregator": "",
"event_properties": {
"filter": {
"conditions": [
{
"name": "",
"operator": "",
"type": "",
"value": ""
}
]
}
},
"winning_direction": ""
}
],
"name": "Annual Growth Control Group",
"scope": "global"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.optimizely.com/flags/v1//projects/{project_id}/holdouts", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));ruby
require "uri"
require "json"
require "net/http"
url = URI("https://api.optimizely.com/flags/v1//projects/{project_id}/holdouts")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["accept"] = "application/json"
request["content-type"] = "application/json"
request.body = JSON.dump({
"key": "annual_growth_holdout",
"metrics": [
{
"aggregator": "",
"event_properties": {
"filter": {
"conditions": [
{
"name": "",
"operator": "",
"type": "",
"value": ""
}
]
}
},
"winning_direction": ""
}
],
"name": "Annual Growth Control Group",
"scope": "global"
})
response = https.request(request)
puts response.read_body
python
import requests
import json
url = "https://api.optimizely.com/flags/v1//projects/{project_id}/holdouts"
payload = json.dumps({
"key": "annual_growth_holdout",
"metrics": [
{
"aggregator": "",
"event_properties": {
"filter": {
"conditions": [
{
"name": "",
"operator": "",
"type": "",
"value": ""
}
]
}
},
"winning_direction": ""
}
],
"name": "Annual Growth Control Group",
"scope": "global"
})
headers = {
'accept': 'application/json',
'content-type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
201
// Successful retrieval, creation or update of a Holdout.
The response includes RESTful JSON (https://restfuljson.org/) styled links. If a
link is not present in the response, it indicates a user is not authorized to access
the related resource.
{
"archived": false,
"audience_conditions": [
{}
],
"audience_ids": [
0
],
"created_by_user_email": "[email protected]",
"created_time": "2023-12-15T10:00:00.000Z",
"description": "Holdout group to measure the overall impact of our growth experiments throughout the year",
"end_time": "2024-12-31T23:59:59.000Z",
"environment_key": "production",
"environment_name": "Production",
"exclude_targeted_deliveries": false,
"holdout_results_api_token": "SampleToken.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
"id": 12345,
"key": "annual_growth_holdout",
"metrics": [
{
"aggregator": "",
"display_title": "",
"display_unit": "",
"event_id": 32334454244,
"event_properties": {
"filter": {
"combine_operator": "",
"conditions": [
{
"name": "",
"operator": "",
"type": "",
"value": ""
}
]
}
},
"event_type": "",
"field": "",
"id": "",
"metrics": [
{
"aggregator": "",
"display_title": "",
"event_id": 0,
"event_type": "",
"field": "",
"role": "",
"scope": ""
}
],
"project_id": 0,
"scope": "",
"visibility": "",
"winning_direction": ""
}
],
"name": "Annual Growth Control Group",
"project_id": 98765,
"projects": [
{
"id": ""
}
],
"revision": 3,
"rules": [
{
"flag_id": "",
"flag_key": "",
"flag_name": "",
"id": "",
"key": "",
"name": "",
"project_id": ""
}
],
"scope": "global",
"start_time": "2024-01-01T00:00:00.000Z",
"status": "running",
"traffic_allocation": 1000,
"updated_time": "2024-01-01T10:00:00.000Z",
"url": "/holdouts/12345",
"urn": "holdout.flag.optimizely.com::12345"
}400
// Bad Request - Invalid input data or validation failure.
Common causes:
Missing required fields (key or name)
Duplicate holdout key within the project
Invalid key format (must be alphanumeric with underscores/hyphens only)
traffic_allocation outside valid range (0-10000)
Field length limits exceeded
Invalid JSON structure in request body
Malformed audience conditions or metrics configuration
{
"detail": "",
"status": 0,
"title": "",
"type": "",
"uuid": ""
}GENERATED
// Bad Request - Invalid input data or validation failure.
Common causes:
Missing required fields (key or name)
Duplicate holdout key within the project
Invalid key format (must be alphanumeric with underscores/hyphens only)
traffic_allocation outside valid range (0-10000)
Field length limits exceeded
Invalid JSON structure in request body
Malformed audience conditions or metrics configuration
{
"detail": "",
"status": 0,
"title": "",
"type": "",
"uuid": ""
}duplicate_key
// Duplicate holdout key
{
"detail": "Another entity already exists with the key 'checkout_holdout'.",
"status": 400,
"title": "Key checkout_holdout already exists",
"type": "about:blank"
}invalid_data
// Invalid request data
{
"detail": "traffic_allocation must be between 0 and 10000",
"status": 400,
"title": "Invalid request data",
"type": "about:blank"
}401
// Invalid credentials
403
// Do not have permission to perform the operation