Rule Evaluation (Reference)

This document contains additional information about Rule Evaluation, such as how to create rule evaluation requests using alternative values, create rule evaluation requests without suitable alternatives, and create rule evaluation requests with iterative rule results. It also contains a list of possible error scenarios.

 

Rule Evaluation With Alternative Values

This section describes how to create rule evaluation requests using alternative values.

As an example, consider that you want to evaluate Financial Services / Custody and Payment Services, and you are interested in the prospect and existingClient client statuses.

You need to encode the clientStatus attribute with a multi-value (a pipe separated list of alternative values):


  {"name":"clientStatus", "value":"*(prospect|existingClient)"},

If you want to produce results for all the alternative values, you must wrap the value list with an asterisk and parenthesis: *(…).
If you miss the asterisk or the parenthesis, you get only the result for the first alternative that arrives at an action node.
For example: *(prospect|existingClient).

 

Complete request

The code below shows how the complete request looks like.


    POST /api/v3/rules/eval HTTP/1.1
    Content-Type: application/json
    Apikey: ...
    Authorization: Bearer ...
    Host: rule-engine.apiax.io
    Content-Length: 542
    
    {
      "products": [
        {
          "productId": "Custody and Payment Services",
          "familyId": "Financial Services"
        }
      ],
      "regimes": [
        "CAN"
      ],
      "versionFilter": "latest",
      "attributes": [
        {"name":"marketingOrigination", "value":"proActiveMarketing"},
        {"name":"serviceCategory", "value":"creditCard"},
        {"name":"clientStatus", "value":"*(prospect|existingClient)"},
        {"name":"presentProspectClientEventCountry", "value":"CAN"},
        {"name":"presentFIEmployeeCountry", "value":"CAN"},
        {"name":"financialInstituteLicense", "value":"none"}
      ]
    }

 

The response contains a result structure for each alternative path. Paths pertain to a result. You can be found them at $.results[0].results[*].path.


    // Result for clientStatus == prospect will be at
    $.results[0].results[?(@.path.clientStatus.value=="prospect")] 
    
    // Result for clientStatus == existingClient will be at
    $.results[0].results[?(@.path.clientStatus.value=="existingClient")]

 

Complete response

The code below shows the complete response for the current request.


    {
      "priorityCountry": "CAN",
      "results": [
        {
          "resultId": "56df8724-f40f-4ea8-8b62-4a2238c80bef",
          "country": "CAN",
          "generatedFor": "CAN",
          "results": [
            {
              "actions": [
                {
                  "id": "cd9ac9c9-7a46-45c9-827e-aa2bc0050655",
                  "title": "[[activitiesCustody]]",
                  "message": ".",
                  "type": "CustomAction",
                  "specificInfo": {
                    "properties": [
                      {
                        "title": "provideServiceCustody",
                        "description": "[[provideServiceCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": ""
                      },
                      {
                        "title": "negotiateTermsCustody",
                        "description": "[[negotiateTermsCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkNegotiateConditionsProspects:definition]]"
                      },
                      {
                        "title": "explainExecutionCustody",
                        "description": "[[explainExecutionCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkSecuritiesDealing:definition]]"
                      },
                      {
                        "title": "receiveExecutionCustody",
                        "description": "[[receiveExecutionCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkSecuritiesDealing:definition]]"
                      }
                    ]
                  },
                  "originRuleSetId": [
                    "5ff48d38a36d165b16283705"
                  ]
                }
              ],
              "path": {
                "presentProspectClientEventCountry": {
                  "value": "CAN",
                  "operation": "=="
                },
                "financialInstituteLicense": {
                  "value": "none",
                  "operation": "=="
                },
                "clientStatus": {
                  "value": "prospect",
                  "operation": "=="
                },
                "presentFIEmployeeCountry": {
                  "value": "CAN",
                  "operation": "=="
                },
                "serviceCategory": {
                  "value": "creditCard",
                  "operation": "=="
                },
                "marketingOrigination": {
                  "value": "proActiveMarketing",
                  "operation": "=="
                }
              },
              "nodeId": "71"
            },
            {
              "actions": [
                {
                  "id": "8d4359e3-bdd3-4138-939b-04d168c66e75",
                  "title": "[[activitiesCustody]]",
                  "message": ".",
                  "type": "CustomAction",
                  "specificInfo": {
                    "properties": [
                      {
                        "title": "provideServiceCustody",
                        "description": "[[provideServiceCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": ""
                      },
                      {
                        "title": "negotiateTermsCustody",
                        "description": "[[negotiateTermsCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": ""
                      },
                      {
                        "title": "explainExecutionCustody",
                        "description": "[[explainExecutionCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkSecuritiesDealing:definition]]"
                      },
                      {
                        "title": "receiveExecutionCustody",
                        "description": "[[receiveExecutionCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkSecuritiesDealing:definition]]"
                      }
                    ]
                  },
                  "originRuleSetId": [
                    "5ff48d38a36d165b16283705"
                  ]
                }
              ],
              "path": {
                "presentProspectClientEventCountry": {
                  "value": "CAN",
                  "operation": "=="
                },
                "financialInstituteLicense": {
                  "value": "none",
                  "operation": "=="
                },
                "clientStatus": {
                  "value": "existingClient",
                  "operation": "=="
                },
                "presentFIEmployeeCountry": {
                  "value": "CAN",
                  "operation": "=="
                },
                "serviceCategory": {
                  "value": "creditCard",
                  "operation": "=="
                },
                "marketingOrigination": {
                  "value": "proActiveMarketing",
                  "operation": "=="
                }
              },
              "nodeId": "130"
            }
          ],
          "aggregationResult": false,
          "ruleSelectionLogicApplied": "[[selectedFromRequestRegimesList]]",
          "ruleSets": [
            {
              "id": "5ff48d38a36d165b16283705",
              "productFamilyId": "Financial Services",
              "productId": "Custody and Payment Services",
              "productFamily": "[[financialServicesRuleSetFamily]]",
              "product": "[[apiaxCustodyAndPaymentServices]]",
              "version": "22.2",
              "country": "CAN",
              "contentProviderId": "5acf2f957b13a61fa4304c96",
              "rulesetActivationState": "PROD",
              "countryOverviewId": "5ff3220b38f73116e3db4a33"
            }
          ]
        }
      ]
    }

 

Rule Evaluation Without Suitable Alternatives

This section describes how to create rule evaluation requests without suitable alternatives.

In some rules, fallback branches comprise a set of negated options.

You can verify this in many regulatory properties of type Country.

 

The screenshot below shows an example with the Present Client Country property with the Outside CAN and Inside CAN branches.

The inside case is defined as presentClientCountry == CAN (meaning that the present client Country equals Canada).

The outside case is the negation of the inside case: presentClientCountry != CAN (meaning that the current client Country does not equal Canada).

presentclientproperty with branches

In such cases, Apiax recommends using the following best practice:

  • Use the value __ (double underscore) to denote:

    • the outside Country or jurisdiction case (regulatory properties of type Country)

    • the case of none of the possible options (regulatory properties of type Text)
      __ means non-existing-country / jurisdiction.

  • For regulatory properties of type Text, use the value _other_. This value is a convention to follow when creating a rule and defining branch options.
    No rule must ever use the option _other_ in its definition.

For evaluating the case above, there are two alternatives:

  1. If you know the current client country, you can specify that value. For example, GBR which is != CAN. The attribute looks like this:

    {"name":"presentClientCountry","value":"GBR"}

  2. Alternatively, you can use __ to specify that it is not CAN even if you do not know which country it is. This also triggers the outside path since __ != CAN. The attribute looks like this:

    {"name":"presentClientCountry","value":"__"}

 

Rule Evaluation With Iterative Rule Results

This section describes how to create rule evaluation requests with iterative rule results.

When evaluating rules with an incomplete or invalid set of attributes, the rule evaluation does its best to find a path to an action node. If this is not possible, then it produces an iterative result.

 

Incomplete request

The code below shows an example of an incomplete request.


POST /api/v3/rules/eval HTTP/1.1
Content-Type: application/json
Apikey: YOUR API KEY
Authorization: Bearer ...
Host: rule-engine.apiax.io
Content-Length: 542

{
    "products": [
        {
            "productId": "Custody and Payment Services",
            "familyId": "Financial Services"
        }
    ],
    "regimes": [
        "CAN"
    ],
    "versionFilter": "latest",
    "attributes": [
        {"name":"presentProspectClientEventCountry", "value":"CAN"},
        {"name":"presentFIEmployeeCountry", "value":"CAN"},
        {"name":"financialInstituteLicense", "value":"none"}
    ]
}

 

By creating an incomplete request, you get an iterative result.

 

Iterative result

Following the current example, evaluating the request above yields the following result.


{
    "priorityCountry": "CAN",
    "results": [
        {
        "resultId": "3cc80cc8-9ad9-4912-8fa8-55d81122c318",
        "country": "CAN",
        "generatedFor": "CAN",
        "results": [
            {
            "iterativeResult": {
                "path": [
                "0",
                "1",
                "2",
                "3",
                "4",
                "21",
                "22",
                "23",
                "24",
                "25",
                "26",
                "27",
                "28",
                "29"
                ],
                "property": "clientStatus",
                "type": "Text",
                "options": [
                {
                    "value": "prospect",
                    "operation": "=="
                },
                {
                    "value": "existingClient",
                    "operation": "=="
                }
                ]
            }
            }
        ],
        "aggregationResult": false,
        "ruleSelectionLogicApplied": "[[selectedFromRequestRegimesList]]",
        "ruleSets": [ ... ]
        }
    ]
    }

 

The iterative result contains information at $.results[0].results[0].iterativeResult.property about which regulatory property needs further specification.

You also get the possible options (values) for that property at $.results[0].results[0].iterativeResult.options.

Using this information, you can create a new attribute that you can then use in a subsequent rule evaluation with the previously defined attributes. For example, if you are interested in the prospect case {"name":"clientStatus", "value":"prospect"}.

 


...
"attributes": [
        {"name":"clientStatus", "value":"prospect"},
        {"name":"presentProspectClientEventCountry", "value":"CAN"},
        {"name":"presentFIEmployeeCountry", "value":"CAN"},
        {"name":"financialInstituteLicense", "value":"none"}
    ]

 

This evaluation / iterative result cycle repeats until you arrive at a result that contains actions.

 


{
    "priorityCountry": "CAN",
    "results": [
        {
        "resultId": "438ef171-5f34-4d58-9671-8f4efcf0e9f2",
        "country": "CAN",
        "generatedFor": "CAN",
        "results": [
            {
            "actions": [
                {
                "id": "cd9ac9c9-7a46-45c9-827e-aa2bc0050655",
                "title": "[[activitiesCustody]]",
                "message": ".",
                "type": "CustomAction",
                "specificInfo": {
                    "properties": [
                    {
                        "title": "provideServiceCustody",
                        "description": "[[provideServiceCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": ""
                    },
                    {
                        "title": "negotiateTermsCustody",
                        "description": "[[negotiateTermsCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkNegotiateConditionsProspects:definition]]"
                    },
                    {
                        "title": "explainExecutionCustody",
                        "description": "[[explainExecutionCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkSecuritiesDealing:definition]]"
                    },
                    {
                        "title": "receiveExecutionCustody",
                        "description": "[[receiveExecutionCustody:definition]]",
                        "type": "Boolean",
                        "value": "no",
                        "reason": "[[remarkSecuritiesDealing:definition]]"
                    }
                    ]
                },
                "originRuleSetId": [
                    "5ff48d38a36d165b16283705"
                ]
                }
            ],
            "path": {
                "presentProspectClientEventCountry": {
                "value": "CAN",
                "operation": "=="
                },
                "financialInstituteLicense": {
                "value": "none",
                "operation": "=="
                },
                "clientStatus": {
                "value": "prospect",
                "operation": "=="
                },
                "presentFIEmployeeCountry": {
                "value": "CAN",
                "operation": "=="
                },
                "serviceCategory": {
                "value": "creditCard",
                "operation": "=="
                },
                "marketingOrigination": {
                "value": "proActiveMarketing",
                "operation": "=="
                }
            },
            "nodeId": "71"
            }
        ],
        "aggregationResult": false,
        "ruleSelectionLogicApplied": "[[selectedFromRequestRegimesList]]",
        "ruleSets": [
            {
            "id": "5ff48d38a36d165b16283705",
            "productFamilyId": "Financial Services",
            "productId": "Custody and Payment Services",
            "productFamily": "[[financialServicesRuleSetFamily]]",
            "product": "[[apiaxCustodyAndPaymentServices]]",
            "version": "22.2",
            "country": "CAN",
            "contentProviderId": "5acf2f957b13a61fa4304c96",
            "rulesetActivationState": "PROD",
          "countryOverviewId": "5ff3220b38f73116e3db4a33"
            }
        ]
        }
    ]
    }

 

Error Scenarios

This section describes the HTTP response error codes you might get when making a rule evaluation request.

The sections below describe each of the codes and how you can solve them.

 

HTTP Response Code 400

If your request returns with HTTP error code 400, and response body, this means the request is malformed. Make sure the request structure follows the swagger definition of the v3 rule-engine API.

 

HTTP Response Code 401

If your request returns without body, and you get the HTTP error code 401, you need to retrieve a valid access token from https://auth.apiax.io/auth/realms/apiax/protocol/openid-connect/token and use it as an Authentication Bearer token

 

HTTP Response Code 403

If your request returns with HTTP error code 403, it means you don't have the permissions required to access the Rule Engine, or you are using an APIKey that does not belong to your company.

 

HTTP Response Code 404

If your request returns with HTTP error code 404, that means one of the following options:

  • your request does not contain at least one product configured on your ApiKey

  • your ApiKey does not have the jurisdictions of your request or the GLOBAL jurisdiction.

If the response you get returns a Not Found message in the JSON structure, for example,
{"timestamp":1630591806028,"status":404,"error":"Not Found","path":"/XX/api/v3/rules/inspect"} this means one of the following:

  • the URL used for the request is malformed.
    Change the URL for pointing to the correct location: /api/v3/rules/inspect or /api/v3/rules/eval

  • You have a typo on a product name. Check if you wrote it correctly.

If none of the presented options applies, contact Apiax support.

 

HTTP Response Code 502

If the service does not respond or you get a "Bad Gateway” message in the response body, this means the service is down. To get more information, contact Apiax support.

 

HTTP Response Code 503

If your request returns with a JSON structure in the response body, and you get the HTTP error code 503, this means an unknown error occurred while evaluating the request.

 

Further readings

Was this article helpful?

Comments

0 comments

Article is closed for comments.

Still have questions?

Please submit a request and we will get back to you shortly.

Submit a ticket