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).
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.
- the outside Country or jurisdiction case (regulatory properties of type
- 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:
- 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"}
- 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.
Comments
0 comments
Article is closed for comments.