SumScript

Define matching logic for each transaction.

Rule condition can consist of one or more criteria combined using AND/OR logic. When a transaction matches the condition, the rule triggers and applies the configured actions, for example assigning a risk score, adding a tag, or creating a case.

Sumsub evaluates conditions independently for each transaction, using only the data available at the time of evaluation. This makes condition behavior predictable and consistent. Conditions do not modify transaction data and do not produce any side effects.

During evaluation, conditions operate on the current transaction and may also take historical data into account. This allows rules to consider not only single events but also behavior over time.

How SumScript works

At the stage of the basic SumScript expression building, conditions operate on data from the current transaction. SumScript lets you reference transaction fields, applicants profile data, and custom properties.

📘

Note

To learn more about expression attributes, refer to this article.

You can access transaction data via the data path. This includes the transaction details sent in the request, such as amounts, currencies, participants, and other business-specific fields.

Some transaction fields are system-defined and describe the transaction itself rather than its content. These fields are accessed using the txn path. For example, txn.createdAt represents the timestamp when the transaction was created in the system.

SumScript allows referencing applicant information from two different sources, depending on what the rule needs to evaluate. The applicant.* path refers to data stored in the applicant profile, while data.applicant.* refers to applicant details included in a specific transaction and reflects the information as it was provided when that transaction was created.

Having access to both paths allows rules to compare applicant information stored in the applicant profile with the applicant details provided as part of a transaction, as well as to build conditions that rely specifically on verified profile data.

For example, a transaction may contain an applicant name that differs from the name stored in the applicant profile. In this case, applicant.fullName represents the name stored in the applicant profile, while data.applicant.fullName reflects the name provided as part of the transaction, making it possible to detect and evaluate such differences.

If you need to pass custom parameters that are not part of the standard transaction schema, you can use props. Values passed in props are always treated as strings.

📘

Note

To evaluate the current transaction, you can use custom properties in rule conditions, but they are not supported in aggregation conditions.

data.props.dailyOutLimit

Operators and expressions

SumScript expressions use standard operators – the building blocks you can use inside an expression to tell the engine how to evaluate transaction data.

Comparison operators

Comparison operators allow the system to compare values of compatible types.

OperatorDescription
=Checks whether the values are exactly the same.
!=Checks whether two values are different.
>Checks whether the value on the left is greater than the value on the right.
>=Checks whether the left value is greater than or equal to the right value.
<Checks whether the left value is less than the right value.
<=Checks whether the left value is less than or equal to the right value.
INChecks whether a value matches any item in a provided list.
data.info.direction = 'in'
data.info.amountInDefaultCurrency >= 1000
data.info.currencyCode IN ("EUR", "USD")

Logical operators

Logical operators allow the system to combine multiple checks in one rule condition.

OperatorDescription
ANDReturns true only when both expressions evaluate to true.
ORReturns true when at least one of the expressions evaluates to true.
NOTInverts a boolean expression. It returns true when the expression evaluates to false, and false when the expression evaluates to true.
data.info.amountInDefaultCurrency >= 1000 AND
data.info.currencyCode = "EUR"

Mathematical operators

Mathematical operators allow the system to calculate values inside an expression, usually to compare the result to a set threshold.

OperatorDescription
+Adds two numeric values and returns their sum.
-Subtracts the second numeric value from the first and returns the difference.
*Multiplies two numeric values and returns the result.
/Divides the first numeric value by the second and returns the quotient.
%Returns the remainder after dividing the first number by the second.
data.info.amountInDefaultCurrency / 100 > 10

Aggregation conditions

Aggregation conditions evaluate the current transaction in the context of other related transactions. They let us analyze behavior over time, such as transaction frequency, repetition, or patterns that cannot be detected from a single transaction.

Aggregation structure

An aggregation condition defines which transactions to include, how to group them, and which calculation to run on the resulting set.

An aggregation typically follows these steps:

  1. Select a transaction type.
  2. Define how to group transactions.
  3. Apply optional filters.
  4. Restrict the time window.
  5. Apply an aggregation function.
  6. Compare the result.

Each step narrows or transforms the transaction set until the aggregation produces a final value.

All aggregation conditions start with the txns keyword.

Aggregation scheme looks like the following: txns.<transactionType>.<aggregationType>.<filters>.<timeWindow>.<aggregateFunction>.

Then the aggregation expression compares its result using standard comparison operators.

Transaction type

The transaction type determines which events the aggregation includes.

txns.finance

txns.kyc

txns.travelRule

txns.userPlatformEvent

txns.iGamingSession

Grouping transactions

Grouping defines how transactions relate to each other. It also determines the aggregation scope and identity.

txns.finance.byApplicant

txns.finance.byCounterparty

txns.finance.byBeneficiary

txns.finance.byRemitter

txns.finance.byDevice

txns.finance.byIp

Filters

Filters further restrict which transactions the aggregation includes. You can apply multiple filters within a single aggregation condition to narrow the transaction set. Filters remain optional, so you can omit them when you do not need extra restrictions.

Common filters include:

  • Transaction direction:
    • in — includes only incoming transactions.
    • out — includes only outgoing transactions.
  • Transaction status:
    • approved — includes only approved transactions.
    • rejected — includes only rejected transactions.
    • notRejected — includes all transactions except rejected ones.
      📘

      Note

      By default, aggregations include transactions in all statuses. Use status filters when you need to restrict the aggregation to specific transaction states.

  • Participant matching:
    • sameCounterparty — includes transactions where the counterparty externalUserId matches that of the current transaction.
    • sameBeneficiary — includes only outgoing transactions with the same counterparty externalUserId as the current transaction.
    • sameRemitter — includes only incoming transactions with the same counterparty externalUserId as the current transaction.
    • sameParticipants — includes transactions involving the same pair of participants (applicant and counterparty) as the current transaction, regardless of direction.
  • Excluding the current transaction (excludeCurrent) — excludes the current transaction from the aggregation set.
    📘

    Note

    By default, aggregations include the current transaction in the result. Use excludeCurrent when you want the aggregation to count only previously completed transactions.

  • Custom field-based filtering
txns.finance.byApplicant.out.approved

txns.finance.byApplicant.sameCounterparty.excludeCurrent

Custom field-based filtering

The filter() function allows applying a custom condition to each transaction in the aggregation set.
Inside a filter, use the it keyword to reference the transaction currently evaluated within the aggregation.

txns.finance.byApplicant.filter(it.data.info.amountInDefaultCurrency >= 1000)  

txns.finance.byApplicant.filter(it.data.counterparty.device.ipInfo.ip = data.counterparty.device.ipInfo.ip)

Time window

Every aggregation condition must define a time window. The time window limits the aggregation to transactions that occurred within a specific period relative to the current transaction.

lastMinutes(10)

lastHours(24)

lastDays(7)

lastMonths(3)

currentCalendarMonth

Aggregation functions

Aggregation functions calculate a value over the selected transaction set. In the table below, you can find common aggregation functions.

FunctionDescription
countReturns the total number of transactions in the aggregation set.
existsReturns true when the aggregation set contains at least one matching transaction.
sumAdds up the values of a specified numeric field across the aggregated transactions and returns the total.
avgReturns the average value of a specified numeric field across the aggregated transactions.
minReturns the smallest value of a specified numeric field across the aggregated transactions.
maxReturns the largest value of a specified numeric field across the aggregated transactions.
distinctCountCounts how many unique values a specified field has across the aggregated transactions.
stddevSampReturns the sample standard deviation of a specified numeric field across the aggregated transactions.
distinctReturns the array of unique values of a specified field across the aggregated transactions.

Aggregation functions produce the output that can be used directly in rule conditions with standard operators.

txns.finance.byApplicant.lastMinutes(10).exists
txns.finance.byApplicant.lastHours(12).count < 3
txns.finance.byApplicant.lastDays(7).min(it.data.info.amountInDefaultCurrency) >= 10000
txns.finance.byApplicant.lastWeeks(2).distinctCount(it.data.info.currencyCode) = 5
'Birthday Present' IN txns.finance.byApplicant.lastMonths(1).distinct(it.data.info.paymentDetails)

Advanced usage

For more complex conditions, you can use advanced patterns described below.

Custom time windows

Custom time windows allow defining non-standard time ranges for aggregation conditions. You can use them when predefined intervals are not sufficient. In the table below, you can find the supported functions.

FunctionDescription
lastDefines a time window relative to the current transaction by combining multiple time units. Takes a duration argument.
fromDefines a time window starting from a specific date until the current transaction. Takes a non-null date argument.
timeRangeDefines a time window between two specific dates. Takes non-null date arguments.

Time window functions rely on time-related functions to define durations and dates used in aggregation windows.

The following functions are used to specify time intervals, which represent a length of time and are typically used with rolling windows.

FunctionDescription
secondsReturns a time interval measured in seconds.
minutesReturns a time interval measured in minutes.
hoursReturns a time interval measured in hours.
daysReturns a time interval measured in days.

To define points in time relative to the current transaction, you can use relative date functions. These functions return a date offset from the current transaction time.

FunctionDescription
minutesAgoReturns the date and time relative to the current transaction, offset by minutes.
hoursAgoReturns the date and time relative to the current transaction, offset by hours.
daysAgoReturns the date and time relative to the current transaction, offset by days.
weeksAgoReturns the date and time relative to the current transaction, offset by weeks.
monthsAgoReturns the date and time relative to the current transaction, offset by months.

In some cases, aggregation windows need to be aligned to specific calendar boundaries. Date alignment functions return a date adjusted to a calendar boundary and can be combined with other time functions.

FunctionDescription
nowReturns the date and time relative to the current transaction, offset by minutes.
toStartOfHourReturns the start of the calendar hour for the given date.
toStartOfDayReturns the start of the calendar day for the given date.
toStartOfWeekReturns the start of the calendar week for the given date.
toStartOfMonthReturns the start of the calendar month for the given date.
txns.finance.byApplicant.last(days(1) + minutes(10)).count < 5 txns.finance.byApplicant.excludeCurrent.from(toStartOfDay(now())).exists txns.finance.byApplicant.timeRange(daysAgo(14), daysAgo(7)).distinctCount(it.data.info.paymentDetails) > 3 

Values extraction

In addition to calculating numeric metrics, aggregation conditions can extract values from aggregated transactions. In the table below, you can find the supported value extraction functions.

FunctionDescription
firstValueReturns the value from the earliest transaction in the aggregation window.
lastValueReturns the value from the most recent transaction in the aggregation window.
txns.finance.byApplicant.lastDays(1).firstValue(it.data.info.paymentDetails) = 'Birthday Present'
txns.finance.byApplicant.excludeCurrent.lastDays(7).lastValue(it.data.info.currencyCode) = 'EUR'

Arrays

Array functions allow you to process arrays within rule conditions.

An array can be:

  • Returned by an aggregation (for example, through distinct function).
  • A field containing multiple values (for example, applicant.tags).
  • Constructed dynamically within an expression.

In arrayFilter and arrayCount, the condition is written using the variable -> expression syntax. The variable represents each element of the array, and the expression is evaluated for every element. The expression must return a boolean value.

FunctionDescription
arrayAvg(x)Returns the average of the numeric values in the array.
arrayCount(condition, x)Counts the number of elements in an array that match the condition.
arrayFilter(condition, x)Creates a new array that includes only the elements from the array that match the condition.
arraySum(x)Returns the sum of the numeric values in the array.
arrayMin(x)Returns the smallest numeric value in the array.
arrayMax(x)Returns the largest numeric value in the array.
length(x)Returns the total number of elements in the array.
arrayCount(v -> v IN ('High Risk', 'Medium Risk', 'Low Risk'), applicant.tags) > 1

Time difference calculations

Time difference functions allow comparing timestamps and calculating the difference between them. All time difference functions return numeric values. In the table below, you can find the time difference functions.

FunctionDescription
diffSeconds(x, y)Returns the difference between two timestamps, measured in seconds.
diffMinutes(x, y)Returns the difference between two timestamps, measured in minutes.
diffHours(x, y)Returns the difference between two timestamps, measured in hours.
diffSeconds(data.txnDate, txn.createdAt) > 60

diffMinutes(data.txnDate, txn.createdAt) > 5

Type conversion

Type conversion functions allow explicit control over data types. They are required when working with values stored as strings, such as custom props. In the table below, you can find the type conversion functions.

FunctionDescription
INT(x)Converts a value to an integer number.
FLOAT(x)Converts a value to a floating-point number.
DATE(x)Converts a value to a date.
STRING(x)Converts a value to a string.
FLOAT(data.props.dailyLimit) > 1000

Null-safe expressions

Null-safe functions allow handling missing or optional values without causing validation errors. In the table below, you can find the null-handling functions.

FunctionDescription
isNull(x)Returns true if the value is NULL.
isNotNull(x)Returns true if the value is not NULL.
ifNull(x, defaultValue)Returns a default value if x is NULL.
notNull(x)Converts a nullable value into a non-null value.
isNull(data.props.promoCode)
diffDays(ifNull(DATE(data.props.date), notNull(DATE(applicant.createdAt.timestamp))),data.txnDate) > 7