Partially update a feature
Updates any combination of a feature’s metadata, default value, environment state, and rules. Other top-level fields are patch-merged: omit a field to leave it unchanged. The rules field, when supplied, replaces the entire rules array atomically in a single revision (v1 PUT applied per-environment patches; v2 swaps the full flat array). To preserve existing rules during a partial edit, GET the feature first, mutate the returned rules array, and PUT the full array back. Safe-rollout rules round-trip via their safeRolloutId; use POST /v2/features/:id/revisions/:version/rules to create new ones. Returns 403 if approval rules are enabled for an affected environment and the bypass setting is off.
curl -X POST 'https://api.growthbook.io/api/v2/features/{id}' \
-H 'Authorization: Bearer YOUR_API_KEY'import requests
url = "https://api.growthbook.io/api/v2/features/{id}"
payload = {
"description": "<string>",
"archived": True,
"project": "<string>",
"owner": "<string>",
"defaultValue": "<string>",
"tags": ["<string>"],
"rules": [
{
"type": "force",
"value": "<string>",
"description": "<string>",
"condition": "<string>",
"savedGroupTargeting": [{ "savedGroups": ["<string>"] }],
"prerequisites": [
{
"id": "<string>",
"condition": "<string>"
}
],
"scheduleRules": [
{
"timestamp": "2023-11-07T05:31:56Z",
"enabled": True
}
],
"id": "<string>",
"enabled": True,
"sparse": True,
"allEnvironments": True,
"environments": ["<string>"]
}
],
"environments": {},
"prerequisites": ["<string>"],
"jsonSchema": "<string>",
"customFields": {},
"holdout": {
"id": "<string>",
"value": "<string>"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
description: '<string>',
archived: true,
project: '<string>',
owner: '<string>',
defaultValue: '<string>',
tags: ['<string>'],
rules: [
{
type: 'force',
value: '<string>',
description: '<string>',
condition: '<string>',
savedGroupTargeting: [{savedGroups: ['<string>']}],
prerequisites: [{id: '<string>', condition: '<string>'}],
scheduleRules: [{timestamp: '2023-11-07T05:31:56Z', enabled: true}],
id: '<string>',
enabled: true,
sparse: true,
allEnvironments: true,
environments: ['<string>']
}
],
environments: {},
prerequisites: ['<string>'],
jsonSchema: '<string>',
customFields: {},
holdout: {id: '<string>', value: '<string>'}
})
};
fetch('https://api.growthbook.io/api/v2/features/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.growthbook.io/api/v2/features/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'description' => '<string>',
'archived' => true,
'project' => '<string>',
'owner' => '<string>',
'defaultValue' => '<string>',
'tags' => [
'<string>'
],
'rules' => [
[
'type' => 'force',
'value' => '<string>',
'description' => '<string>',
'condition' => '<string>',
'savedGroupTargeting' => [
[
'savedGroups' => [
'<string>'
]
]
],
'prerequisites' => [
[
'id' => '<string>',
'condition' => '<string>'
]
],
'scheduleRules' => [
[
'timestamp' => '2023-11-07T05:31:56Z',
'enabled' => true
]
],
'id' => '<string>',
'enabled' => true,
'sparse' => true,
'allEnvironments' => true,
'environments' => [
'<string>'
]
]
],
'environments' => [
],
'prerequisites' => [
'<string>'
],
'jsonSchema' => '<string>',
'customFields' => [
],
'holdout' => [
'id' => '<string>',
'value' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.growthbook.io/api/v2/features/{id}"
payload := strings.NewReader("{\n \"description\": \"<string>\",\n \"archived\": true,\n \"project\": \"<string>\",\n \"owner\": \"<string>\",\n \"defaultValue\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"rules\": [\n {\n \"type\": \"force\",\n \"value\": \"<string>\",\n \"description\": \"<string>\",\n \"condition\": \"<string>\",\n \"savedGroupTargeting\": [\n {\n \"savedGroups\": [\n \"<string>\"\n ]\n }\n ],\n \"prerequisites\": [\n {\n \"id\": \"<string>\",\n \"condition\": \"<string>\"\n }\n ],\n \"scheduleRules\": [\n {\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true\n }\n ],\n \"id\": \"<string>\",\n \"enabled\": true,\n \"sparse\": true,\n \"allEnvironments\": true,\n \"environments\": [\n \"<string>\"\n ]\n }\n ],\n \"environments\": {},\n \"prerequisites\": [\n \"<string>\"\n ],\n \"jsonSchema\": \"<string>\",\n \"customFields\": {},\n \"holdout\": {\n \"id\": \"<string>\",\n \"value\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.growthbook.io/api/v2/features/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"<string>\",\n \"archived\": true,\n \"project\": \"<string>\",\n \"owner\": \"<string>\",\n \"defaultValue\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"rules\": [\n {\n \"type\": \"force\",\n \"value\": \"<string>\",\n \"description\": \"<string>\",\n \"condition\": \"<string>\",\n \"savedGroupTargeting\": [\n {\n \"savedGroups\": [\n \"<string>\"\n ]\n }\n ],\n \"prerequisites\": [\n {\n \"id\": \"<string>\",\n \"condition\": \"<string>\"\n }\n ],\n \"scheduleRules\": [\n {\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true\n }\n ],\n \"id\": \"<string>\",\n \"enabled\": true,\n \"sparse\": true,\n \"allEnvironments\": true,\n \"environments\": [\n \"<string>\"\n ]\n }\n ],\n \"environments\": {},\n \"prerequisites\": [\n \"<string>\"\n ],\n \"jsonSchema\": \"<string>\",\n \"customFields\": {},\n \"holdout\": {\n \"id\": \"<string>\",\n \"value\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.growthbook.io/api/v2/features/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"<string>\",\n \"archived\": true,\n \"project\": \"<string>\",\n \"owner\": \"<string>\",\n \"defaultValue\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"rules\": [\n {\n \"type\": \"force\",\n \"value\": \"<string>\",\n \"description\": \"<string>\",\n \"condition\": \"<string>\",\n \"savedGroupTargeting\": [\n {\n \"savedGroups\": [\n \"<string>\"\n ]\n }\n ],\n \"prerequisites\": [\n {\n \"id\": \"<string>\",\n \"condition\": \"<string>\"\n }\n ],\n \"scheduleRules\": [\n {\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true\n }\n ],\n \"id\": \"<string>\",\n \"enabled\": true,\n \"sparse\": true,\n \"allEnvironments\": true,\n \"environments\": [\n \"<string>\"\n ]\n }\n ],\n \"environments\": {},\n \"prerequisites\": [\n \"<string>\"\n ],\n \"jsonSchema\": \"<string>\",\n \"customFields\": {},\n \"holdout\": {\n \"id\": \"<string>\",\n \"value\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"feature": {
"id": "<string>",
"dateCreated": "2023-11-07T05:31:56Z",
"dateUpdated": "2023-11-07T05:31:56Z",
"archived": true,
"description": "<string>",
"owner": "<string>",
"project": "<string>",
"defaultValue": "<string>",
"tags": [
"<string>"
],
"rules": [
{
"description": "<string>",
"id": "<string>",
"enabled": true,
"type": "force",
"value": "<string>",
"allEnvironments": true,
"condition": "<string>",
"scheduleRules": [
{
"enabled": true,
"timestamp": "2023-11-07T05:31:56Z"
}
],
"rampScheduleId": "<string>",
"savedGroupTargeting": [
{
"savedGroups": [
"<string>"
]
}
],
"prerequisites": [
{
"id": "<string>",
"condition": "<string>"
}
],
"sparse": true,
"environments": [
"<string>"
]
}
],
"environments": {},
"revision": {
"version": 123,
"comment": "<string>",
"date": "2023-11-07T05:31:56Z",
"createdBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
},
"publishedBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
}
},
"prerequisites": [
"<string>"
],
"customFields": {},
"holdout": {
"id": "<string>",
"value": "<string>"
}
}
}Authorizations
If using Bearer auth, pass the Secret Key as the token:
curl https://api.growthbook.io/api/v1/features -H "Authorization: Bearer secret_abc123DEF456"
Path Parameters
The id of the requested resource
Body
Description of the feature
10000An associated project ID
The userId or email address of the owner. If an email address is provided, it will be used to look up the userId of the matching organization member. If an ID is provided, it will be validated as existing in the organization.
List of associated tags. Will override tags completely with submitted list
Replaces all feature rules atomically. Behavior differs from v1: v1 PUT applies per-environment patches, v2 PUT swaps the entire rules array in one revision. To preserve existing rules during a partial edit, GET the feature first, mutate the returned rules array, and PUT the full array back. Safe-rollout rules round-trip via their safeRolloutId (creation requires POST /v2/features/:id/revisions/:version/rules).
- Option 1
- Option 2
- Option 3
- Option 4
Show child attributes
Show child attributes
Per-environment enabled state. V2 rules are specified on the top-level rules field.
Show child attributes
Show child attributes
Feature IDs. Each feature must evaluate to true
Use JSON schema to validate the payload of a JSON-type feature value (enterprise only).
Show child attributes
Show child attributes
Holdout to assign this feature to. Pass null to remove the feature from its current holdout. Omit the field entirely to leave the holdout unchanged.
Show child attributes
Show child attributes
Response
Resource created
Show child attributes
Show child attributes
Was this page helpful?
curl -X POST 'https://api.growthbook.io/api/v2/features/{id}' \
-H 'Authorization: Bearer YOUR_API_KEY'import requests
url = "https://api.growthbook.io/api/v2/features/{id}"
payload = {
"description": "<string>",
"archived": True,
"project": "<string>",
"owner": "<string>",
"defaultValue": "<string>",
"tags": ["<string>"],
"rules": [
{
"type": "force",
"value": "<string>",
"description": "<string>",
"condition": "<string>",
"savedGroupTargeting": [{ "savedGroups": ["<string>"] }],
"prerequisites": [
{
"id": "<string>",
"condition": "<string>"
}
],
"scheduleRules": [
{
"timestamp": "2023-11-07T05:31:56Z",
"enabled": True
}
],
"id": "<string>",
"enabled": True,
"sparse": True,
"allEnvironments": True,
"environments": ["<string>"]
}
],
"environments": {},
"prerequisites": ["<string>"],
"jsonSchema": "<string>",
"customFields": {},
"holdout": {
"id": "<string>",
"value": "<string>"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
description: '<string>',
archived: true,
project: '<string>',
owner: '<string>',
defaultValue: '<string>',
tags: ['<string>'],
rules: [
{
type: 'force',
value: '<string>',
description: '<string>',
condition: '<string>',
savedGroupTargeting: [{savedGroups: ['<string>']}],
prerequisites: [{id: '<string>', condition: '<string>'}],
scheduleRules: [{timestamp: '2023-11-07T05:31:56Z', enabled: true}],
id: '<string>',
enabled: true,
sparse: true,
allEnvironments: true,
environments: ['<string>']
}
],
environments: {},
prerequisites: ['<string>'],
jsonSchema: '<string>',
customFields: {},
holdout: {id: '<string>', value: '<string>'}
})
};
fetch('https://api.growthbook.io/api/v2/features/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.growthbook.io/api/v2/features/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'description' => '<string>',
'archived' => true,
'project' => '<string>',
'owner' => '<string>',
'defaultValue' => '<string>',
'tags' => [
'<string>'
],
'rules' => [
[
'type' => 'force',
'value' => '<string>',
'description' => '<string>',
'condition' => '<string>',
'savedGroupTargeting' => [
[
'savedGroups' => [
'<string>'
]
]
],
'prerequisites' => [
[
'id' => '<string>',
'condition' => '<string>'
]
],
'scheduleRules' => [
[
'timestamp' => '2023-11-07T05:31:56Z',
'enabled' => true
]
],
'id' => '<string>',
'enabled' => true,
'sparse' => true,
'allEnvironments' => true,
'environments' => [
'<string>'
]
]
],
'environments' => [
],
'prerequisites' => [
'<string>'
],
'jsonSchema' => '<string>',
'customFields' => [
],
'holdout' => [
'id' => '<string>',
'value' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.growthbook.io/api/v2/features/{id}"
payload := strings.NewReader("{\n \"description\": \"<string>\",\n \"archived\": true,\n \"project\": \"<string>\",\n \"owner\": \"<string>\",\n \"defaultValue\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"rules\": [\n {\n \"type\": \"force\",\n \"value\": \"<string>\",\n \"description\": \"<string>\",\n \"condition\": \"<string>\",\n \"savedGroupTargeting\": [\n {\n \"savedGroups\": [\n \"<string>\"\n ]\n }\n ],\n \"prerequisites\": [\n {\n \"id\": \"<string>\",\n \"condition\": \"<string>\"\n }\n ],\n \"scheduleRules\": [\n {\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true\n }\n ],\n \"id\": \"<string>\",\n \"enabled\": true,\n \"sparse\": true,\n \"allEnvironments\": true,\n \"environments\": [\n \"<string>\"\n ]\n }\n ],\n \"environments\": {},\n \"prerequisites\": [\n \"<string>\"\n ],\n \"jsonSchema\": \"<string>\",\n \"customFields\": {},\n \"holdout\": {\n \"id\": \"<string>\",\n \"value\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.growthbook.io/api/v2/features/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"<string>\",\n \"archived\": true,\n \"project\": \"<string>\",\n \"owner\": \"<string>\",\n \"defaultValue\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"rules\": [\n {\n \"type\": \"force\",\n \"value\": \"<string>\",\n \"description\": \"<string>\",\n \"condition\": \"<string>\",\n \"savedGroupTargeting\": [\n {\n \"savedGroups\": [\n \"<string>\"\n ]\n }\n ],\n \"prerequisites\": [\n {\n \"id\": \"<string>\",\n \"condition\": \"<string>\"\n }\n ],\n \"scheduleRules\": [\n {\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true\n }\n ],\n \"id\": \"<string>\",\n \"enabled\": true,\n \"sparse\": true,\n \"allEnvironments\": true,\n \"environments\": [\n \"<string>\"\n ]\n }\n ],\n \"environments\": {},\n \"prerequisites\": [\n \"<string>\"\n ],\n \"jsonSchema\": \"<string>\",\n \"customFields\": {},\n \"holdout\": {\n \"id\": \"<string>\",\n \"value\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.growthbook.io/api/v2/features/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"<string>\",\n \"archived\": true,\n \"project\": \"<string>\",\n \"owner\": \"<string>\",\n \"defaultValue\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"rules\": [\n {\n \"type\": \"force\",\n \"value\": \"<string>\",\n \"description\": \"<string>\",\n \"condition\": \"<string>\",\n \"savedGroupTargeting\": [\n {\n \"savedGroups\": [\n \"<string>\"\n ]\n }\n ],\n \"prerequisites\": [\n {\n \"id\": \"<string>\",\n \"condition\": \"<string>\"\n }\n ],\n \"scheduleRules\": [\n {\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true\n }\n ],\n \"id\": \"<string>\",\n \"enabled\": true,\n \"sparse\": true,\n \"allEnvironments\": true,\n \"environments\": [\n \"<string>\"\n ]\n }\n ],\n \"environments\": {},\n \"prerequisites\": [\n \"<string>\"\n ],\n \"jsonSchema\": \"<string>\",\n \"customFields\": {},\n \"holdout\": {\n \"id\": \"<string>\",\n \"value\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"feature": {
"id": "<string>",
"dateCreated": "2023-11-07T05:31:56Z",
"dateUpdated": "2023-11-07T05:31:56Z",
"archived": true,
"description": "<string>",
"owner": "<string>",
"project": "<string>",
"defaultValue": "<string>",
"tags": [
"<string>"
],
"rules": [
{
"description": "<string>",
"id": "<string>",
"enabled": true,
"type": "force",
"value": "<string>",
"allEnvironments": true,
"condition": "<string>",
"scheduleRules": [
{
"enabled": true,
"timestamp": "2023-11-07T05:31:56Z"
}
],
"rampScheduleId": "<string>",
"savedGroupTargeting": [
{
"savedGroups": [
"<string>"
]
}
],
"prerequisites": [
{
"id": "<string>",
"condition": "<string>"
}
],
"sparse": true,
"environments": [
"<string>"
]
}
],
"environments": {},
"revision": {
"version": 123,
"comment": "<string>",
"date": "2023-11-07T05:31:56Z",
"createdBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
},
"publishedBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
}
},
"prerequisites": [
"<string>"
],
"customFields": {},
"holdout": {
"id": "<string>",
"value": "<string>"
}
}
}
