# Update a feature

> For the complete machine-readable documentation index, see [llms.txt](https://apidocs.chargebee.com/llms.txt).


[Idempotency Supported](/docs/api/idempotency)

Updates a specific feature.

**Note**

The list of objects `levels[]` provided as part of this operation fully replaces the existing list of objects `[levels[]](/docs/api/features/feature-object#levels)` of the feature.

### Considerations when modifying `levels`[](#considerations-when-modifying-levels)

This section describes validations that are performed by Chargebee when modifying the `levels` list of objects for the feature, using this operation.

#### Adding `levels`[](#adding-levels)

Adding a new object to the `levels[]` list is allowed if and only if the feature `[type](/docs/api/features/feature-object#type)` is `quantity` or `custom`

#### Removing `levels`[](#removing-levels)

Removing an existing object in the `levels[]` list is not allowed if the `value` for that object is currently mapped to one or more `[item_entitlement](/docs/api/item_entitlements)`s or `[subscription_entitlement](/docs/api/subscription_entitlements)`s.

#### Reordering `levels`[](#reordering-levels)

**Note**

The validation described in this section is only applicable for features of `type` `custom`

If any of `levels[].value` are currently mapped to `item_entitlement`s or `subscription_entitlement`s, then the relative order of the corresponding `levels[].level` must be preserved when invoking this operation.

For example, consider that the `levels[]` list is currently in the state shown below. (For brevity, only the `value` and `level` key are shown here and the JSONs have been compacted.)

Now consider that `email-rise`, `email-advanced`, and `email-pro` have already been mapped to `item_entitlement`s or `subscription_entitlement`s. As seen in the above object, the relative order of `levels[].level` is such that `email-rise` < `email-advanced` < `email-pro`.

Invoking this API to change `levels[]` to the state below is allowed since the relative order of `level` corresponding to `email-rise`, `email-advanced`, and `email-pro` has been preserved.

However, changing `levels[]` to the state shown below is not permissible because the `level` of `email-advanced` is provided as greater than the `level` of `email-pro`, thereby disrupting the original order.

## Sample Request

#### cURL

```bash
curl  https://{site}.chargebee.com/api/v2/features/fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede \
     -u {site_api_key}:\
     -d name="User Licenses (updated name)" \
     -d description="Maximum number of user licenses allowed" \
     -d "levels[level][0]"=0 \
     -d "levels[value][0]"="25" \
     -d "levels[name][0]"="25 Users" \
     -d "levels[level][1]"=1 \
     -d "levels[value][1]"="100" \
     -d "levels[name][1]"="100 Users" \
     -d "levels[level][2]"=2 \
     -d "levels[value][2]"="Unlimited" \
     -d "levels[name][2]"="Unlimited Users" \
     -d "levels[is_unlimited][2]"="true"
```

#### .NET

```dotnet
using ChargeBee.Api;
using ChargeBee.Models;

ApiConfig.Configure("{site}","{site_api_key}");
EntityResult result = Feature.Update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede")
		.Name("User Licenses (updated name)")
		.Description("Maximum number of user licenses allowed")
		.LevelLevel(0, 0)
		.LevelValue(0, "25")
		.LevelName(0, "25 Users")
		.LevelLevel(1, 1)
		.LevelValue(1, "100")
		.LevelName(1, "100 Users")
		.LevelLevel(2, 2)
		.LevelValue(2, "Unlimited")
		.LevelName(2, "Unlimited Users")
		.LevelIsUnlimited(2, true)
		.Request();

Feature feature = result.Feature;
```

#### Go

```go
package main
import (
    "fmt"
    "github.com/chargebee/chargebee-go/v3"
    featureAction "github.com/chargebee/chargebee-go/v3/actions/feature"
    "github.com/chargebee/chargebee-go/v3/models/feature"
)
func main() {
    chargebee.Configure("{site_api_key}","{site}");
    res,err := featureAction.Update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede", &feature.UpdateRequestParams{
        Levels : []*feature.UpdateLevelParams{
            {
                Level : chargebee.Int32(0),
                Value : "25",
                Name : "25 Users",
            },
            {
                Level : chargebee.Int32(1),
                Value : "100",
                Name : "100 Users",
            },
            {
                Level : chargebee.Int32(2),
                Value : "Unlimited",
                Name : "Unlimited Users",
                IsUnlimited : chargebee.Bool(true),
            },
        },
        Name : "User Licenses (updated name)",
        Description : "Maximum number of user licenses allowed",
    }).Request()
    if err != nil {
        fmt.Println(err)
    } else {
        Feature := res.Feature
    }
}
```

#### Go

```go
package main

import (
  "fmt"
  "github.com/chargebee/chargebee-go/v4"
)

func main() {
  config := &chargebee.ClientConfig{
    SiteName: "{site}",
    ApiKey: "{site_api_key}",
  }    
  client := chargebee.NewClient(config)
  req := &chargebee.FeatureUpdateRequest{
    Levels : []*chargebee.FeatureUpdateLevel{
        {
            Level : chargebee.Int32(0),
            Value : "25",
            Name : "25 Users",
        },
        {
            Level : chargebee.Int32(1),
            Value : "100",
            Name : "100 Users",
        },
        {
            Level : chargebee.Int32(2),
            Value : "Unlimited",
            Name : "Unlimited Users",
            IsUnlimited : chargebee.Bool(true),
        },
    },
    Name : "User Licenses (updated name)",
    Description : "Maximum number of user licenses allowed",
}
  res, err := client.Feature.Update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede", req)
      if err != nil {
        fmt.Println(err)
    } else {
        Feature := res.Feature
    }
}
```

#### Java

```java
import com.chargebee.*;
import com.chargebee.ListResult;
import com.chargebee.models.*;
import com.chargebee.models.enums.*;
import java.io.IOException;

public class Sample {

    public static void main(String args[]) throws IOException, Exception {
        Environment.configure("{site}", "{site_api_key}");
        Result result = Feature.update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede")
            .name("User Licenses (updated name)")
            .description("Maximum number of user licenses allowed")
            .levelLevel(0, 0)
            .levelValue(0, "25")
            .levelName(0, "25 Users")
            .levelLevel(1, 1)
            .levelValue(1, "100")
            .levelName(1, "100 Users")
            .levelLevel(2, 2)
            .levelValue(2, "Unlimited")
            .levelName(2, "Unlimited Users")
            .levelIsUnlimited(2, true)
            .request();

        Feature feature = result.feature();
    }
}
```

#### Java

```java
import com.chargebee.v4.client.ChargebeeClient;
import com.chargebee.v4.models.feature.Feature;
import com.chargebee.v4.models.feature.params.FeatureUpdateParams;
import com.chargebee.v4.models.feature.responses.FeatureUpdateResponse;
import java.util.List;

public class FeatureUpdate {

    public static void main(String[] args) {
        ChargebeeClient client = ChargebeeClient.builder()
            .apiKey("{site_api_key}")
            .siteName("{site}")
            .build();

        FeatureUpdateParams.LevelsParams level0 =
            FeatureUpdateParams.LevelsParams.builder()
                .level(0)
                .value("25")
                .name("25 Users")
                .build();

        FeatureUpdateParams.LevelsParams level1 =
            FeatureUpdateParams.LevelsParams.builder()
                .level(1)
                .value("100")
                .name("100 Users")
                .build();

        FeatureUpdateParams.LevelsParams level2 =
            FeatureUpdateParams.LevelsParams.builder()
                .level(2)
                .value("Unlimited")
                .name("Unlimited Users")
                .isUnlimited(true)
                .build();

        List<FeatureUpdateParams.LevelsParams> levelsList =
            List.of(level0, level1, level2);

        FeatureUpdateParams params = FeatureUpdateParams.builder()
            .name("User Licenses (updated name)")
            .description("Maximum number of user licenses allowed")
            .levels(levelsList)
            .build();

        FeatureUpdateResponse response = client
            .features()
            .update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede", params);

        Feature feature = response.getFeature();
    }
}
```

#### Node.js

```node
import Chargebee from "chargebee";

const chargebee = new Chargebee({
    site: "{site}",
    apiKey: "{site_api_key}",
});

try {
    const result = await chargebee.feature.update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede", {
        levels: [
            {
                level: 0,
                value: 25,
                name: "25 Users"
            },
            {
                level: 1,
                value: 100,
                name: "100 Users"
            },
            {
                level: 2,
                value: "Unlimited",
                name: "Unlimited Users",
                is_unlimited: true
            }
        ],
        name: "User Licenses (updated name)",
        description: "Maximum number of user licenses allowed"
    });

    console.log(result);
    const feature = result.feature;
} catch (err) {
    console.log(err);
}
```

#### PHP

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Chargebee\ChargebeeClient;

$chargebee = new ChargebeeClient(options: [
    "site" => "{site}",
    "apiKey" => "{site_api_key}",
]);
$result = $chargebee->feature()->update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede", [
    "levels" => [
        [
            "level" => 0,
            "value" => 25,
            "name" => "25 Users"
        ],
        [
            "level" => 1,
            "value" => 100,
            "name" => "100 Users"
        ],
        [
            "level" => 2,
            "value" => "Unlimited",
            "name" => "Unlimited Users",
            "is_unlimited" => true
        ]
    ],
    "name" => "User Licenses (updated name)",
    "description" => "Maximum number of user licenses allowed"
]);
$feature = $result->feature;
```

#### Python

```python
from chargebee import Chargebee

cb_client = Chargebee(api_key="{site_api_key}", site="{site}")
response = cb_client.Feature.update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede",
    cb_client.Feature.UpdateParams(
        levels=[
            cb_client.Feature.UpdateLevelParams(
              level=0,
              value="25",
              name="25 Users"
            ),
            cb_client.Feature.UpdateLevelParams(
              level=1,
              value="100",
              name="100 Users"
            ),
            cb_client.Feature.UpdateLevelParams(
              level=2,
              value="Unlimited",
              name="Unlimited Users",
              is_unlimited=True
            )
        ],
        name="User Licenses (updated name)",
        description="Maximum number of user licenses allowed"
    )
)
feature = response.feature
```

#### Ruby

```ruby
require 'chargebee'

ChargeBee.configure(:site => "{site}",
  :api_key => "{site_api_key}")

result = ChargeBee::Feature.update("fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede",{
  :name => "User Licenses (updated name)",
  :description => "Maximum number of user licenses allowed",
  :levels => [
    {
      :level => 0,
      :value => "25",
      :name => "25 Users"
    },
    {
      :level => 1,
      :value => "100",
      :name => "100 Users"
    },
    {
      :level => 2,
      :value => "Unlimited",
      :name => "Unlimited Users",
      :is_unlimited => "true"
    }
  ]
})

feature = result.feature
```

## Sample Response

```json
{
  "feature": {
    "description": "Maximum number of user licenses allowed",
    "id": "fea-a5d1f7de-c58c-45da-a08b-6934e3ab3ede",
    "levels": [
      {
        "is_unlimited": false,
        "level": 0,
        "name": "25 Users",
        "value": "25"
      },
      {..}
    ],
    "name": "User Licenses (updated name)",
    "object": "feature",
    "status": "active",
    "type": "quantity"
  }
}
```

## URL Format

**POST** https://[site].chargebee.com/api/v2/features/{feature-id}

## Input Parameters

- `name` (optional, string, max chars=50)
  A case-sensitive unique name for the feature. For example: `user license` , `data storage` , `Salesforce Integration` , `devices` , `UHD Streaming` , and so on.
  
  **Note:** This name is not displayed on any customer-facing documents or pages such as [invoice PDFs](/docs/api/invoices/retrieve-invoice-as-pdf) or [hosted pages](/docs/api/hosted_pages). However, in the future, it is likely to be introduced on the [Self-Serve Portal](/docs/api/portal_sessions) .

- `description` (optional, string, max chars=500)
  A brief description of the feature. For example: `Access to 10TB cloud storage` .

- `status` (optional, enumerated string)
  The current status of the feature.
  Possible enum values:
    - `active`
      A `draft` or an `archived` feature can be changed to `active`. Any [entitlements](/docs/api/entitlements) or [subscription entitlements](/docs/api/subscription_entitlements) defined for the feature take effect immediately.
    - `archived`
      An `active` feature can be changed to `archived`. Once `archived` , no **new** [entitlements](/docs/api/entitlements) or [subscription entitlements](/docs/api/subscription_entitlements) can be created for the feature. However, any pre-existing item or subscription entitlements from the time that the feature was `active` , remain effective.
    - `draft`
      The feature is in an unpublished state. [Entitlements](/docs/api/entitlements) and [subscription entitlements](/docs/api/subscription_entitlements) can be created for a draft feature but they are not effective until the feature is active. A feature `status` cannot be changed back to `draft` once it is in `active` or `archived` `status` .

- `unit` (optional, string, max chars=50)
  For features of `type` `quantity` or `range` , this specifies the unit of measure. The value is expected in the singular form and when used by the system, it is pluralized automatically as needed. For example, for a feature such as `user licenses` , the `unit` can be `license` .

- `levels` (optional, array)
  Parameters for levels
  - `name` (optional, string, max chars=50)
    A case-sensitive display name for the entitlement level. Provide a name that helps you clearly identify the entitlement level. For example: a feature such as `Email Support` can have entitlement levels named as `All weekdays` , `All days` , `40 hours per week` and so on.
    
    When not provided for `feature.type` `quantity` or `range` , this name is auto-generated as the space-separated concatenation of `levels[].value` and the pluralized version of `unit`. For example, if `levels[].value` is `20` and `unit` is `user` , then `levels[].name` becomes `20 users` .
  - `value` (optional, string, max chars=50)
    The value denoting the entitlement level granted.
    
    -   **When `type` is `quantity`:** this attribute denotes the quantity of units of the feature for this entitlement level. For example, a feature such as `number of users` can have `levels[].value` as `5`, `20`, `50`, and `100`. `levels[].is_unlimited` is used to set the entitlement level to "unlimited".
    -   **When `type` is `range`:** there can be only two elements in the `levels[]` array; one corresponding to the minimum value (`levels[0]`) and the other to the maximum value (`levels[1]`) of the range of possible entitlement levels. For example, a feature such as `number of users` may have `levels[0].value` = `5` and `levels[1].value` = `50000`. When the upper limit is "unlimited", then `levels[1].value` is not set and `levels[1].is_unlimited` is `true`.
    -   **When `type` is `custom`:** this attribute denotes the value of this custom entitlement level. For example, a feature `Email Support` can have `levels[].value` as one of say, `24×7` and `24×5`.
    
    **Note**
    
    This must be provided exactly as it already exists for the feature if the `value` is currently mapped to an `[entitlement](/docs/api/entitlements)`s or `[subscription_entitlement](/docs/api/subscription_entitlements)`s.
  - `is_unlimited` (optional, boolean)
    When `type` is `quantity` or `range`, this attribute indicates whether the entitlement level corresponds to unlimited units of the feature. Possible values are:
    
    -   `true`: The entitlement level corresponds to unlimited units of the feature. `levels[].value` is ignored for this level. This can only be set for the level that has the highest value for `levels[].level.`
    -   `false`: The entitlement level does not correspond to unlimited units of the feature.
    
    Either this or levels\[value\] should be passed.
  - `level` (optional, integer)
    Represents the order of the entitlement levels from lowest to highest.
    
    -   **When `type` is `quantity`:** Provide the `level` for the lowest entitlement level as `0`, the next higher level as `1`, followed by `2`, and so on.
    -   **When `type` is `custom`:** Provide the `level` for the lowest entitlement level as `0`, the next higher level as `1`, followed by `2`, and so on. **Note:** There are some validations to be considered.
    -   **When `type` is `range`:** Provide `0` for the minimum value and `1` for the maximum value in the range.
    
    When not defined, it is assumed as the index of the `levels[]` array.

## Returns

- `feature` (Feature object)
  Resource object representing feature
