# Apply business rules

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


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

Evaluates business rules against a context that you supply. You can evaluate a single rule using `rule_id`, every rule in a ruleset using `ruleset_id`, or an ad hoc expression using `structured_expression`. Set `evaluate` to `true` to return only the evaluation result without running the actions configured on the rules.

These three parameters are independent of one another rather than alternatives. Passing more than one evaluates each of them in the same request and returns the results together, so a request carrying both `rule_id` and `ruleset_id` evaluates that rule and that ruleset.

The response returns one entry in `apply_rule.rules[]` for each rule that was evaluated, carrying the `evaluation_result` of its expression, the `actions` that the result triggered, and an `error_message` when the rule could not be evaluated. The entry for an ad hoc `structured_expression` carries only `evaluation_result`, because there is no stored rule to describe.

### Prerequisites & Constraints

-   Business rules must be enabled for the site.
-   A rule referenced by `rule_id` must be released and `active`, and a ruleset referenced by `ruleset_id` must be `active`.

### Use Cases

Evaluate a single rule

Pass `rule_id` along with the `context`. The latest released version of that rule is evaluated on its own.

Evaluate a group of rules together

Pass `ruleset_id` along with the `context`. The rules in the ruleset are evaluated in their priority order, and the ruleset `execute_mode` decides whether evaluation stops early and which results are returned.

Test an expression before saving it

Pass `structured_expression` and the `context` you want to test it against, with `evaluate` set to `true`. This evaluates the expression without creating a rule and without executing any actions.

## Sample Request

#### cURL

```bash
curl  https://{site}.chargebee.com/api/v2/business_rules/apply_rules \
     -u {site_api_key}:\
     -d ruleset_id="quote_create_rules" \
     -d context='{"type":"CPQ","customer":{"language":"en"},"quote":{"shipping_address_country":"IN"}}'
```

#### .NET

```dotnet
using ChargeBee.Api;
using ChargeBee.Models;
using Newtonsoft.Json.Linq;

ApiConfig.Configure("{site}","{site_api_key}");
var context = new JObject {
  ["type"] = "CPQ",
  ["customer"] = "{\"language\":\"en\"}",
  ["quote"] = "{\"shipping_address_country\":\"IN\"}"
};
EntityResult result = BusinessRule.ApplyRules()
		.RulesetId("quote_create_rules")
		.Context(context)
		.Request();

ApplyRule applyRule = result.ApplyRule;
```

#### Go

```go
package main
import (
    "fmt"
    "github.com/chargebee/chargebee-go/v3"
    businessruleAction "github.com/chargebee/chargebee-go/v3/actions/businessrule"
    "github.com/chargebee/chargebee-go/v3/models/businessrule"
)
func main() {
    chargebee.Configure("{site_api_key}","{site}");
    res,err := businessruleAction.ApplyRules(&businessrule.ApplyRulesRequestParams{
        RulesetId : "quote_create_rules",
        Context : &businessrule.ApplyRulesContextParams{
            Type : "CPQ",
            Customer : map[string]interface{}{
    "language" : "en",
},
            Quote : map[string]interface{}{
    "shipping_address_country" : "IN",
},
        },
    }).Request()
    if err != nil {
        fmt.Println(err)
    } else {
        ApplyRule := res.ApplyRule
    }
}
```

#### 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.BusinessRuleApplyRulesRequest{
    RulesetId : "quote_create_rules",
    Context : &chargebee.BusinessRuleApplyRulesContext{
        Type : "CPQ",
        Customer : map[string]interface{}{
"language" : "en",
},
        Quote : map[string]interface{}{
"shipping_address_country" : "IN",
},
    },
}
  res, err := client.BusinessRule.ApplyRules(req)
      if err != nil {
        fmt.Println(err)
    } else {
        ApplyRule := res.ApplyRule
    }
}
```

#### Java

```java
import com.chargebee.*;
import com.chargebee.ListResult;
import com.chargebee.models.*;
import com.chargebee.models.enums.*;
import java.io.IOException;
import com.chargebee.org.json.JSONArray;
import com.chargebee.org.json.JSONObject;

public class Sample {

    public static void main(String args[]) throws IOException, Exception {
        Environment.configure("{site}", "{site_api_key}");
        Result result = BusinessRule.applyRules()
            .rulesetId("quote_create_rules")
            .context(new JSONObject("{\"type\":\"CPQ\",\"customer\":{\"language\":\"en\"},\"quote\":{\"shipping_address_country\":\"IN\"}}"))
            .request();

        ApplyRule applyRule = result.applyRule();
    }
}
```

#### Java

```java
import com.chargebee.v4.client.ChargebeeClient;
import com.chargebee.v4.models.applyRule.ApplyRule;
import com.chargebee.v4.models.businessRule.params.BusinessRuleApplyRulesParams;
import com.chargebee.v4.models.businessRule.responses.BusinessRuleApplyRulesResponse;
import java.util.List;
import java.util.Map;

public class BusinessRuleApplyRules {

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

        BusinessRuleApplyRulesParams params = BusinessRuleApplyRulesParams.builder()
            .rulesetId("quote_create_rules")
            .context(Map.of("type", "CPQ", "customer", Map.of("language", "en"), "quote", Map.of("shipping_address_country", "IN")))
            .build();

        BusinessRuleApplyRulesResponse response = client.businessRules().applyRules(params);

        ApplyRule applyRule = response.getApplyRule();
    }
}
```

#### Node.js

```node
import Chargebee from "chargebee";

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

try {
    const result = await chargebee.businessRule.applyRules({
        ruleset_id: "quote_create_rules",
        context: {
            type: "CPQ",
            customer: {
                language: "en"
            },
            quote: {
                shipping_address_country: "IN"
            }
        }
    });

    console.log(result);
    const applyRule = result.apply_rule;
} 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->businessRule()->applyRules([
    "ruleset_id" => "quote_create_rules",
    "context" => '{"type":"CPQ","customer":{"language":"en"},"quote":{"shipping_address_country":"IN"}}'
]);
$applyRule = $result->apply_rule;
```

#### Python

```python
from chargebee import Chargebee

cb_client = Chargebee(api_key="{site_api_key}", site="{site}")
response = cb_client.BusinessRule.apply_rules(
    cb_client.BusinessRule.ApplyRulesParams(
        ruleset_id="quote_create_rules",
        context={
            "type": "CPQ",
            "customer": {
    "language": "en"
},
            "quote": {
    "shipping_address_country": "IN"
}
        }
    )
)
apply_rule = response.apply_rule
```

#### Ruby

```ruby
require 'chargebee'

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

result = ChargeBee::BusinessRule.apply_rules({
  :ruleset_id => "quote_create_rules",
  :context => {:type => "CPQ",:customer => {:language => "en"},:quote => {:shipping_address_country => "IN"}}
})

apply_rule = result.apply_rule
```

## Sample Response

```json
{
  "apply_rule": {
    "context": {
      "type": "CPQ",
      "customer": {
        "language": "en"
      },
      "quote": {
        "shipping_address_country": "IN"
      }
    },
    "rules": [
      {
        "id": "custom-uuid-1",
        "version": 1,
        "name": "Apply 12 percentage discount at invoice level",
        "description": "Apply 12 percentage discount at invoice level",
        "evaluation_result": true,
        "actions": [
          {
            "input": {
              "apply_on": "invoice_amount",
              "duration_type": "one_time",
              "discount": 12,
              "discount_type": "percentage"
            },
            "action_template_id": "action-apply-discount",
            "type": "APPLY_DISCOUNT"
          },
          {..}
        ],
        "object": "applied_rule"
      },
      {..}
    ],
    "object": "apply_rule"
  }
}
```

## URL Format

**POST** https://[site].chargebee.com/api/v2/business_rules/apply_rules

## Input Parameters

- `evaluate` (optional, boolean)
  When set to `true`, skips rule action execution and only performs rule evaluation. Useful for testing rule conditions without executing associated actions.

- `rule_id` (optional, string)
  The [business rule](/docs/api/business_rules) to evaluate. Its latest released version is evaluated, and one entry is returned for it in `apply_rule.rules[]`.

- `ruleset_id` (optional, string)
  The [business ruleset](/docs/api/business_rulesets) to evaluate. Every rule it contains is evaluated in its priority order, following the strategy configured in the ruleset `execute_mode`, which also decides whether evaluation stops early and which of the results are returned.

- `skip_failed_rules` (optional, boolean)
  Skip failed rules and continue processing the rest of the ruleset. A rule that could not be evaluated is returned with `error_message` set. When `false`, the request fails as soon as a rule cannot be evaluated.
  
  This applies only to the rules evaluated through `ruleset_id`. A rule evaluated through `rule_id` and an expression evaluated through `structured_expression` fail the request regardless of this value.

- `structured_expression` (optional, jsonobject)
  An expression to evaluate without storing it as a rule. Use it to try an expression while you are building it. See [Expressions](/docs/api/business_rules#expressions) for the node types and the operators each field type supports.
  
  **Impacts**
  
  -   The entry returned for the expression in `apply_rule.rules[]` carries only `evaluation_result`. No actions run, because actions belong to a stored rule rather than to an ad-hoc expression.
  -   An `operator` applied to a field of another type cannot be evaluated and fails the request. `skip_failed_rules` does not apply to this parameter.
  
  **Example →** `structured_expression = {"type":"GROUP","operation":"AND","children":[{"type":"CONDITION","field":"customer.language","operator":"CONTAINS","value":"en"},{"type":"CONDITION","field":"quote.shipping_address_country","operator":"ANY_OF","values":["IN","US"]}]}`

- `context` (optional, jsonobject)
  The data that the rule expressions are evaluated against, passed as a JSON object. The `field` of each condition is resolved against this object. See [Context](/docs/api/business_rules#context) for the schema and the fields a condition can reference.
  
  **Constraints**
  
  -   Must carry a `type`, which selects the schema that the rest of the object is read as. `CPQ` is the only type available.
  
  **Impacts**
  
  -   A key that falls outside the schema is dropped as the context is read.
  -   A condition that references a field the context does not carry, including a key dropped for falling outside the schema, evaluates to `false`. The rule holding it does not match, and no `error_message` is returned for it.
  
  **Example →** `context = {"type":"CPQ","customer":{"language":"en"},"quote":{"shipping_address_country":"IN"}}`

## Returns

- `apply_rule` (Apply rule object)
  The outcome of the evaluation. It echoes back the `context` you passed and carries one entry in `rules[]` for each rule that was evaluated.
  
  Each entry in `rules[]` holds the following.
  
  -   `id` and `version`: the rule that was evaluated, and the released version that was used.
  -   `name` and `description`: carried over from the rule.
  -   `evaluation_result`: `true` when the rule expression matched the context, and `false` when it did not.
  -   `actions`: the actions produced when `evaluation_result` is `true`, each carrying its `type`, the `action_template_id` of the template it was built from, and that template's parameters in `input`. It is absent for a rule that did not match. See [Actions](/docs/api/business_rules#actions) for what each template returns.
  -   `error_message`: the reason a rule could not be evaluated, such as an operator used on a field of another type. It is returned when `skip_failed_rules` is `true`.
  
  When you pass `ruleset_id`, which of the evaluated rules appear in `rules[]` depends on the `execute_mode` of the [ruleset](/docs/api/business_rulesets). See [Evaluation results](/docs/api/business_rules#evaluation-results) for an annotated response, and [Context](/docs/api/business_rules#context) for the fields the echoed context can carry.
