You can create a matching ruleset to define how LUSID compares data for a reconciliation (rec) type, such as holding, input transaction, or valuation. Once you create a matching ruleset, you can use it in any number of reconciliation definitions.
Recommended reading: Understanding advanced reconciliations
Methods
Navigate to Advanced Recs > Matching Rulesets.
Click the Create matching ruleset button and populate the form. Continue reading this article to learn more about the fields you can populate in a matching ruleset.

Call the CreateMatchingRuleset API, for example:
curl -X POST "https://<your-domain>.lusid.com/api/api/recs/[TBC: endpoint path]"
-H "Authorization: Bearer <your-API-access-token>"
-d "{
"id": {
"scope": "Finbourne-Examples",
"code": "HoldingUnits"
},
"displayName": "Compare holding units",
"recType": "Holding",
"filters": {
"left": "holdingType eq 'P'",
"right": "holdingType eq 'P'"
},
"coreRules": [
{
"ruleName": "Instrument",
"leftFormula": "Properties[Instrument/default/Figi]",
"rightFormula": "Properties[Instrument/default/Figi]",
"isCaseSensitive": false
}
],
"aggregateRules": [
{
"ruleName": "Units",
"leftFormula": "units",
"leftOperation": "Sum",
"rightFormula": "units",
"rightOperation": "Sum"
}
],
"allowPartialMatching": true
}"Fields
Rec type
Specifies the reconciliation type this matching ruleset applies to, out of:
Holding
Cash holding
Valuation
Input transaction
Output transaction
Settlement activity
Pre-filters
You can specify a left and right LUSID filtering expression that LUSID applies to that side’s data before comparing anything.
Core rules
Core rules tell LUSID how to pair up records from each side of the reconciliation.
Each core rule defines a value that must agree on both sides for LUSID to treat two records as the same. For a holdings reconciliation, for example, this could be an instrument identifier such as a FIGI or ISIN.
Each core rule has:
A Name, which you see as a column heading in your results.
A Left formula and Right formula which use LUSID filtering syntax to tell LUSID where to find the value on each side. See Appendix A for more information on accepted formula values.
If you add more than one core rule, LUSID only pairs two records together when the values for every core rule agree, or fall within that rule’s core tolerances.
💡 TipChoose a core rule (or set of core rules) that:
Identifies each record uniquely
Contains a value for every record on both sides
For example, cash balances don’t have a FIGI, so a FIGI core rule gives every cash balance the same empty value. Use pre-filters to exclude records like these, and reconcile them separately with a suitable rec type, such as Cash holding.
Core tolerances
You can add core tolerances to relax how your core rules behave, so LUSID can pair records whose values for that rule aren’t identical.
LUSID always attempts to pair exact records first; it only uses core tolerances for records it can’t pair exactly.
You can add up to five core tolerances to a matching ruleset. For each core tolerance, you must specify:
The Rule name it relaxes.
A Tolerance type and its relevant fields. There are three core tolerance types:
For what each core tolerance type does, see Appendix B: Tolerances.
Aggregate rules
Aggregate rules tell LUSID which values to compare on records it has already paired, such as the number of units held. For each pair, LUSID shows you the following:
The value from each side
The difference between them
For each aggregate rule, you specify:
A Name, which you see as a column heading in your results.
A Left formula and Right formula which tell LUSID where to find the value to compare on each side. See Appendix A for more information on accepted formula values.
A Left operation and Right operation which tell LUSID how to combine the values on each side when more than one record shares the same core rule values. For example, Sum adds up the units across all those records.

Aggregate tolerances
You can add aggregate tolerances to allow compared values to differ by an acceptable amount without the result becoming a partial match. You can only use the numeric tolerance type for aggregate rules.
LUSID applies the numeric tolerance to each side’s total, after it has combined the values using the rule’s operation. See Appendix B: Tolerances for more information.
Updating a matching ruleset
Once created, you can update a matching ruleset in the following ways:
Via the LUSID web app: Find the ruleset you need to update and click the Edit icon.

Via the LUSID API: Call the UpdateMatchingRuleset endpoint.
When you update a matching ruleset:
All subsequent reconciliation runs that use the ruleset will use the updated version.
Reruns of an existing reconciliation instance that use the ruleset will use the updated version.
Appendix A: Using built-in fields and properties in formulas for each rec type
The built-in fields you can refer to in a rule formula depend on the rec type. Core rules and aggregate rules refer to the same fields.
The following table shows some examples for each rec type:
Rec type | What built-in fields can I use? | What properties can I use? |
|---|---|---|
Holding | Holding fields, for example:
| Properties from the following domains:
For example, |
Cash holding | Holding fields, for example:
| |
Valuation | Valuation fields, for example:
| Properties accessed via address key, for example |
Input transaction | Input transaction fields, for example:
| Properties from the |
Output transaction | Output transaction fields, for example:
| |
Settlement activity | Settlement activity fields, for example:
| Properties from the following domains:
|
Appendix B: Tolerances
Tolerance type | Applicable rule type | Data type rule formula must return |
|---|---|---|
Text | ||
Any | ||
Dates | ||
Numbers |
Tolerance type: String cross
A string cross tolerance treats one specific value on a side as equal to a different value on the other side.
Use this tolerance type for known differences in how each side records the same thing.
Important
LUSID reports records paired using a string cross tolerance as one of the following in the results:
A
Crossif the aggregate rules agree.A
Partial Crossif the aggregate rules disagree.You can check which tolerance LUSID used for a result in its Applied tolerance column.
Field | Description |
|---|---|
Reference side | The side where LUSID expects to find the Reference value:
|
Reference value | The value LUSID looks for on the reference side. |
Cross value | The value on the other side that LUSID treats as equal to Reference value. |
Note
To treat more than one pair of values as equal, add a separate tolerance for each pair.
For example, you could set a string cross tolerance when one side uses GBP, whilst the other uses GBp (and you want GBp to be considered GBP for the rec run):

If you’re creating a ruleset via API, you might specify the following:
{
"toleranceType": "CoreStringCross",
"ruleName": "Currency",
"referenceValue": "GBP",
"crossValue": "GBp",
"referenceSide": "Left"
}Tolerance type: Attribute optionality
An optionality tolerance allows LUSID to pair records when one side has no value for the core rule, for example because a property isn't set.
Field | Description |
|---|---|
Optional side | Sets which side is allowed to have no value:
|
For example, you could set a tolerance where a right side with no strategy pairs with any strategy on the left side, whilst a left side with no strategy still has to agree with the right side exactly:

If you’re creating a ruleset via API, you might specify the following:
{
"toleranceType": "CoreAttributeOptionality",
"ruleName": "Strategy",
"optionalSide": "Right"
}Tolerance type: Date
A date tolerance pairs records when the date on one side is within an interval of the date on the other side.
Field | Description |
|---|---|
Reference side | The side whose date LUSID measures the interval from: |
Interval | How far the other side's date can be from the reference date, as an ISO 8601 period. For example:
|
Offset | Which direction the other side's date can differ in:
|
Note
The date range includes the dates at each end.
A record with no date never falls within a date tolerance.
For example, you could set a tolerance where a left settlement date 1 Oct 2026 pairs with a right settlement date anywhere from 30 Sep to 2 Oct 2026:

If you’re creating a ruleset via API, you might specify the following:
{
"toleranceType": "CoreDateTolerance",
"ruleName": "SettlementDate",
"referenceSide": "Left",
"interval": "P1D",
"offset": "Either"
}Tolerance type: Numeric
A numeric tolerance allows the totals for an aggregate rule to differ by a specified acceptable amount.
Field | Description |
|---|---|
Reference side | Whether LUSID should measure the difference from the |
Absolute threshold | The difference allowed, in the rule’s own units. Must be greater than 0. |
Relative threshold | The difference allowed, as a percentage of the reference side’s total. Must be greater than 0. For example, |
Threshold priority | If you set both Absolute threshold and Relative threshold, this specifies how LUSID combines the two thresholds:
|
Offset | Which direction the non-reference side’s total can differ in:
|
Note
The range includes the values at each end.
A side with no total never falls within a numeric tolerance.
If you add more than one numeric tolerance to the same rule, the totals pass if they’re within any one of them.
For Relative threshold, the inputs vary depending on whether you’re using the LUSID web app or LUSID API:
LUSID web app: Specify a percentage, for example
10allows a 10% differenceLUSID API: Specify a fraction, for example
0.1allows a 10% difference
For example, this is how different thresholds could apply if the left side’s total is 100 and the right side’s total is 90 (a difference of 10, or 10% of the reference total):
Threshold scenario | Absolute threshold | Relative threshold (%) | Threshold priority | Within tolerance? |
|---|---|---|---|---|
Absolute threshold equals the difference. |
| Not set | Not set | |
Absolute threshold is less than the difference. |
| Not set | Not set | |
Relative threshold equals the relative difference. | Not set |
| Not set | |
Specifying both an Absolute and Relative threshold, with a Threshold priority of |
|
|
| |
Specifying both an Absolute and Relative threshold, with a Threshold priority of |
|
|
|
Creating the final threshold scenario in the LUSID web app looks like this:

If you’re creating a ruleset via API, you might specify the following:
{
"toleranceType": "Numeric",
"ruleName": "Units",
"referenceSide": "Left",
"absoluteThreshold": 9,
"relativeThreshold": 0.1,
"thresholdPriority": "LesserOf",
"offset": "Either"
}