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 statements that make up the language:
- Statements
- Decision functions
- Action functions
- Observation functions
- Model functions
- Device attribute functions
- Referencing attributes and variables
- Logical operators
- List functions
- Comparison operators
- BIN Lookup functions
- Geo functions
- String functions
- Math functions
- Type casting operators
- DateTime functions
- Aggregation functions
The guide also covers other articles. Here are some examples:
Statements
Statement syntax | Description | Example |
---|---|---|
LET <VariableName> = <Expression> | A LET statement is used to define a new variable. The scope of the variable is the rule or velocity set it's defined in. Variable names should be prefixed with a dollar sign ($). For more information, see Defining your own variables. Any number of LET statements can be used in the Condition section and the clauses of all rule types and velocity sets. |
LET $fullName = @"user.firstName" + @"user.lastName" |
OBSERVE OBSERVE <ObservationFunction>(<KeyValuePairs>) |
An OBSERVE statement doesn't terminate rule execution with a decision. It merely logs key-value pairs to either the API response or trace logs. Subsequent rules and rule clauses continues to run until a RETURN statement is reached. An OBSERVE statement must be followed by one or more observation functions. If a WHEN clause is present and is evaluated to False, the OBSERVE statement isn't logged. A maximum of one can be used for each clause in the following rules:
|
OBSERVE Output(reason="high score") OBSERVE TRACE(ip=@"device.ipAddress") WHEN @"riskscore" > 400 |
RETURN <DecisionFunction> [ ,<ObservationFunction>(<KeyValuePairs>) ] [ WHEN <BooleanExpression> ] |
A RETURN statement terminates rule execution with a decision. 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() Finally, the statement can include a WHEN clause to specify the condition under which it should do any of the preceding. A maximum of one can be used per clause in the following rules:
|
RETURN Review() RETURN Reject(), Trace(ip=@"device.ipAddress") WHEN @"riskscore" > 400 |
ROUTETO QUEUE <QueueName> [ WHEN <BooleanExpression> ] |
The ROUTETO command is used in routing rules to direct matching assessments to case management queues. The optional WHEN clause can be used to describe the conditions under which the command should perform the routing. A maximum of one can be used per clause in routing rules. |
ROUTETO Queue("High Value Queue") WHEN @"purchase.request.totalAmount" > 500 |
SELECT <AggregationFunction> AS <VelocityName> FROM <AssesmentType> GROUPBY <GroupExpression> [ WHEN <BooleanExpression> ] |
A SELECT statement is used in velocity sets to define a velocity. It must specify an aggregation function. The required AS clause is used to create an alias for your velocity. This alias can then be referenced from rules. The required FROM clause is used to specify the assessment type to observe a velocity on. Valid values are Purchase, AccountLogin, AccountCreation, Chargeback, BankEvent, and CustomAssessment. The required GROUPBY clause 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 requested in the SELECT statement. For example, to calculate an aggregation for each user, use GROUPBY @"user.userId". The optional WHEN clause specifies a Boolean expression that determines whether the assessment that's being processed should be included in the velocity that's being defined. A maximum of one can be used per clause in velocity sets. |
SELECT Count() AS _Purchase_Rejections_Per_Email SELECT DistinctCount(@"purchaseId") |
WHEN <BooleanExpression> | The WHEN statement is like the WHEN clauses on the other statements, but it stands alone in the Condition section of rules and velocity sets. It specifies a Boolean condition that determines whether the whole rule, velocity set, or routing rule should run. A maximum of one can be used in the Condition section of all rule types and velocity sets. |
WHEN @"riskscore" > 400 |
DO <Action function> | A DO statement is used to perform some action at the end of rule execution. This statement can only be used in Post-decision actions, and followed by an Action function | DO SetResponse(name = @”firstname” + @”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 another 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 another 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 another 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 another supporting message. Overloads:
|
RETURN Challenge ("SMS") RETURN Challenge ("SMS", "suspected bot") RETURN Challenge ("SMS", suspected bot", "do not escalate") |
Action functions
Action functions are used to specify the action to be taken in a Post-decision action rule
Action type | Description | Example |
---|---|---|
SetResponse(String sectionName, k=v) | This function can be used to pass key-value pairs to the “CustomProperties” section of API response. You can specify a subsection sectionName for the key values pair to go into. Overloads: • SetResponse(k=v) |
SetResponse(“Scores”, bot = Model.Bot(@deviceContextId), risk=Model.Risk()) SetResponse(test=”123”) |
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") |
Model functions
Model functions run the various fraud models and are useful when your assessment does not automatically run one or more fraud models. When model functions run, information about the model running during rule evaluation is output in the fraud assessment API call. Then, the rule gets access to the model result, including score, reasons, and more, that can be used for further rule processing and decision making.
Model type | Description | Example |
---|---|---|
Risk | Assesses the likelihood of a session being risky. | Model.Risk() |
Bot | Assesses the likelihood of a session being bot-initiated. Pass in a device context ID that was sent to Fraud Protection’s device fingerprinting solution. | Model.Bot(@deviceContextId) |
Device attribute functions
Operator | Description | Example |
---|---|---|
Device.GetAttributes(String sessionId) | Returns selected device attributes from device fingerprinting. The selected device attributes are curated by Fraud Protection and are a set of attributes commonly used in rules. | Device.GetAttributes(@"deviceContext.deviceContextId).attribute_name |
Device.GetFullAttributes(String sessionId) | Returns a full set of device attributes from device fingerprinting. Use this function only when needed to access the full set of device attributes. To view the full set of device attributes, see Set up device fingerprinting. | Device.GetFullAttributes(@"deviceFingerprinting.id").attribute_name |
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 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") |
Response.Decision() | This function references the decision for the current assessment being evaluated. | Response.Decision() == “Approve” |
Request.CorrelationId() | This function references the unique Correlation ID of the event being evaluated. You can use this function to access the Correlation ID of an event in the rules experience and pass it to an external call as a parameter or a header. | External.MyExternalCall(Request.CorrelationId()) |
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 is always 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 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 |
BIN Lookup functions
BIN Lookup functions provide payment card account information (for example, card network, card type, card country code) based on bank identification number (BIN). Data for BIN Lookup is sourced from leading third-party BIN data providers and then curated by Microsoft Fraud Protection.
Operator | Description | Example |
---|---|---|
BIN.Lookup(String BIN).cardNetwork | This function looks up BIN and returns card's network (for example, Visa, Mastercard). |
BIN.Lookup(@"card.bin").cardNetwork |
BIN.Lookup(String BIN).cardType | This operator looks up BIN and returns card type (for example, Debit, Credit). |
BIN.Lookup(@"card.bin").cardType |
BIN.Lookup(String BIN).issuer | This operator looks up BIN and returns issuing organization. |
BIN.Lookup(@"card.bin").issuer |
BIN.Lookup(String BIN).countryCode | This operator looks up BIN and returns ISO two-letter country code of the card. |
BIN.Lookup(@"card.bin").countryCode |
BIN.Lookup(String BIN).error | This operator looks up BIN and returns an error message if the BIN could not be found. |
BIN.Lookup(@"card.bin").error |
Geo functions
Geo functions provide resolution by converting an IP address to a geographical address. Geo functions can be invoked in rules only by using IPs that are part of transaction payload or collected by Fraud Protection by using Device Fingerprinting. Geo functions can't be invoked for arbitrary IP values.
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. |
Geo.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 |
---|---|---|
Contains(String substring) | This operator checks whether a string contains another string. Contains(String substring) |
@"productList`.productName".Contains("Xbox") |
ContainsOnly(CharSet) | This operator checks whether a string contains only the charsets provided. ContainsOnly(Charset1 Charset2 ...etc.) |
@"zipcode".ContainsOnly(CharSet.Numeric) |
ContainsAll(CharSet) | This operator checks whether a string contains all the charsets provided. ContainsAll(Charset1 Charset2 ...etc.) |
@ “zipcode”.ContainsAll(CharSet.Numeric|CharSet.Hypen) |
ContainsAny(CharSet) | This operator checks whether a string contains any of the charsets provided. ContainsAll(Charset1 Charset2 ...etc.) |
@”zipcode”.ContainsAny(CharSet.Numeric|CharSet.Hypen) |
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") |
IsNumeric() | This operator checks whether a string is a numeric value. (String).IsNumeric() |
@"user.email".IsNumeric() |
Length | This operator returns the number of characters in the string. |
@"user.username".Length |
Convert.ToDateTime(@"user.creationDate").ToString("yyyy-MM-dd HH:mm:ss") | This operator converts the string to datetime and converts datetime to a string using the given format. |
Convert.ToDateTime(@"user.creationDate").ToString("yyyy-MM-dd") |
Using CharSet in ContainsOnly, ContainsAll, and ContainsAny
The following character types can be used in ContainsOnly, ContainsAll, and ContainsAny.
Character Type | Description |
---|---|
Alphabetic | a-z, A-Z |
Apostrophe | ' |
Asperand | @ |
Backslash | \ |
Comma | , |
Hypen | - |
Numeric | 0-9 |
Period | . |
Slash | / |
Underscore | _ |
WhiteSpace | Single space |
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") |
RandomInt(Integer min, Integer max) | This operator returns a random integer in the range provided, including the minimum value and excluding the maximum value. | RandomInt(0, 100) |
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 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 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 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. Prefix all variables 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 is 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 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, external assessments and velocities
- To reference an external call, type External, followed by the external call that you want to reference. For more information, see Use an external call in rules.
- To reference an external assessment, type Assessments, followed by the external assessment that you want to reference. For more information, see Use an external assessment in rules.
- To reference a velocity, type Velocity, followed by the 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.
JSON Arrays and Objects
FQL has support for the construction of complex structured objects as local variables, which may be passed through to the external call or external assessment in JSON form. As with all other locals in FQL, arrays and objects are immutable once created.
JSON arrays
Arrays are created by enclosing expressions in a pair of brackets:
LET $arr1 = [ "hello", "world" ]
LET $arr2 = [
"this is also an array",
78.4,
$arr1,
@"user.email",
External.MyExtcall()
]
JSON objects
Objects are created with braces:
LET $obj1 = { isObject: true }
LET $obj2 = {
numberField: 7,
fieldIs: "string",
internalObj: $obj1,
inline: {
innerInnerField: "hello"
}
}
Feedback
Submit and view feedback for