Skip to main content
Match rules define how Matcher compares transactions across sources. You can enforce strict matches, allow controlled variance, or model more advanced logic with composite conditions.

How rules work


When a matching run starts, Matcher evaluates rules in priority order.
  • Rules are evaluated from the lowest priority number to the highest.
  • The first rule that produces a match determines the outcome.
  • If no rule matches, the transaction becomes an exception.
This approach ensures deterministic matching while allowing progressively looser rules as fallbacks.

Rule types


Exact

Requires a strict match on the selected fields.
  • Best for: Deterministic matches where values should align 1:1.

Tolerance

Allows controlled variance (amount and/or date).
  • Best for: Known variance patterns such as fees, rounding, or posting delays.

Composite

Combines multiple conditions using AND/OR logic.
  • Best for: Scenarios that depend on multiple signals (amount, reference patterns, counterparties).

Exact rules


EXACT rules require the configured fields to match precisely.

Basic exact rule

cURL
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_abc123/rules" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "name": "Exact Amount and Date",
   "description": "Match when amount, currency, and date are identical",
   "type": "EXACT",
   "priority": 1,
   "conditions": {
     "fields": [
       "amount",
       "currency",
       "date"
     ]
   }
 }'

Response

{
  "id": "rule_001",
  "name": "Exact Amount and Date",
  "type": "EXACT",
  "priority": 1,
  "conditions": {
    "fields": [
      "amount",
      "currency",
      "date"
    ]
  },
  "status": "ACTIVE",
  "created_at": "2024-01-15T10:00:00Z"
}

Exact rule with reference matching

Match on external reference values, optionally constrained by a pattern:
{
  "name": "Exact Reference Match",
  "type": "EXACT",
  "priority": 1,
  "conditions": {
    "fields": [
      "reference",
      "currency"
    ],
    "reference_pattern": "^INV-\\d+$"
  }
}
This rule matches when:
  • reference matches exactly
  • currency matches
  • reference also matches the configured pattern

Tolerance rules


Tolerance rules accept variance while keeping the match bounded and explainable.

Percentage tolerance

cURL
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_abc123/rules" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "name": "1% Amount Tolerance",
   "description": "Match when amounts are within 1% and dates within 3 days",
   "type": "TOLERANCE",
   "priority": 2,
   "conditions": {
     "amount": {
       "tolerance_type": "percentage",
       "tolerance_value": 1.0
     },
     "date": {
       "tolerance_days": 3
     },
     "currency": {
       "must_match": true
     }
   }
 }'

Response

{
  "id": "rule_002",
  "name": "1% Amount Tolerance",
  "type": "TOLERANCE",
  "priority": 2,
  "conditions": {
    "amount": {
      "tolerance_type": "percentage",
      "tolerance_value": 1.0
    },
    "date": {
      "tolerance_days": 3
    },
    "currency": {
      "must_match": true
    }
  },
  "status": "ACTIVE"
}
Example:
  • Transaction A: $1,000.00 on 2024-01-15
  • Transaction B: $1,008.00 on 2024-01-17
  • Variance: 0.8% amount, 2 days → Matches

Absolute tolerance

Use fixed variance for scenarios like fees:
{
  "name": "Fixed $5 Tolerance",
  "type": "TOLERANCE",
  "priority": 3,
  "conditions": {
    "amount": {
      "tolerance_type": "absolute",
      "tolerance_value": 5.0
    },
    "date": {
      "tolerance_days": 1
    },
    "currency": {
      "must_match": true
    }
  }
}

Combined tolerance

Use both percentage and absolute tolerances (whichever is greater):
{
  "name": "Combined Tolerance",
  "type": "TOLERANCE",
  "priority": 4,
  "conditions": {
    "amount": {
      "tolerance_type": "combined",
      "percentage": 0.5,
      "absolute": 10.0
    }
  }
}
This matches when variance stays within 0.5% or $10.00 (whichever allows more headroom).

Composite rules


Composite rules let you express matching logic as a decision tree using AND/OR blocks.

And conditions

All conditions must pass:
cURL
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_abc123/rules" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "name": "Wire Transfer Matching",
   "type": "COMPOSITE",
   "priority": 2,
   "conditions": {
     "operator": "AND",
     "rules": [
       {
         "field": "amount",
         "tolerance_type": "percentage",
         "tolerance_value": 0.5
       },
       {
         "field": "reference",
         "match_type": "contains",
         "value": "WIRE"
       },
       {
         "field": "date",
         "tolerance_days": 5
       }
     ]
   }
 }'

Response

{
  "id": "rule_003",
  "name": "Wire Transfer Matching",
  "type": "COMPOSITE",
  "priority": 2,
  "conditions": {
    "operator": "AND",
    "rules": [
      {
        "field": "amount",
        "tolerance_type": "percentage",
        "tolerance_value": 0.5
      },
      {
        "field": "reference",
        "match_type": "contains",
        "value": "WIRE"
      },
      {
        "field": "date",
        "tolerance_days": 5
      }
    ]
  },
  "status": "ACTIVE"
}

Or conditions

At least one sub-condition must match:
{
  "name": "Flexible Reference Match",
  "type": "COMPOSITE",
  "priority": 5,
  "conditions": {
    "operator": "AND",
    "rules": [
      {
        "field": "amount",
        "match_type": "exact"
      },
      {
        "operator": "OR",
        "rules": [
          {
            "field": "reference",
            "match_type": "exact"
          },
          {
            "field": "external_id",
            "match_type": "exact"
          },
          {
            "field": "counterparty",
            "match_type": "exact"
          }
        ]
      }
    ]
  }
}
This matches when amount is exact AND one of reference, external_id, or counterparty matches.

Rule priority


Rules are evaluated by priority. Lower numbers run first.

Priority strategy

PriorityRule typeUse case
1–10EXACTDeterministic matches
11–50TOLERANCE (tight)Small, expected variance
51–90TOLERANCE (loose)Broader variance that typically requires review
91–100Catch-allLast resort (use carefully)

Example priority configuration

[
  {
    "priority": 1,
    "name": "Exact Match",
    "type": "EXACT"
  },
  {
    "priority": 10,
    "name": "Reference Match",
    "type": "EXACT",
    "conditions": {
      "fields": [
        "reference"
      ]
    }
  },
  {
    "priority": 20,
    "name": "0.1% Tolerance",
    "type": "TOLERANCE",
    "conditions": {
      "amount": {
        "tolerance_type": "percentage",
        "tolerance_value": 0.1
      }
    }
  },
  {
    "priority": 50,
    "name": "1% Tolerance",
    "type": "TOLERANCE",
    "conditions": {
      "amount": {
        "tolerance_type": "percentage",
        "tolerance_value": 1.0
      }
    }
  },
  {
    "priority": 80,
    "name": "5% Tolerance",
    "type": "TOLERANCE",
    "conditions": {
      "amount": {
        "tolerance_type": "percentage",
        "tolerance_value": 5.0
      }
    }
  }
]

Confidence scoring


Rules can contribute to confidence scoring so your run output reflects match quality, not just pass/fail.
{
  "name": "Amount Tolerance Rule",
  "type": "TOLERANCE",
  "priority": 20,
  "conditions": {
    "amount": {
      "tolerance_type": "percentage",
      "tolerance_value": 1.0
    }
  },
  "scoring": {
    "base_score": 80,
    "deductions": {
      "per_percent_variance": 5,
      "per_day_variance": 2
    }
  }
}
Example calculation:
  • Base score: 80
  • Amount variance 0.5%: -2.5 points
  • Date variance 2 days: -4 points
  • Final score: 73.5

Rule parameters reference


Amount conditions

ParameterTypeDescription
tolerance_typeStringpercentage, absolute, or combined
tolerance_valueDecimalTolerance value
percentageDecimalPercentage for combined type
absoluteDecimalAbsolute value for combined type
sign_agnosticBooleanIgnore sign differences

Date conditions

ParameterTypeDescription
tolerance_daysIntegerDays before and after
days_beforeIntegerDays before only
days_afterIntegerDays after only
use_posting_dateBooleanUse posting date instead of transaction date

String conditions

ParameterTypeDescription
match_typeStringexact, contains, starts_with, ends_with, regex
case_sensitiveBooleanCase-sensitive matching
valueStringValue or pattern to match

Practical examples


Bank reconciliation rules

[
  {
    "name": "Exact Match - Same Day",
    "priority": 1,
    "type": "EXACT",
    "conditions": {
      "fields": [
        "amount",
        "currency",
        "date"
      ]
    },
    "scoring": {
      "base_score": 100
    }
  },
  {
    "name": "Exact Amount - Date Lag",
    "priority": 10,
    "type": "TOLERANCE",
    "conditions": {
      "amount": {
        "match_type": "exact"
      },
      "date": {
        "tolerance_days": 3
      },
      "currency": {
        "must_match": true
      }
    },
    "scoring": {
      "base_score": 95,
      "deductions": {
        "per_day_variance": 1
      }
    }
  },
  {
    "name": "Bank Fee Tolerance",
    "priority": 20,
    "type": "TOLERANCE",
    "conditions": {
      "amount": {
        "tolerance_type": "absolute",
        "tolerance_value": 50.0
      },
      "date": {
        "tolerance_days": 3
      },
      "currency": {
        "must_match": true
      }
    },
    "scoring": {
      "base_score": 85
    }
  }
]

Payment gateway reconciliation

[
  {
    "name": "Payment ID Match",
    "priority": 1,
    "type": "EXACT",
    "conditions": {
      "fields": [
        "external_id",
        "amount",
        "currency"
      ]
    },
    "scoring": {
      "base_score": 100
    }
  },
  {
    "name": "Processing Fee Tolerance",
    "priority": 15,
    "type": "TOLERANCE",
    "conditions": {
      "amount": {
        "tolerance_type": "percentage",
        "tolerance_value": 3.0
      },
      "date": {
        "tolerance_days": 2
      },
      "currency": {
        "must_match": true
      }
    },
    "description": "Allow up to 3% for payment processing fees",
    "scoring": {
      "base_score": 90
    }
  }
]

Intercompany reconciliation

[
  {
    "name": "Exact Intercompany Match",
    "priority": 1,
    "type": "EXACT",
    "conditions": {
      "fields": [
        "amount",
        "currency",
        "reference"
      ]
    },
    "scoring": {
      "base_score": 100
    }
  },
  {
    "name": "FX Variance Tolerance",
    "priority": 20,
    "type": "TOLERANCE",
    "conditions": {
      "amount": {
        "tolerance_type": "percentage",
        "tolerance_value": 2.0
      },
      "currency": {
        "must_match": false
      },
      "date": {
        "tolerance_days": 5
      }
    },
    "description": "Allow FX conversion variance",
    "scoring": {
      "base_score": 85
    }
  }
]

Testing rules


Test rules in dry-run mode before applying changes to production contexts.

Dry run a matching job

cURL
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_abc123/match" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "mode": "dry_run",
   "date_from": "2024-01-01",
   "date_to": "2024-01-31"
 }'

Response

{
  "job_id": "job_dry_001",
  "mode": "dry_run",
  "status": "COMPLETED",
  "summary": {
    "transactions_analyzed": 1000,
    "potential_matches": 920,
    "potential_exceptions": 80,
    "by_rule": [
      {
        "rule_id": "rule_001",
        "rule_name": "Exact Match",
        "matches": 750
      },
      {
        "rule_id": "rule_002",
        "rule_name": "1% Tolerance",
        "matches": 150
      },
      {
        "rule_id": "rule_003",
        "rule_name": "5% Tolerance",
        "matches": 20
      }
    ]
  },
  "note": "Dry run - no changes applied"
}

Test a specific rule

curl -X POST "https://api.matcher.example.com/v1/rules/rule_002/test" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "transactions": [
     {
       "id": "txn_1",
       "amount": 1000.0,
       "currency": "USD",
       "date": "2024-01-15"
     },
     {
       "id": "txn_2",
       "amount": 1005.0,
       "currency": "USD",
       "date": "2024-01-16"
     }
   ]
 }'

Response

{
  "rule_id": "rule_002",
  "would_match": true,
  "confidence": 92,
  "details": {
    "amount_variance": 0.5,
    "amount_variance_percent": 0.5,
    "date_variance_days": 1
  }
}

Managing rules


List rules

curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/rules" \
 -H "Authorization: Bearer $TOKEN"

Update rule priority

curl -X PATCH "https://api.matcher.example.com/v1/rules/rule_002" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "priority": 15
 }'

Disable a rule

curl -X POST "https://api.matcher.example.com/v1/rules/rule_002/disable" \
 -H "Authorization: Bearer $TOKEN"

Delete a rule

curl -X DELETE "https://api.matcher.example.com/v1/rules/rule_002" \
 -H "Authorization: Bearer $TOKEN"

Best practices


Lead with exact rules. Add tolerance rules only for the variance you can justify and explain.
Use gaps (1, 10, 20, 50) so you can insert rules without renumbering your entire set.
Treat rule updates as production changes. Validate match rates and exception volume before committing.
A rule should document the variance it covers and the risk it introduces.
If a rule never matches, it may be unnecessary. If it matches too often, it may be too broad.
High tolerance increases false positives. Use it as a fallback and review results carefully.

Next steps