Contextual Rule Features

Enrich authorization rules with card and account behavioral history to detect anomalies, flag first-time activity, and tailor fraud logic per cardholder.

📘

Contextual Rule Features is a premium capability of the Lithic Fraud Command suite. To enable Fraud Command, contact your Customer Success Manager.

Overview

Standard authorization rules apply the same thresholds to every card. A spend limit that catches fraud on low-activity cards will block legitimate purchases on high-spend cards. Contextual Rule Features solve this by evaluating each transaction relative to the specific card's or account's own history.

Contextual Rule Features give your authorization rules access to historical behavior data for the card or account being evaluated. Instead of acting only on properties of the current transaction (amount, MCC, country, etc.), you can write rules that factor in the full transaction history: average spend amounts, countries visited, time since last activity, and more.

A single program-wide rule using Contextual Rule Features automatically tailors itself to each card and cardholder. For example, a rule that challenges transactions with a z-score above 3 will flag a $200 charge on a card that typically spends $20, while allowing the same $200 charge on a card that regularly spends $500.

Contextual Rule Features are available in both CONDITIONAL_ACTION rules (as condition attributes) and TYPESCRIPT_CODE rules (via the TRANSACTION_HISTORY_SIGNALS and CONSECUTIVE_DECLINES feature inputs). They are evaluated on the AUTHORIZATION event stream only.

How It Works

Lithic automatically tracks transaction history for every card and account. When a rule references a contextual feature, the relevant history is evaluated at authorization time alongside the current transaction. For example, is_new_country checks whether the current merchant country has appeared in any previous approved transaction on the card.

Feature freshness depends on the category:

CategoryExamplesUpdate Frequency
Behavioral signalsIs New Country, Consecutive Declines, Is First TransactionWithin seconds of each transaction
Statistical aggregatesAverage, Standard Deviation, Z-ScoreRecomputed hourly

Contextual Rule Features only add latency to authorizations when at least one active rule references them. Programs without contextual rules are unaffected.

🚧

Contextual Rule Features use a fail-open design. If feature data is temporarily unavailable, all features return null and rules evaluate as if the features are absent. Unavailable feature data never blocks authorizations.

Available Features

Lithic regularly adds new contextual features. This guide covers the current set, but may not be exhaustive. See the Auth Rules API specification for the most up-to-date list of available attributes.

Anomaly Detection

Z-score measures how far the current transaction amount deviates from the card's or account's historical average, expressed in standard deviations. A z-score of 3 means the transaction amount is 3 standard deviations above the average: a strong outlier signal.

FeatureTypeDescription
Amount Z-ScorenumericHow many standard deviations the current transaction amount is from the historical mean
Avg Transaction Amountnumeric (cents)Mean amount of approved transactions
Stdev Transaction Amountnumeric (cents)Standard deviation of approved transaction amounts

Each of these features is available over the entity's (card, account, or business account) full lifetime and in 7-day, 30-day, and 90-day trailing windows. See Time Windows.

📘

Z-score and standard deviation require at least 30 approved transactions before returning a value. Average transaction amount requires at least 5. For programs with low per-card transaction volume, consider using account-level scope (which aggregates across all cards) to reach these thresholds faster, or use the boolean pattern features (Is New Country, Is New MCC) which have no minimum threshold.

Geographic and Spending Patterns

FeatureTypeDescription
Is New CountrybooleanWhether the merchant country has never appeared in the entity's transaction history
Is New MCCbooleanWhether the merchant category code has never appeared in the entity's transaction history
Distinct Country CountintegerNumber of unique merchant countries seen

These features are computed over the entity's full lifetime.

Activity Signals

FeatureTypeDescription
Is First TransactionbooleanWhether this is the very first transaction attempt on the entity
Time Since Last Transactionnumeric (days)Elapsed days since the most recent approved transaction
Consecutive DeclinesintegerCount of consecutive declined transactions, reset to 0 on any approval

Decline Velocity

FeatureTypeDescription
Decline Count (15m, 1h, 24h)integerNumber of declined transactions in the trailing window (card scope only)

3DS Authentication

FeatureTypeDescription
3DS Success Rateinteger (0 to 100)Percentage of successful 3DS authentications over the card's lifetime (card scope only)

Feature Scopes

Contextual Rule Features are computed at three scope levels. The scope determines which entity's transaction history the feature draws from:

ScopeValueDescription
CardCARDHistory of transactions on a single card
AccountACCOUNTHistory across all cards belonging to the account
Business AccountBUSINESS_ACCOUNTHistory across all accounts under the business account

Account and business account scopes are useful for detecting patterns that span multiple cards. Consider an account takeover where an attacker opens new cards on a compromised account. A rule that evaluates IS_NEW_COUNTRY at the ACCOUNT scope flags activity in a country that no card under the account has ever transacted in, even if the specific card being used is new.

Not all features are available at every scope:

FeatureCardAccountBusiness Account
Z-Score, Avg, StdevYesYesYes
Is New Country / MCCYesYesYes
Is First TransactionYesYesYes
Time Since Last TransactionYesYesYes
Distinct Country CountYesYesYes
Consecutive DeclinesYesYesNo
3DS Success RateYesNoNo
Decline Count (15m, 1h, 24h)YesNoNo

Time Windows

Statistical features (z-score, average, standard deviation) are available over multiple time windows:

WindowValueDescription
LifetimeLIFETIMEFull history of the entity
90 days90DTrailing 90-day window
30 days30DTrailing 30-day window
7 days7DTrailing 7-day window

Shorter windows capture recent behavioral shifts. A card that typically spends $50 per transaction but shifted to $200 over the past week would show a low lifetime z-score but a high 7-day z-score. Combining windows lets you distinguish between a genuine spending change and an anomalous burst.

See How It Works for feature freshness by category.

Using Contextual Rule Features in Rules

Conditional Action Rules

In CONDITIONAL_ACTION rules, reference contextual features as condition attributes. Most contextual attributes are parameterized: the attribute identifies the feature, and a parameters object specifies the scope and (for statistical features) the time window.

See the following examples:

  1. Anomalous Spend - challenge transactions where the card's 30-day z-score exceeds 3
  2. New Country - decline transactions in countries the card has never visited, skipping the card's very first transaction (where every country is inherently new)
  3. Card Testing - challenge after 5 consecutive declines so the real cardholder can verify and reset the counter
{
  "type": "CONDITIONAL_ACTION",
  "parameters": {
    "event_stream": "AUTHORIZATION",
    "conditions": [
      {
        "attribute": "AMOUNT_Z_SCORE",
        "parameters": {
          "scope": "CARD",
          "interval": "30D"
        },
        "operation": "IS_GREATER_THAN",
        "value": 3
      }
    ],
    "actions": [
      {
        "type": "CHALLENGE"
      }
    ]
  }
}
{
  "type": "CONDITIONAL_ACTION",
  "parameters": {
    "event_stream": "AUTHORIZATION",
    "conditions": [
      {
        "attribute": "IS_NEW_COUNTRY",
        "parameters": { "scope": "CARD" },
        "operation": "IS_ONE_OF",
        "value": ["TRUE"]
      },
      {
        "attribute": "IS_FIRST_TRANSACTION",
        "parameters": { "scope": "CARD" },
        "operation": "IS_ONE_OF",
        "value": ["FALSE"]
      }
    ],
    "actions": [
      {
        "type": "DECLINE",
        "decline_code": "UNAUTHORIZED"
      }
    ]
  }
}
{
  "type": "CONDITIONAL_ACTION",
  "parameters": {
    "event_stream": "AUTHORIZATION",
    "conditions": [
      {
        "attribute": "CONSECUTIVE_DECLINES",
        "parameters": { "scope": "CARD" },
        "operation": "IS_GREATER_THAN",
        "value": 5
      }
    ],
    "actions": [
      {
        "type": "CHALLENGE"
      }
    ]
  }
}
📘

Boolean contextual features use IS_ONE_OF with string values ["TRUE"] or ["FALSE"]. The CONDITIONAL_ACTION rule schema represents all condition values as strings or string arrays, so boolean checks follow the same pattern as other enum attributes. The decline_code specifies the reason code returned to the network. See the Auth Rules API specification for valid codes and the full list of supported operations.

📘

Conditions within a single rule are joined with AND logic. To express OR logic across different features, create separate rules. See Authorization Rules for details on rule structure and the full rule lifecycle.

Attribute Reference

Each attribute below lists the accepted parameters object alongside the attribute name. Statistical attributes accept both scope and interval; most behavioral attributes accept only scope; a few attributes take no parameters at all.

AttributeParametersTypeCompatible Operations
AMOUNT_Z_SCOREscope, intervalnumericIS_GREATER_THAN, IS_LESS_THAN, and other numeric comparisons
AVG_TRANSACTION_AMOUNTscope, intervalnumeric (cents)Same as above
STDEV_TRANSACTION_AMOUNTscope, intervalnumeric (cents)Same as above
IS_NEW_COUNTRYscopebooleanIS_ONE_OF with ["TRUE"] or ["FALSE"]
IS_NEW_MCCscopebooleanIS_ONE_OF with ["TRUE"] or ["FALSE"]
IS_FIRST_TRANSACTIONscopebooleanIS_ONE_OF with ["TRUE"] or ["FALSE"]
TIME_SINCE_LAST_TRANSACTIONscopenumeric (days)IS_GREATER_THAN, IS_LESS_THAN, and other numeric comparisons
DISTINCT_COUNTRY_COUNTscopeintegerSame as above
CONSECUTIVE_DECLINESscope (CARD or ACCOUNT)integerSame as above
THREE_DS_SUCCESS_RATE(none, card-only)integer (0 to 100)Same as above
CARD_DECLINE_COUNT_15M(none, card-only)integerSame as above
CARD_DECLINE_COUNT_1H(none, card-only)integerSame as above
CARD_DECLINE_COUNT_24H(none, card-only)integerSame as above

Valid scope values are CARD, ACCOUNT, and BUSINESS_ACCOUNT (except where noted). Valid interval values are LIFETIME, 7D, 30D, and 90D.

📘

Thresholds may be integers or decimals (e.g., "value": 2.5). Use whichever precision best fits the rule.

Custom Code Rules

In TYPESCRIPT_CODE rules, the statistical and behavioral signals are exposed as a TRANSACTION_HISTORY_SIGNALS feature, and consecutive decline counts are exposed as a separate CONSECUTIVE_DECLINES feature. Declare each feature with the desired scope. Each feature is passed to your rule() function as a typed input.

import {
  Authorization,
  TransactionHistorySignals,
  ConsecutiveDeclines,
  AuthorizationAction as Action,
} from './types';

function rule(
  authorization: Authorization,
  card_signals: TransactionHistorySignals,
  account_signals: TransactionHistorySignals,
  card_declines: ConsecutiveDeclines,
): Action[] {
  // Challenge if the card's 30-day z-score exceeds 3
  if (
    card_signals.amount_z_score_30d !== null &&
    card_signals.amount_z_score_30d > 3
  ) {
    return [
      Action.Challenge(
        `Z-score ${card_signals.amount_z_score_30d.toFixed(1)} exceeds threshold`
      ),
    ];
  }

  // Decline if a new country appears at the account level (cross-card ATO signal)
  if (
    account_signals.is_new_country === true &&
    authorization.amount > 100_00
  ) {
    return [
      Action.Decline(
        'UNAUTHORIZED',
        'New country on account with high-value transaction'
      ),
    ];
  }

  // Challenge after 5 consecutive declines on the card
  if (card_declines.count > 5) {
    return [Action.Challenge('Consecutive decline threshold exceeded')];
  }

  return [];
}

When creating the rule via the API, declare each feature with its scope:

{
  "type": "TYPESCRIPT_CODE",
  "parameters": {
    "event_stream": "AUTHORIZATION",
    "features": [
      { "name": "authorization", "type": "AUTHORIZATION" },
      { "name": "card_signals", "type": "TRANSACTION_HISTORY_SIGNALS", "scope": "CARD" },
      { "name": "account_signals", "type": "TRANSACTION_HISTORY_SIGNALS", "scope": "ACCOUNT" },
      { "name": "card_declines", "type": "CONSECUTIVE_DECLINES", "scope": "CARD" }
    ],
    "code": "..."
  }
}

The TransactionHistorySignals type exposes all the features listed in Available Features (except consecutive declines), plus additional properties for advanced use cases such as the raw sets of observed countries and MCCs (seen_countries, seen_mccs), approved transaction counts, Welford m2 values for custom variance calculations, and 3DS authentication counts. All properties are nullable. The ConsecutiveDeclines type exposes a single count property and supports only the CARD and ACCOUNT scopes. See the auto-generated type definitions in ./types for the full interface.

📘

For details on the Custom Code Rules execution environment, compilation, and constraints, see Custom Code Rules.

Inspecting Feature State

Use the Signals API to view the current feature state for a card or account outside of a rule evaluation. This is useful for debugging rules, building dashboards, or feeding contextual data into your own systems.

The response includes current values for statistical and behavioral features, the sets of countries and MCCs the entity has transacted in, the most recent card-present transaction location, and raw Welford m2 values for custom variance calculations.

📘

The Signals API returns features that can be computed without a transaction (averages, counts, sets, etc.). Features that require a current transaction for comparison (z-score, is_new_country, is_new_mcc) are computed at authorization time during rule evaluation. Consecutive decline counts are not exposed via this API; inspect them through rule evaluation reports instead.

Null Handling

Statistical features return null when insufficient data is available to produce a meaningful value. Null values are handled safely by default:

FeatureNull When
Avg Transaction AmountFewer than 5 approved transactions recorded
Stdev Transaction AmountFewer than 30 approved transactions recorded
Z-ScoreFewer than 30 approved transactions recorded
3DS Success RateNo 3DS authentication attempts recorded
Time Since Last TransactionNo prior approved transaction exists

In conditional action rules, a null value causes any comparison to evaluate to false. A rule that declines when AMOUNT_Z_SCORE > 3 at the card scope will not decline a card with no transaction history, because the null z-score produces a false comparison. Missing features never trigger a decline.

In custom code rules, null values appear as null in the TypeScript type. Always check for null before using a value:

if (
  signals.amount_z_score_30d !== null &&
  signals.amount_z_score_30d > 3
) {
  // Only fires when enough history exists AND the z-score exceeds the threshold
}

When no feature state exists at all (the entity has never transacted), behavioral features return sensible defaults rather than null: is_first_transaction returns true, is_new_country and is_new_mcc return true (any value is inherently new), distinct_country_count returns 0, and consecutive_declines.count returns 0. All statistical features return null.

Limitations

  • Authorization stream only: Contextual Rule Features are available on the AUTHORIZATION event stream.
  • Statistical feature freshness: Statistical features (average, standard deviation, z-score) are recomputed hourly and may lag real-time activity by up to one hour. Behavioral signals (is_new_country, consecutive_declines, etc.) update within seconds.
  • Minimum transaction thresholds: Z-score and standard deviation require at least 30 approved transactions before returning a value. Average transaction amount requires at least 5. Entities with limited history will have null values for these features.
  • Pattern features are lifetime-scoped: Is New Country, Is New MCC, and Distinct Country Count are computed over the entity's full lifetime.
  • Backtesting coverage: Contextual feature values are recorded alongside rule evaluations from the moment Fraud Command is enabled. We recommend enabling Fraud Command early, even before deploying contextual rules, to build backtesting history.
  • Consecutive declines scope: Consecutive Declines is available at the CARD and ACCOUNT scopes only.
  • Decline count scope: Decline Count (15m, 1h, 24h) and 3DS Success Rate are available at the card scope only.
  • Signals API scope: The Signals API exposes feature state at the card and account scopes. Business account scope state is available only through rule evaluation.

Next Steps

Rules using Contextual Rule Features support the same draft, shadow, and promotion lifecycle as all authorization rules, including instant deactivation. Use this lifecycle to safely test and deploy contextual rules.