> ## Documentation Index
> Fetch the complete documentation index at: https://developer.mindbridge.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Saved Filters

**Saved Filters** are used to filter data tables in order to easily and repeatedly extract insights on large sets of data. The saved filters
endpoint allows for easy creation and management of saved filters, and validation of the applicability of filters across different data
tables and even across engagements and organizations.

Saved filters contain **conditions**, which are definitions on how the filter applies constraints on the underlying data table. These
conditions contain a field, type and various parameters depending on the condition type.

The field can either specify a column in the data table (with some constraints), or a special case field name, which provides the ability to
filter the data table on features of the dataset that are not represented by a specific column.

The condition type determines how the data will be filtered. Which types can be applied depends on the data table's column type and other
properties. For special case filters the type parameters depend on the underlying data table and analysis features. See the *Condition
Types* section for more details.

Saved filters can be used to filter general ledger, accounts payable, and accounts receivable analyses. They cannot be used as part of
custom analysis types.

### Validation

Saved filters are different from other entities in the MindBridge API in that the filter conditions are not immediately validated upon
creation. This is because they may or may not be applicable to different target data tables based on the analysis features and the column
present in the data table, and their types. To validate whether a given filter is compatible on a target data table a `/validate` endpoint
is provided, which will return a list of errors and warnings explaining incompatibilities between the provided filter and the target data
table.

### Display fields

Saved Filter conditions include various fields that are used in generating a description of the filter for each condition. This description
is visible in the web application and presents the filter in plain English.

In the web application, filters can only be created in either a library or analysis context, and have immediate context with which to base
the display fields on. The API doesn't require this context, and can therefore create filters in contexts the web application can't, such as
on an organization or engagement without any analyses. In order to generate a sensible filter description for use in the web application,
users of the API can optionally provide these values, and verify if they align with a target data table using the `/validate` endpoint.

### Filter types

Filters can be of one of four types:

`LIBRARY`, `ORGANIZATION`, `ENGAGEMENT` and `PRIVATE`

Library, organization, and engagement types determine which parent entity type the filter is stored under, and in some cases restrict which
fields can be used on those filters.

Private filters function like organization filters, but they are only accessible by the user that created them. This also applies to the API
users, who can only see private filters created by that same token user. The API cannot be used to access private filter created by other
users, including other token users.

### Filter data type

Filter data type is used to determine what kind of data the filter intends to target, and can be set to the values: `TRANSACTION_FILE`,
`ENTRIES_FILE` or `LIBRARY_ADMIN_TABLE`.

The `TRANSACTION_FILE` value corresponds to the transactions data table in a general ledger analysis.

The `ENTRIES_FILE` corresponds to a general ledger, accounts payable and accounts receivable entries tables.

### Disallowed fields

The following fields cannot be used as conditions:

* `account`, if the analysis is a general ledger analysis
* `accounts` or `mac_hierarchy`, if the data table column type is `ARRAY_STRINGS`
* `txid`, `rowid` or `matched_entry_id`, if the data table column type is `INT64`
* `total_amt`, if the data table column type is `MONEY_100`
* `invoice_paid_zero_date`, if the data table column type is `DATE_TIME`
* Any data table column whose field name starts with "`cp_score_`"
* Any data table column whose field name starts with "`risk`", and has data table column type `PERCENTAGE_FIXED_POINT`
* Any column that does not have a data table column type of `KEYWORD_SEARCH` or `LEGACY_ACCOUNT_TAG_EFFECTS`, and without one of
  `equalitySearch`, `rangeSearch` and `containsSearch` being `true`

### Condition types

Condition's types are determined by their `type` field. Some condition types also contain subtypes, which further determine what fields are
required to configure them.

Broadly there are 2 types of conditions: Group type conditions, and value conditions.

Group conditions don't require a field or other properties, and instead contain a sub-list of conditions that are applied against the data
table entries.

Value conditions filter a specific field and cover all other condition types other than `GROUP`. In addition to `field` they have the
following properties:

* `fieldLabel` - An optional display name for the field which is used in the full condition description.
* `negated` - When `true` the condition will instead exclude any entry that matches the condition from the result.
* `fullConditionDescription` - A description of the filter in plain English, using the provided display values such as `fieldLabel` and
  others.

#### `GROUP` type conditions

Group conditions, also known as rules, don't require a field, and contain both an operator and a list of conditions. The operation can be
either `AND` or `OR`, and the condition will match records that meet all or any of the conditions, depending on the operator. Group
conditions can be nested, and the value of the `condition` field on a saved filter must be a group condition, though it can be either type.

```json theme={null}
{
  "type": "GROUP",
  "operator": "AND",
  "conditions": [
    ...
  ]
}
```

#### `STRING` type conditions

String type conditions compare a field against a specific string value. This condition can only be applied to the following special case
fields:

| **Field**        | **Name**        | **Allowed Values**                                                                                                                        | **Notes**                                |
| ---------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `accountScoping` | Account Scoping | SIGNIFICANT, INSIGNIFICANT, UNSCOPED                                                                                                      | Only allowed on general ledger analyses. |
| `riskGroup`      | Risk Group      | Not `GENERAL` or `MindBridge Score`<br /><br />ASSETS, LIABILITIES\_EQUITY, PROFIT\_LOSS, or any custom account group by `category` name. | Only allowed on general ledger analyses. |

#### `STRING_ARRAY` type conditions

String array conditions compare the field against a set of string values. It can be applied to any data table column with the following
properties:

* Data table column type is `STRING` and `caseInsensitivePrefixSearch` is `true`.
* Data table column type is `KEYWORD_SEARCH`.

#### `CONTROL_POINT` type conditions

Control point conditions match a set of selected control points within their respective high, medium and low risk scores.

The control point type can only be used with the field `cp_failed` and when the data table column type is `BOOLEAN_FLAGS`.

The `riskLevel` property can be set to `HIGH_RISK`, `MEDIUM_RISK` or `LOW_RISK`.

The `controlPoints` contains a list of control point selection models, with the following properties:

* `id` - The unique ID of the control point prefixed with `custom_`, in the case of custom control points, or the symbolic name, in the case
  of MindBridge control points.
* `name` - The display name of the control point. Optional.
* `symbolicName` - The symbolic name of the control point. In the case of custom control points it must be the symbolic name of the
  underlying MindBridge control point.
* `isRulesBased` - Must be `true` if the target control point is rules based. Rules based control points can only have high and low risk
  values, and therefore cannot be selected with a `riskLevel` of `MEDIUM_RISK`.

Here is an example of both a MindBridge and a custom control point:

```json theme={null}
{
  "type": "CONTROL_POINT",
  "field": "cp_failed",
  "fieldLabel": "Control point",
  "negated": false,
  "riskLevel": "HIGH_RISK",
  "controlPoints": [
    {
      "id": "custom_682fab332f732c4d0b8d1ced",
      "name": "Expert Rules - Example Custom Control Point",
      "symbolicName": "journal_entry_flat_expert_flow_v2",
      "rulesBased": false
    },
    {
      "id": "journal_entry_two_digit_benford_v2",
      "name": "2 Digit Benford",
      "symbolicName": "journal_entry_two_digit_benford_v2",
      "rulesBased": false
    }
  ]
}
```

#### `ACCOUNT_NODE_ARRAY` type conditions

Account node array type conditions match an entry if it's within an account group or specific account code within varying contexts.

This condition type can only be used for general ledger analyses.

The following fields use the account node array type:

| **Field**                 | **Name**           | **Notes**                                                                                                                                      |
| ------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `account_hierarchy_codes` | Account            | Matches if the entry is associated with an account within the selection of accounts.                                                           |
| `increasingCredits`       | Increasing Credits | Matches if the entry is associated with an account within the selection of accounts and the credit value within those accounts are increasing. |
| `increasingDebits`        | Increasing Debits  | Matches if the entry is associated with an account within the selection of accounts and the debit value within those accounts are increasing.  |

Both `increasingCredits` and `increasingDebits` are special case fields and can be used even if they are not present as data table columns.

When using an `ACCOUNT_NODE_ARRAY` condition a list of account selections must be provided with the following properties:

* `name` - The display name of the account. Optional.
* `code` - The account group or account ID of the account.
* `useAccountId` - If `true` the condition should match the account id from the account mapping instead of the account group ID for this
  selection.

Here is an example of a condition that matches both an account group and a mapped account:

```json theme={null}
{
  "type": "ACCOUNT_NODE_ARRAY",
  "field": "increasingCredits",
  "fieldLabel": "Increasing credits",
  "negated": false,
  "accountSelections": [
    {
      "name": "Assets",
      "code": "1000",
      "useAccountId": false
    },
    {
      "name": "Accounts Payable",
      "code": "21011",
      "useAccountId": true
    }
  ]
}
```

#### `TYPEAHEAD_ENTRY` type condition

The typeahead entry type condition can be used to match one or more string values within a known set of allowed values. They are used both
to filter columns that have been mapped to certain MindBridge field and additional columns marked as filterable. There are also additional
special case field that can be used for various purposes.

| **Field**                     | **Name**                | **Notes**                                                                               |
| ----------------------------- | ----------------------- | --------------------------------------------------------------------------------------- |
| `status`                      | Status                  | Matches entries which contain corresponding tasks with the selected statuses.           |
| `memo`                        | Suspicious keyword      | Allowed values are from the Suspicious keyword control point.                           |
| `entriesFundRestriction`      | Fund restriction        | Allowed values are `restricted`, `unrestricted` and `none`                              |
| `transactionsFundRestriction` | Fund restriction        | Allowed values are `restricted`, `unrestricted`, `both` and `none`                      |
| `account_tags_increasing`     | Increasing account tags | Matches entries whose accounts using the provided account tags have increased in value. |
| `account_tags_decreasing`     | Decreasing account tags | Matches entries whose accounts using the provided account tags have decreased in value. |

In addition to the above field, any data table column with the type `STRING` or `ARRAY_STRINGS` and an ID set for `typeaheadDataTableId` can
be used in a typeahead entry condition. The allowed values for typeahead based fields are any of the values present in the column. Typeahead
column values are not currently validated, so no warnings will be produced if a value that is not present in the column is used as an entry.

A value selection for a typeahead entry has three properties: `lookupId`, which is the value being selected, `displayName`, which is the
display name of the underlying value, and `hideLookupId`, which hides the lookup ID when displaying the full display name.

Here is an example of a typeahead entry condition:

```json theme={null}
{
  "type": "TYPEAHEAD_ENTRY",
  "field": "entriesFundRestriction",
  "fieldLabel": "Fund restriction",
  "negated": false,
  "values": [
    {
      "lookupId": "none",
      "displayName": "No fund information",
      "hideLookupId": true
    },
    {
      "lookupId": "restricted",
      "displayName": "Restricted funds",
      "hideLookupId": true
    }
  ]
}
```

#### `POPULATIONS` type condition

The populations type condition matches any entries that are within the provided populations.

Population type conditions can only be used in general ledger analyses, and can only be used in saved filters at the analysis level.

Populations type conditions must use the special case field `population`. Population type conditions can only be applied to general ledger
analyses.

To include a population in the condition it simply needs to be added to the `populationIds` field. In addition to IDs, population category
names can be present in the population IDs list for display purposes.

Here is an example of a populations filter:

```json theme={null}
{
  "type": "POPULATIONS",
  "field": "population",
  "fieldLabel": "Population",
  "negated": false,
  "populationIds": [
    "Custom Category",
    "67d06587edfa507f5e80c7c2"
  ]
}
```

#### `RISK_SCORE` type condition

A risk score condition matches entries whose risk score falls within the constraints configured in the condition.

The specific risk score being tested is selected by setting the `riskScoreId` field to the field of the target risk score, as found in the
data table column metadata.

Risk scores are used on the special case fields `riskScoresHml` or `riskScoresPercentage`, depending on the library configuration for the
analysis. Additionally, the `riskScoreType` must be set to `HML` or `PERCENT` accordingly.

For HML type risk score conditions a set of the values `HIGH`, `MEDIUM`, `LOW` or `UNSCORED`, which match entries that fall within the
configured risk range for the selected risk score.

Here is an example of a HML risk score filter on a custom risk score:

```json theme={null}
{
  "type": "RISK_SCORE",
  "field": "riskScoresHml",
  "fieldLabel": "Risk score",
  "negated": false,
  "riskScoreType": "HML",
  "riskScoreId": "risk_67d2f16d9ffead02b4f54aad",
  "riskScoreLabel": "My custom risk score",
  "values": [
    "MEDIUM",
    "UNSCORED"
  ]
}
```

For percentage risk score conditions a `riskScorePercentType` of `MORE_THAN`, `LESS_THAN`, `BETWEEN`, `CUSTOM_RANGE` or `UNSCORED` is set.
These determine how the rule will be applied, and which parameters can be set.

For `UNSCORED` only entries that haven't been scored are matched.

For `MORE_THAN` and `LESS_THAN`, a `value` parameter must be set with a number from 0 to 10,000, representing a percentage between 0% to
100%, and matching entries with scores above or below the specified value.

For `CUSTOM_RANGE` a pair of percentage values `rangeStart` and `rangeEnd` are set. Any entries whose score falls between the values will be
matched.

`BETWEEN` is functionally equivalent to custom range, with the restriction that the `rangeStart` and `rangeEnd` must equal the start and end
values of one of the risk score's risk range entries (high, medium or low risk). In the web application this is represented as the user
selecting an existing risk range, rather than manually entering a pair of percentages as custom range requires.

Here is an example of a percentage risk score filter:

```json theme={null}
{
  "type": "RISK_SCORE",
  "field": "riskScoresPercentage",
  "fieldLabel": "Risk score",
  "negated": false,
  "riskScoreType": "PERCENT",
  "riskScoreId": "risk",
  "riskScoreLabel": "MindBridge score",
  "riskScorePercentType": "MORE_THAN",
  "value": 0
}
```

#### `MONETARY_FLOW` type condition

The `MONETARY_FLOW` type condition matches entries that are part of a monetary flow corresponding to the filter's configuration.

This condition type can only be used in general ledger analyses.

Only the special case field `monetarySpecificFlow` can be used with this condition type.

The property `monetaryFlowType` must be set to one of the following values, which determine what kind of flow to include entries from:
`SIMPLE_FLOW`, `COMPLEX_FLOW` or `SPECIFIC_FLOW`.

For simple and complex flow values, entries that are part of simple account to account flows, or flows that are too complex to assign to an
account are included.

For specific flows a pair of credit and debit account selections, `creditAccount` and `debitAccount` accordingly are set. These use the same
parameters as the account node array condition. In addition, the code may be set to `complex` to match flows whose credit or debit account
is
determined to be too complex to match.

Additionally for specific flows a value for `specificMonetaryFlowType` must be set, which further filters the entries based on the specific
value of the flow. The following values can be used:

* `SPECIFIC_VALUE` - by setting the `value` field to a currency amount only entries whose flow amount matches the value exactly will be
  matched.

* `MORE_THAN` - by setting the `value` field to a currency amount only entries where the flow value exceeds that amount will be matched.

* `BETWEEN` - a pair of `rangeStart` and `rangeEnd` values only entries whose value is between the specified currency amounts.

Currency amounts are expressed as integers, and do not include decimal places. They follow the same formatting rules as `MONEY_100` fields.
See the *Data Formats* section for more information.

Here is an example of a monetary flow condition:

```json theme={null}
{
  "type": "MONETARY_FLOW",
  "field": "monetarySpecificFlow",
  "fieldLabel": "Monetary flow",
  "negated": false,
  "monetaryFlowType": "SPECIFIC_FLOW",
  "creditAccount": {
    "name": "Flows too complex to determine a match",
    "code": "complex",
    "useAccountId": false
  },
  "debitAccount": {
    "name": "Operational assets",
    "code": "1100",
    "useAccountId": false
  },
  "specificMonetaryFlowType": "BETWEEN",
  "rangeStart": 0,
  "rangeEnd": 1037979412
}
```

#### `MONEY` type condition

The money type condition matches entries whose value for the provided field is within the configured bounds of the condition.

The money type condition can be applied to any field with a data table column type of `MONEY_100`.

The following `monetaryValueType` values can be used to configure how the entries are matched:

* `MORE_THAN` - Matches entries whose value is more than the configured `value` field.
* `LESS_THAN` - Matches entries whose value is less than the configured `value` field.
* `SPECIFIC_VALUE` - Matches entries whose value is equal to the configured `value` field.
* `BETWEEN` - Matches entries whose value is between the provided `rangeStart` and `rangeEnd` values.

The values for `value`, `rangeStart` and `rangeEnd` follow the same formatting rules as the `MONEY_100` data type.

Here is an example of a money type condition:

```json theme={null}
{
  "type": "MONEY",
  "field": "bs_delta",
  "fieldLabel": "Balance sheet impact",
  "negated": false,
  "monetaryValueType": "MORE_THAN",
  "value": 0
}
```

#### `MATERIALITY` type condition

The materiality type condition matches entries that are above, below or above a percentage of the threshold.

The materiality type condition can be applied to general ledger analyses with a materiality judgment value set, and can only be applied to
the special case `materiality` field.

The following `materialityOption` values can be used to configure how the entries are matched:

* `ABOVE` - Matches entries whose value is above the materiality threshold.
* `BELOW` - Matches entries whose value is below the materiality threshold.
* `PERCENTAGE` - Matches entries whose value is above a percent of the materiality threshold. The percent is a decimal number set in the
  `value` field, and can be greater than 100%.

Here is an example of a materiality type condition, and represents a percentage value of 110.25%:

```json theme={null}
{
  "type": "MATERIALITY",
  "field": "materiality",
  "fieldLabel": "Materiality",
  "negated": false,
  "materialityOption": "PERCENTAGE",
  "value": 110.25
}
```

#### `NUMERICAL` type condition

The numerical type condition matches entries whose value for the provided field is within the configured bounds of the condition.

This condition can be applied to any field with a data table column types of `INT32`, `INT64`, `FLOAT32` and `FLOAT64`.

The following `numericalValueType` values can be used to configure how the entries are matched:

* `MORE_THAN` - Matches entries whose value is more than the configured `value` field.
* `LESS_THAN` - Matches entries whose value is less than the configured `value` field.
* `SPECIFIC_VALUE` - Matches entries whose value is equal to the configured `value` field.
* `BETWEEN` - Matches entries whose value is between the provided `rangeStart` and `rangeEnd` values.

Here is an example of a numerical type condition:

```json theme={null}
{
  "type": "NUMERICAL",
  "field": "entries_count",
  "fieldLabel": "Entries count",
  "negated": false,
  "numericalValueType": "MORE_THAN",
  "value": 0
}
```

#### `DATE` type condition

The date type condition matches entries whose value for the provided field is within the configured bounds of the condition.

The numerical type condition can be applied to any field with a data table column types of `DATE` and `DATE_TIME`.

The following `numericalValueType` values can be used to configure how the entries are matched:

* `AFTER` - Matches entries whose value is more than the configured `value` field.
* `BEFORE` - Matches entries whose value is less than the configured `value` field.
* `SPECIFIC_VALUE` - Matches entries whose value is equal to the configured `value` field.
* `BETWEEN` - Matches entries whose value is between the provided `rangeStart` and `rangeEnd` values.

The values for `value`, `rangeStart` and `rangeEnd` should be expressed as ISO date strings, without a timestamp or timezone.

Here is an example of a date type condition:

```json theme={null}
{
  "type": "DATE",
  "field": "effective_date",
  "fieldLabel": "Effective date",
  "negated": false,
  "dateType": "SPECIFIC_VALUE",
  "value": "2010-01-01"
}
```

### Legacy filters

Saved filters with the `legacyFilterFormat` field set to `true` are using a legacy format which is not supported by the API, and will have
their `condition` property set to `null`.
