Language reference guide
Microsoft Dynamics 365 has its own rich and expressive language to help you define and express your fraud strategy. This language has many similarities to C# and SQL, and is designed to give you the flexibility that you need to address fraud for your unique business scenarios.
You can use this language today to define rules and velocities. For more information, see Manage rules and Perform velocity checks.
This language reference guide includes the complete list of operators, functions, and keywords that make up the language:
- Keywords
- Decision functions
- Observation functions
- Referencing attributes and variables
- Logical operators
- List functions
- Comparison operators
- Geo functions
- String functions
- Math functions
- Type casting operators
- DateTime functions
- Aggregation functions
The guide also covers additional articles. Here are some examples:
Keywords
| Keyword | Description | Example |
|---|---|---|
| RETURN | A RETURN statement terminates rule execution. The statement must specify a valid decision function: Approve(), Reject(), Challenge(), or Review(). The statement can also specify one or more observation functions: Output() or Trace() |
RETURN Reject() RETURN Reject(), Output(key=@"user.email") RETURN Reject(), Trace(ip=@"device.ipAddress") |
| OBSERVE | An OBSERVE statement does not terminate rule execution. When an OBSERVE clause is hit, it will be logged in the API response, however, clauses will continue to evaluate until a RETURN statement is reached. An OBSERVE statement must be followed by an observation function. |
OBSERVE Output() OBSERVE Output(reason=”high score”) |
| WHEN | A WHEN statement specifies a Boolean condition. The rest of the block is then run only if the condition is evaluated to true. | WHEN @"riskscore" > 400 |
| SELECT | A SELECT statement is used in a velocity to specify an aggregation function. | SELECT Count() AS velocityName |
| AS | An AS statement is used to create an alias for your velocity. This alias can then be referenced from rules. | SELECT Count() AS velocityName |
| FROM | A FROM statement is used to specify an assessment to observe a velocity on. | FROM Purchase |
| GROUPBY | A GROUPBY statement specifies a property or an expression. All events that are evaluated to the same value in the GROUPBY statement are combined to calculate the aggregation that is requested in the SELECT statement. For example, to calculate an aggregation for each user, use GROUPBY @"user.userId". |
GROUPBY @"user.userId" |
| LET | A LET statement is used to define a new variable. The scope of the variable is the rule or velocity set that it's defined in. Variable names should be prefixed with a dollar sign ($). For more information, see Defining your own variables. |
LET $fullName = @"user.firstName" + @"user.lastName" |
Decision functions
Decision functions are used in rules to specify a decision.
| Decision type | Description | Example |
|---|---|---|
| Approve() | This type specifies a decision of Approve. It can include a reason for the approval and an additional supporting message. Overloads:
|
RETURN Approve() RETURN Approve("on safe list") RETURN Approve ("on safe list", "do not escalate") |
| Reject() | This type specifies a decision of Reject. It can include a reason for the rejection and an additional supporting message. Overloads:
|
RETURN Reject() RETURN Reject("embargo country") RETURN Reject("embargo country", "do not escalate") |
| Review() | This type specifies a decision of Review. It can include a reason for the review and an additional supporting message. Overloads:
|
RETURN Review() RETURN Review("user on watch list") RETURN Review("user on watch list", "do not escalate") |
| Challenge(String challengeType) | This type specifies a decision of Challenge and a challenge type. It can also include a reason for the challenge and an additional supporting message. Overloads:
|
RETURN Challenge ("SMS") RETURN Challenge ("SMS", "suspected bot") RETURN Challenge ("SMS", suspected bot", "do not escalate") |
Observation functions
Observation functions can be used to take data from the current context and write it somewhere else.
| Return type | Description | Example |
|---|---|---|
| Output(k=v) | This function can be used to pass key-value pairs into the API response. | Output(key="test", email=@"user.email", countryRegion=Geo.CountryRegion(@"device.ipAddress")) |
| Trace(k=v) | This function can be used to trigger a Trace event and send key-value pairs to the FraudProtection.Trace.Rule Event Tracing namespace. | Trace(key="Manual Review", ip=@"device.ipAddress") |
Referencing attributes and variables
You can use the at sign (@) operator to reference an attribute from the current event.
| Variable | Description | Example |
|---|---|---|
| @ | An at sign (@) is used to reference an attribute from the incoming event. The attribute might be sent as part of the request payload, or it might be generated by Microsoft Dynamics 365 Fraud Protection. After the at sign (@), specify the full path of the attribute that you want to reference. Enclose the path in quotation marks (for example, @"address.city"). If the referenced attribute isn't part of the event payload, the default value for that type is returned: 0.0 for doubles, an empty string for strings, and so on. The type of the attribute is inferred from the context that it's used in. If not enough context is provided, the String type is used by default. For information about type inference, see Type inference of attributes. |
@"address.city" |
| $ | A dollar sign ($) is used to reference a variable that has been defined in a LET statement. For more information, see Defining your own variables. | $fullName |
| @"botScore" | For every Account Creation or Account Login event, Fraud Protection's AI models generate a bot score between 0 and 999. A higher score indicates a higher probability that the event was initiated by a bot. You can use @botScore to reference this score in post-bot-scoring clauses and post-risk-scoring clauses. |
@"botScore" |
| @"riskScore" | For every Purchase or Account Protection event, Fraud Protection's AI models generate a risk score between 0 and 999. A higher score indicates a higher risk. You can use @riskScore to reference this score in post-risk-scoring clauses. |
@"riskScore" |
| @a\[x] | This variable is used to index array variables. If the request payload for an assessment contains an array of items, you can access individual elements of the array by using the following syntax: @"productList[0]". To access an attribute of that element, use the following syntax: @"productList[0].productId" |
@"productList[0].productId" @"paymentInstrumentList[3].type" |
| Exists | This operator checks whether a variable exists in the event payload. Exists(String variable) |
Exists(@"user.email") |
Logical operators
| Operator | Description | Example |
|---|---|---|
| and (&&) | Logical And | @"riskScore" > 500 && @"riskScore" < 800 @"riskScore" > 500 and @"riskScore" < 800 |
| or (||) | Logical Or | @"email.isEmailUsername" == false || @"email.isEmailValidated" == false @"email.isEmailUsername" == false or @"email.isEmailValidated" == false |
| not | Logical negation | @"email.isEmailUsername" not(!) @"email.isEmailUsername" |
List functions
Fraud Protection lets you upload custom lists and reference them in the language.
For information about how to upload these lists, see Manage lists. For more information about how to use lists in rules, see the Using lists in rules section later in this article.
| Operator | Description | Example |
|---|---|---|
| ContainsKey( String listName, String columnName, String key) |
This operator checks whether a key is contained in the specified column in a Fraud Protection list. | ContainsKey("Email Support List", "Emails", @"user.email") This example checks whether the "Emails" column in the "Email Support List" list contains the @"user.email" variable. |
| Lookup( String listName, String keyColName, String valueColName) |
This operator looks up the value of a key in a Fraud Protection list. Both the name of the column that contains the key and the name of the column that contains the value must be specified. The value will always be returned as a string. If the key isn't found, and if the defaultValue parameter isn't specified, "Unknown" is returned. |
Lookup("Email Support List", "Emails", @"user.email", "Status",0) This example looks for the @"user.email" variable in the "Emails" column of the "Email Support List" list and returns the corresponding value in the "Status" column. If the key isn't found in the list, Fraud Protection returns 0. |
| LookupClosest( String listName, String keyColumnName, String key, String valueColumnName, String defaultValue) |
This operator looks up the value of a key in a Fraud Protection list. If the key isn't found, the value of the key that is alphabetically closest to the key that you're looking for is returned. Overloads:
|
LookupClosest("IP Addresses", "IP", @"device.ipAddress", "City") == "Seattle" This example looks for the @ipAddress variable in the "IP" column of the "IP Addresses" list and returns the corresponding value in the "City" column. If @ipAddress isn't found in the list, the expression returns the value of the next closest IP address in the list. |
| In | This operator checks whether a key is contained in a comma-separated list of values. In(String key, String list) |
In(@"user.countryRegion", "US, MX, CA") |
Comparison operators
Fraud Protection supports all standard C# comparison and equality operations. This table includes some examples of operators that you might find useful. If you apply these operators to strings, lexicographic comparisons will occur.
| Operator | Description | Example |
|---|---|---|
| == | This operator checks for equality. | @"user.countryRegion" == @"shippingAddress.countryRegion" |
| != | This operator checks for inequality. | @"user.countryRegion" != @"shippingAddress.countryRegion" |
| > | This operator checks whether the first value is greater than the second value. | @"riskScore" > 500 |
| < | This operator checks whether the first value is less than the second value. | @"riskScore" < 500 |
| >= | This operator checks whether the first value is greater than or equal to the second value. | @"riskScore" >= 500 |
| <= | This operator checks whether the first value is less than or equal to the second value. | @"riskScore" <= 500 |
Geo functions
These functions convert an IP address to a geographical address.
| Operator | Description | Example |
|---|---|---|
| Geo.RegionCode(String ip) | This operator converts an IPv4 address to its US region code (that is, the abbreviation for the name of the US state or territory). For example, for an IP address in Washington state, "WA" is returned. |
Geo.RegionCode(@"device.ipAddress") |
| Geo.Region(String ip) | This operator converts an IPv4 address to its US region (that is, the name of the US state or territory). For example, for an IP address in Washington state, "Washington" is returned. |
Geo.Region(@"device.ipAddress") |
| Geo.CountryCode(String ip) | This operator converts an IPv4 address to its country/region code. For example, for an IP address in Australia, "AU" is returned. |
Geo.CountryCode(@"device.ipAddress") |
| Geo.CountryRegion(String ip) | This operator converts an IP address to a region name. For example, for an IP address in Australia, "Australia" is returned. |
Geo.CountryRegion(@"device.ipAddress") |
| Geo.City(String ip) | This operator converts an IPv4 address to a city name. For example, for an IP address in New York City, "New York City" is returned. |
WGeo.City(@"device.ipAddress") |
| Geo.MarketCode(String ip) | This operator converts an IPv4 address to the market code of the IP address. For example, for an IP address from Canada, "NA" (North America) is returned. |
Geo.MarketCode(@"device.ipAddress") |
String functions
Fraud Protection supports the standard C# string class. This table includes some examples of functions and operators that you might find useful.
| Operator | Description | Example |
|---|---|---|
| StartsWith(String prefix) | This operator checks whether a string begins with a specified prefix. StartsWith(String prefix) |
@"user.phoneNumber".StartsWith("1-") |
| EndsWith(String suffix) | This operator checks whether a string ends with a specified suffix. EndsWith(String suffix) |
@"user.email".EndsWith("@contoso.com") |
| Contains(String suffix) | This operator checks whether a string contains another string. Contains(String substring) |
@"productList.productName".Contains("Xbox") |
Math functions
Fraud Protection supports all standard C# math methods and arithmetic operators. This table includes some examples of methods that you might find useful.
| Operator | Description | Example |
|---|---|---|
| Math.Min(Double value1, Double value2) | This operator computes the minimum of two values. | Math.Min(@"riskScore",@"botScore") |
| Math.Max(Double value1, Double value2) | This operator computes the maximum of two values. | Math.Max(@"riskScore",@"botScore") |
DateTime operators
Fraud Protection supports the standard C# DateTime properties, methods, and operators. This table includes some examples of functions and properties that you might find useful.
| Operator | Description | Example |
|---|---|---|
| DaysSince(DateTime date) | This operator returns an integer that represents the number of days that have passed between the specified DateTime value and the current date (expressed as Coordinated Universal Time [UTC]). | DaysSince(@"user.CreationDate") |
| UtcNow | This operator gets a DateTime object that is set to the current date and time on the computer, expressed as UTC. | DateTime.UtcNow |
| Today | This operator gets an object that is set to the current date, where the time component is set to 00:00:00. | DateTime.Today |
| Year | This operator gets the year component of the date that is represented by this instance. | @"user.creationDate".Year |
| Date | This operator gets a new object that has the same date as this instance, but where the time value is set to 00:00:00 (midnight). | @"user.creationDate".Date |
Type casting operators
For information about type inferencing, see the Type inference of attributes section later in this article.
| Operator | Description | Example |
|---|---|---|
| ToDateTime() | This operator converts a string to a DateTime object. | @"user.creationDate".ToDateTime() |
| ToDouble() | This operator converts a string to a Double value. | @"productList.purchasePrice".ToDouble() |
| ToInt32() | This operator converts a string to an Int32 value. | @"riskScore".ToInt32() |
Aggregation functions
| Function | Description | Example |
|---|---|---|
| Count() | This function returns the number of times that an event has occurred. | SELECT Count() AS numPurchases |
| DistinctCount(String key) | This function returns the number of distinct values for the specified property. If the specified property is null or empty for an incoming event, the event won't contribute to the aggregation. | SELECT DistinctCount(@"device.ipAddress") AS distinctIPs |
| Sum(Double value) | This function returns the sum of values for a specified numeric property. | SELECT Sum(@"totalAmount") AS totalSpending |
Defining your own variables
You can use the LET keyword to define a variable. That variable can then be referenced in other places in the rule. All variables should be prefixed by a dollar sign ($).
For example, you declare the following variable.
LET $fullName = @"user.firstName" + @"user.lastName"
Variables that are declared in a LET statement can be used only within the scope of the rule or velocity set that the statement is defined in.
For example, to reference the variable from the previous example, you can write the following statement.
WHEN $fullName == "Kayla Goderich"
Note
After a variable has been defined, it can't be updated with a new value.
Using lists in rules
You can use the ContainsKey and Lookup operators to reference lists that you've uploaded to Fraud Protection. For more information about lists, see Manage lists.
ContainsKey
To check whether one of your lists contains a specific value, use the ContainsKey operator. Specify the list name, the column, and the key that you want to check for.
For example, you upload a single-column list of risky email addresses and name it Risky email list.
Kayla@contoso.com |
Jamie@bellowscollege.com |
Marie@atatum.com |
You can then use the following syntax to reject all transactions from the risky email addresses in this list.
RETURN Reject("risky email")
WHEN ContainsKey("Risky email list", "Email", @"user.email")
This clause checks whether the "Email" column in the "Risky email list" list contains the @email key. If it does, the transaction is rejected.
Lookup
For multi-column lists, you can use the Lookup operator to check the value of a column for a specific key.
For example, you create a list that has one column for email addresses and another column that indicates the status of those email addresses. You name this list Email List.
| Status | |
|---|---|
Kayla@contoso.com |
Risky |
Jamie@bellowscollege.com |
Risky |
Marie@atatum.com |
Risky |
Camille@fabrikam.com |
Safe |
Miguel@proseware.com |
Safe |
Tyler@contoso.com |
Safe |
You can then use the following syntax to reject all transactions from the email addresses in this list that have a status of Risky.
RETURN Reject("risky email")
WHEN Lookup("Email List", "Email", @"user.email", "Status") == "Risky"
This clause looks for the @"user.email" key in the "Email" column in the "Email List" list and checks whether the value in the "Status" column is Risky. If it is, the transaction is rejected.
If the @"user.email" key isn't found in the list, Fraud Protection returns "Unknown."
You can also specify your own default value as the fifth parameter. For more information, see the Logical operators section earlier in this article.
The Lookup operator always returns a String value. To convert this value to an Int, Double, or DateTime value, use a type casting operator.
Using external calls and velocities
You can reference external calls and velocities by using the corresponding keyword.
- To reference an external call in the language, type External, followed by the external call that you want to reference. For more information, see Use an external call in rules.
- To reference a velocity in the language, type Velocity, followed by the individual velocity that you want to reference. For more information, see Use a velocity in rules.
Type inference of attributes
Variable types are inferred from the context that they are used in. Here are some examples:
- In the expression WHEN @isEmailValidated, the variable is interpreted as a Boolean value.
- In the expression @"riskScore" > 500, the variable is interpreted as a Double value.
- In the expression @"user.creationDate".Year < DateTime.UtcNow.Year, the variable is interpreted as a DateTime value.
If there isn't enough context to infer the type of a variable, it's considered a String value. For example, in the expression @"riskScore" < @"botScore", both variables are interpreted as strings.
To specify the type of a non-string variable, use a type casting operator.
Feedback
Submit and view feedback for