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:

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>)
[ WHEN <BooleanExpression>

]

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:

  • Purchase rules
  • Custom Assessment rules
  • Account Protection 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:

    • Purchase rules
    • Custom Assessment rules
    • Account Protection rules

      RETURN Review()
      WHEN IsWatch("Device Support List", @"deviceAttributes.deviceId") ||
      IsWatch("Payment Support List", @"paymentInstrumentList.merchantPaymentInstrumentId")

      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
      FROM Purchase
      WHEN @"ruleEvaluation.decision" == "Reject"
      GROUPBY @"user.email"

      SELECT DistinctCount(@"purchaseId")
      AS _BankDeclines_Per_Device
      FROM BankEvent
      WHEN @"status" == "DECLINED"
      GROUPBY @"purchase.deviceContext.externalDeviceId"

      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:

      • Approve(String reason)
      • Approve(String reason, String supportMessage)

      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:

      • Reject(String reason)
      • Reject(String reason, String supportMessage)

      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:

      • Review(String reason)
      • Review(String reason, String supportMessage)

      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:

      • Challenge(String challengeType, String reason)
      • Challenge(String challengeType, String reason, String supportMessage)

      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)

      Gibberish detection functions

      These functions help prevent fraud by quickly and efficiently detecting whether key user-input fields (such as names and addresses) contain gibberish.

      Function Description Example
      GetPattern(String).maxConsonants Maximum number of contiguous consonants in a string that aren't separated by a vowel. For example, maxConsonants for the string "01gggyturah" is 5. GetPattern(@"user.email").maxConsonants
      GetPattern(String).gibberScore ML based score between 0 and 1; 0 means most likely to be gibberish and 1 means least likely to be gibberish. GetPattern(@"user.email").gibberScore

      Note

      Gibberish detection model is based on the frequency of two consecutive alphanumeric characters in publicly available english documents. It is assumed that the more frequently two consecutive alphanumeric characters appear in public documents, less likely that they are gibberish. The model should provide reasonable scores for english texts, and can be used to detect if the names or addresses contains gibberish. However, the model might not be suitable for abbreviations, such as short form for states (AZ, TX, etc.) and it also can't be used to validate names or addresses. Lastly, the model has not been tested for non-English texts.

      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 is 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())
      .GetDiagnostics() This function can be used to discover important diagnostic and debug information from an external call or an external assessment response. For an external call, the Diagnostics object contains the Request payload, Endpoint, HttpStatus code, Error message, and Latency. Endpoint isn't available in the Diagnostic object for an external assessment response. Any of these fields can be used in the rules once the Diagnostics object is created using its corresponding extension method".GetDiagnostics()"

      LET $extResponse = External. myCall(@"device.ipAddress")

      LET $extResponseDiagnostics = $extResponse.GetDiagnostics()

      OBSERVE Output(Diagnostics = $extResponseDiagnostics )

      WHEN $extResponseDiagnostics. HttpStatusCode != 200

      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:

      • Lookup(String listName, String keyColumnName, String key, String valueColumnName, String defaultValue)

      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, card category) based on bank identification number (BIN). Data for BIN Lookup is sourced from leading third-party BIN data providers and then curated by Fraud Protection.

      Operator Description Example
      BIN.Lookup(String BIN).cardNetwork

      This function looks up BIN and returns card 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).cardCategory

      This operator looks up BIN and returns card category (for example, Prepaid, Corporate, Rewards).

      BIN.Lookup(@"card.bin").cardCategory
      BIN.Lookup(String BIN).error

      This operator looks up BIN and returns an error message if the BIN couldn't 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 doesn'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

      Global Variables functions

      Global Variables functions can be used to set and get global variables within rules, velocities, routing rules, and post-decision action rules. The variables that are set can be accessed from within the same environment or from environments down the stack. For example, if you set global variables in a rule within the root environment, the variables can be accessed within the rules from the same environment or from their children. Also, global variables are specific to an assessment. A variable set within one assessment can't Hypen be accessed from another assessment.

      Operator Description Example
      SetVariables(k=v) This function can be used to set key-value pairs, that is, set values to variables. Do SetVariables(key= 123, email=@"user.email")
      GetVariable("k") This function can be used to access the variables that are already set. In cases where we access variables that are never set, a default value is returned.

      GetVariable("key").AsInt()

      GetVariable("email").AsString()

      GetVariable("key").AsDouble()

      GetVariable("key").AsBool()

      GetVariable("key").AsDateTime()

      GetVariable("key").AsJsonObject()

      GetVariable("key").AsJsonArray()

      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.

      Email
      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.

      Email 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're 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 nonstring 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"
        }
      }
      

      FQL functions for JSON arrays and objects

      Syntax Description Example
      myArr[0] You can use this syntax to access a specific array element by its index. myArr [0].property
      myArr [0][0]
      myArr [0][0].property
      myArr [0].property[0]
      myArr [0].property[0].property

      Where myArr, in the examples above, is an array. The source of this array can be the @@payloadProperty, external assessment response, external call response, local variable, or a global variable.

      The following are examples of how to use the syntax based on different array sources:

      • Array source: Payload
      LET $sample = @@"myArr[0]".AsJsonArray()   
      RETURN Approve()   
      WHEN $sample[0].AsString() == "a"
      
      • Array source: Local variable
        LET $group1 =["a", "b", "c"]
        LET $group1 =[{ item1: "a", item2: "b"}, { item1: "c", item2: "d"}]
        LET $group3 =[{ item1: "a", item2: "b", item3: ["c", "d"]}, {{ item1: "e", item2: "f", item3: ["g", "h"]}]
        RETURN Approve()
        WHEN $group1[0].AsString() == "a" && $group1[0].item2.AsString() == "b" && $group3[0].item3[0].AsString() == "c" 
        
      Syntax Description Example
      Array.GetValue (TargetArray .AsJsonArray(), matchKey, matchValue, lookupKey) With this function, you can access the first array element that matches a condition.

      Returns a value

      Array.GetValue(@@"payloadProperty".AsJsonArray(), matchKey, matchValue, lookupKey)
      Array.GetValues(TargetArray .AsJsonArray(), matchKey, matchValue) With this function, you can access a set of array elements that match a condition.

      Returns an array

      Array.GetValues(@@"payloadProperty".AsJsonArray(), matchKey, matchValue)

      The following are some more detailed examples of how to use the above syntax based on different array sources:

      Array Source Array.GetValue Array.GetValues
      External assessments LET $a = Assessments.myAssessment.evaluate()
      LET $sample = Array.GetValue($a.ruleEvaluations.AsJsonArray(), "rule", "Sample Payload Generation", "clauseNames")
      RETURN Approve()
      WHEN $sample[0].AsString() == "TestData"
      LET $a = Assessments.myAssessment.evaluate()
      LET $sample = Array.GetValues($a.ruleEvaluations.AsJsonArray(), "rule", "Sample Payload Generation")
      RETURN Approve()
      WHEN $sample[0].clauseNames[0].AsString() == "TestData"
      Payload Payload sample: {"group":[{"item1": "a", "item2": "a1"}, {"item1": "b", "item2": "b1"}]}

      LET $sample = Array.GetValue(@@"group".AsJsonArray(), "item1", "a", "item2")
      RETURN Approve()WHEN $sample.AsString() == "a1"
      Payload sample: { "group":[{"item1": "a", "item2": "a1"}, {"item1": "b", "item2": "b1"}]}

      LET $sample = Array.GetValues(@@"group".AsJsonArray(), "item1", "a")
      RETURN Approve()

      WHEN $sample[0].item2.AsString() == "a1"

      Global variables Using same payload sample as above

      Do SetVariables(Var=@@"group")
      LET $group = GetVariable("Var").AsJsonObject()
      LET $value = Array.GetValue($group, "item1", "a", "item2")
      RETURN Approve()
      WHEN $value.AsString() == "a1"
      Using same payload sample as above

      Do SetVariables(Var=@@"group")
      LET $group = GetVariable("Var").AsJsonObject()
      LET $arr = Array.GetValues($group.AsJsonArray(), "item1", "a")
      RETURN Approve()
      External call

      External call (myCall) response: {"group":[{"item1": "a", "item2": "a1"}, {"item1": "b", "item2": "b1"}]}

      LET $x = External.myCall().AsJsonObject()
      LET $value = Array.GetValue($x.group[0].AsJsonObject(), "item1", "a", "item2")
      RETURN Approve()
      WHEN $value.AsString() == "a1"

      External call (myCall) response: {"group":[{"item1": "a", "item2": "a1"}, {"item1": "b", "item2": "b1"}]}

      LET $x = External.myCall().AsJsonObject()
      LET $arr = Array.GetValues($x.group[0].AsJsonObject(), "item1", "a")
      RETURN Approve()WHEN $arr[0].item2.AsString() == "a1"

      Type casting for JSON arrays and objects

      • The following .As<Type>() are supported from the JsonObject:

        • AsString()
        • AsInt()
        • AsDouble()
        • AsDateTime()
        • AsBool()
        • AsJsonArray()
        • AsJsonObject()
      • When you use either of the two array helper methods, .GetValue or .GetValues, you need to type cast using .As<Type>(). Example:

        LET $arr = {myArr:[{item1: "red", number: 45}, {item1: "blue", number: 56}, {item1: "green", number: 33}]}
        LET $sample = Array.GetValues($arr.myArr.AsJsonArray(), "item1", "blue")
        
      • Once you converted data to a JSON object or array explicitly, you can use .As<Type>() to cast to a different data type, if needed. Example:

        RETURN Approve()
        WHEN $sample[0].number.AsInt() == 56
        
      • When you use @@, the data is implicitly type cast to a JSON object. If you then want to convert the JSON object to a different data type, you must use .As<Type>(). Example:

        LET $sample = @@”user.addresses”.AsJsonArray()
        
      • When you want to output in a certain format, you must use .As<Type>(). Example:

        LET $sample = @@”user.addresses”
        Output(abc = $sample.AsJsonArray())
        

      Note

      Type casting best practices:

      • Always type cast at the end of the . chain.

      Example:

      LET $sample = External.myCall().data[0].Item1[0].AsJsonArray()
      
      Or
      
      LET $sample = @@”accommodations[0].rooms”.AsJsonArray()
      
      • When you aren't sure, always explicitly type cast using .As<Type>().