# GBDS Integration

## Introduction

This manual briefly describes each standard GBDS flow as a sequence of API calls, which are HTTP/HTTPS requests to a GBDS server. For full reference of GBDS API calls, consult the manual [GBDS API specification](https://app.gitbook.com/o/IUPwzGm81miB2T1d1ztv/s/MqtschPie46KAAzuKKeD/).

GBDS provides asynchronous notifications for long-running operations. The notification flows are detailed in the [Notification Flows Manual](https://docs.griaule.com/gbs/en/gbds-integration/notifier).

Authentication for all API calls is performed by presenting a valid token. A new token can be created with the call [createToken](https://gitbook.griaule.com/apis/gbds-4/tokens#post-tokens). A token can and should be used for multiple calls. Creating a new token before each call negatively affects system performance.

All diagrams in this manual follow this convention:

![Diagram Conventions](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-3e77f7c6ade8507548dc26ab58b184017b701c30%2Fflowkey.png?alt=media)

Additionally, GBDS follows an index for biometric identification, as represented in the table below:

| Index | Biometrics                                                                                     |
| ----- | ---------------------------------------------------------------------------------------------- |
| 0     | Little Left                                                                                    |
| 1     | Left Ring                                                                                      |
| 2     | Left Middle                                                                                    |
| 3     | Left Index                                                                                     |
| 4     | Left Thumb                                                                                     |
| 5     | Right Thumb                                                                                    |
| 6     | Right Index                                                                                    |
| 7     | Right Middle                                                                                   |
| 8     | Right Ring                                                                                     |
| 9     | Right Little                                                                                   |
| 10    | icon to open BCC Services.                                                                     |
| 13    | Left Iris                                                                                      |
| 14    | Right Iris                                                                                     |
| 20    | After finalizing the fingerprint capture, click Save, in the lower right corner of the screen. |
| 31    | Left Palmar Interdigital                                                                       |
| 32    | Left Palmar Thenar                                                                             |
| 33    | Left Palmar Hypothenar                                                                         |
| 34    | Right Palmar Interdigital                                                                      |
| 35    | Right Palmar Thenar                                                                            |
| 36    | Right Palmar Hypothenar                                                                        |
| 40    | Left Full Palm                                                                                 |
| 41    | Left Palmar Writer                                                                             |
| 45    | Right Full Palm                                                                                |
| 46    | Right Palmar Writer                                                                            |
| 200   | Newborn Left Palm                                                                              |
| 210   | Newborn Right Palm                                                                             |
| 900   | Sequence Control - Left Little                                                                 |
| 901   | Sequence Control - Left Ring                                                                   |
| 902   | Sequence Control - Left Middle                                                                 |
| 903   | Sequence Control - Left Index                                                                  |
| 904   | Sequence Control - Left Thumb                                                                  |
| 905   | Sequence Control - Right Thumb                                                                 |
| 906   | Sequence Control - Right Index                                                                 |
| 907   | Sequence Control - Right Middle                                                                |
| 908   | Sequence Control - Right Ring                                                                  |
| 909   | Sequence Control - Right Little                                                                |
| 940   | Sequence Control - Left Four Fingers                                                           |
| 941   | Sequence Control - Right Four Fingers                                                          |
| 942   | Sequence Control - Two Thumbs                                                                  |

## Enrollment Flow (Enroll)

In this case, the user wants to insert a new person into the ABIS. To do so, the user makes a call [enroll](https://gitbook.griaule.com/apis/gbds-4/people#post-people) (a request *POST* to the endpoint */gbds/v2/people*).

![Enrollment Flow](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-f2cb83f684e218ceac31443da826439bee702c31%2Fflowenroll.png?alt=media)

A well-formed enroll call will return an HTTP response with a unique transaction ID (*tguid*) as **data.tguid** and a status string in **data.status**.

The **tguid** will be used to identify this transaction in future calls and asynchronous notifications.

The user will be [notified](https://docs.griaule.com/gbs/en/gbds-integration/notifier) when GBDS finishes processing the transaction. The user can also query the transaction status with the call [getTransaction](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions-tguid) (a request *GET* to the endpoint */gbds/v2/people/transactions/{tguid}*).

If the transaction completes successfully (status *ENROLLED*), a unique person identifier (**pguid**) will be generated for lookup operations such as *getPerson*.

The status of an enrollment transaction can be:

**ENQUEUED**

> The transaction was queued for processing.

**PROCESSING**

> The transaction is being processed.

**FAILED**

> The enrollment transaction could not be completed. This situation is the result of exception handling or quality control handling.

**EXCEPTION**

> The enrollment generated at least one exception, and the transaction will remain in this state until the exception is handled (by the GBS ETR application or programmatically).

**PENDING**

> The enrollment failed automatic quality control, and the transaction will remain in this state until quality analysis is performed (by the GBS MIR application or programmatically).

**ENROLLED**

> The enrollment was completed successfully, and the transaction is associated with a valid unique person identifier (**pguid**), which can be obtained with the call *getTransaction*.

**REFUSED**

> The incoming transaction was refused because it matched another transaction associated with one or more pending active exceptions.

## Update Flow (Update)

In this case, the user wants to update the data associated with an existing person in the ABIS. If the user does not have the person identifier (**pguid**), they must obtain it using a biographic key or a transaction identifier (**tguid**):

* To obtain a **pguid** from biographic keys, the user should call [getPGuidUsingKeys](https://gitbook.griaule.com/apis/gbds-4/people#get-people-pguid-1) (a request *GET* to the endpoint */gbds/v2/people/pguid*).
* To obtain the **pguid** associated with a **tguid** known, the user should call [getTransaction](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions-tguid).

To perform the update, the user must call [update](https://gitbook.griaule.com/apis/gbds-4/people#put-people-pguid) (a request *PUT* to the endpoint */gbds/v2/people/{pguid}*).

![Update Flow](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-198f24c9bbcaf0230eeb0c143c57904bb631607f%2Fflowupdate.png?alt=media)

A well-formed update call will return an HTTP response with a unique transaction identifier (*tguid*) as **data.tguid** and a status string in **data.status**.

Update calls that modify biometric data will be processed similarly to enrollment transactions (Enroll), possibly generating exceptions and quality analysis (status *EXCEPTION* and *PENDING*), and will generate notifications for whoever initiated the transaction. The transaction status can also be queried with calls *getTransaction*.

Update calls that modify only biographic data will be processed synchronously. The HTTP response will contain only a status *OK* or *ERROR*.

## Verification Flow

In this case, the user wants to perform a *Verification* (1:1), comparing biometric data to a specific person in the ABIS. The search target must be identified by a single **pguid** or by a biographic key.

To perform the verification, the user must call [search](https://gitbook.griaule.com/apis/gbds-4/searches#post-people-searches) (a request *POST* to the endpoint */gbds/v2/people/searches*). The target profile for the comparison must be given by a biographic key in the parameter **data.keys** or by a *pguid* in **data.pguids**.

![Verification Flow](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-502964d4641ab789b0b416a3b81a77b99f82449a%2Fflowverify.png?alt=media)

The HTTP response will bring the verification result in the field **data.status**, which can be:

**MATCH**

> The provided biometric data matched the person's record in the ABIS.

**NOT\_MATCH**

> The provided biometric data did not match the person's record in the ABIS.

**PERSON\_NOT\_FOUND**

> The target person (**pguid** or biographic key) was not found in the database.

A transaction identifier (**data.tguid**) will also be returned, and further details about the verification operation can be obtained with the call [getSearchResult](https://gitbook.griaule.com/apis/gbds-4/searches#get-people-searches-tguid) (a request *GET* to the endpoint */gbds/v2/people/searches/{tguid}*).

### Verification with Multiple GUIDs

The endpoint `/gbds/v2/people/searches` allows verification requests with multiple PGUIDs or multiple UGUIDs in the case of latent verification.

This enables some new features:

1. Verification of multiple PGUIDs
   * Validates verification with a list of pguids. Only if `isUlSearch` is set to `false`.
   * Validates verification with a list of keys, using the attribute `keys`.
     * The list filters only one person.
     * This feature is valid only if `isUlSearch` is set to `false`.
2. Verification of multiple UGUIDs using `isUlSearch=true`.
   * Uses the attribute `uguids` as a list of strings.
   * Validates verification with this list of uguid. Only if `isUlSearch` is set to `true`.
3. Latent search in pguids/uguids
   * Latent search will be enabled if `isLatentSearch` is set to `true` for pguids search. For uguids search the value is always `true`.

## Identification Flow

In this case, the user wants to perform an *Identification* (1:N), comparing biometric data against several (possibly all) records in the ABIS.

To perform the identification, the user must call [search](https://gitbook.griaule.com/apis/gbds-4/searches#post-people-searches) (a request *POST* to the endpoint */gbds/v2/people/searches*) leaving the parameters **data.keys** and **data.pguids**.

{% hint style="warning" %}
empty `matcher` **MUST** In the case of an identification search, the attribute `DEFAULT`must be set to `MOBILE` will result in returning an error to the user.
{% endhint %}

![Identification Flow](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-a15481b43e9c307447c31347310fda5bc40b4c77%2Fflowidentify.png?alt=media)

Identification searches are performed asynchronously. A successful search call will return an HTTP response with a transaction identifier (**data.tguid**) and a status (**data.status**).

The user will receive a notification when the search completes. The user can also query the transaction status with the call [getSearchResult](https://gitbook.griaule.com/apis/gbds-4/searches#get-people-searches-tguid) (a request *GET* to the endpoint */gbds/v2/people/searches/{tguid}*).

The status of the search transaction can be:

**ENQUEUED**

> The search is queued and has not yet started processing.

**PREPARED**, **PROCESSING**

> These values indicate that the search is being processed.

**MATCH**

> The search was processed, and at least one match was found. Matches are returned in the field **data.cadidates** of the response to *getSearchResult*.

**NOT\_MATCH**

> The search was processed and no match was found.

**PERSON\_NOT\_FOUND**

> The search domain was empty: the specified filters, such as list of pguids and/or label filters resulted in an empty candidate set.

## Enrollment Recovery Flows

This section will present the flows to retrieve profile information using GBDS. For advanced filtering options in the calls to `listPeople` and `listTransactions`, consult the Manual [Using Wildcards to Retrieve Information from GBDS](#usando-coringas-para-recuperar-informacao-do-gbds).

### Retrieving a Single Person's Enrollment

To obtain the most current data associated with a specific person, the user must call [getPerson](https://gitbook.griaule.com/apis/gbds-4/people#get-people-pguid) (a request *GET* to the endpoint */gbds/v2/people/{pguid}*).

![getPerson Flow](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-99700cb7d3d20dbde34924194fac50416e5090df%2Fflowgetperson.png?alt=media)

The HTTP response will contain the person's biographic data and the most recent enrollment transaction associated with them.

### Obtaining the Pguid from Biographic Keys

To obtain a person's unique identifier (**pguid**) from a biographic key, the user must call [getPguidUsingKeys](https://gitbook.griaule.com/apis/gbds-4/people#get-people-pguid-1) (a request *GET* to the endpoint */gbds/v2/people/pguid*).

![getPguidUsingKeys Flow](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-45615924f34a03fa2ce301ec482f32f029a6ce51%2Fflowgetpguid.png?alt=media)

### Obtaining the Pguid from Biographic Data

To obtain a list of person identifiers (**pguids**) that match biographic data (and not just keys), the user can call [listPeople](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list) (a request *POST* to the endpoint */gbds/v2/people/list*).

![listPeople Flow](https://3757157672-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7Bx0xNdsdGHpCZ20yxbn%2Fuploads%2Fgit-blob-c337e9d2b4402ad38cf20b1d3cb2202b5e80f4d2%2Fflowlistpeople.png?alt=media)

{% hint style="info" %}
It is possible to make a listPeople call providing only the `value` which will be used to filter by key or biographic.

This request format can only be used for lists filtered by keys or biographic. If the filtering criterion is any other field, it must be specified in the format of `field:value`.
{% endhint %}

#### Restriction Field Criteria

It is possible to make a [listPeople](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list) call providing the criteria to filter the returned list. The field `restriction` must contain an array of objects that vary according to the data type (represented by the field `type` ) used as a filtering parameter. Each call can contain one or more restrictions, the accepted types are: **BIOGRAPHIC**, **DATE**, **KEY** and **LABEL**. The objects for each type are listed below:

* **BIOGRAPHIC**:

| Field                                    | Required                                                                                  | Type                                  |
| ---------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------- |
| type                                     | Yes. The value MUST be BIOGRAPHIC                                                         | String                                |
| id                                       | Yes                                                                                       | String                                |
| value                                    | Yes                                                                                       | String                                |
| exists                                   | Yes. Default true.                                                                        | Boolean                               |
| <p>matchMode<br><br><br><br><br><br></p> | <p>Default EXACT. Enum:<br>- START<br>- EXACT<br>- ANYWHERE<br>- END<br>- NOT\_EQUALS</p> | <p>String<br><br><br><br><br><br></p> |

* **DATE**:

| Field     | Required                      | Type   |
| --------- | ----------------------------- | ------ |
| type      | Yes. The value MUST be DATE   | String |
| startTime | Yes. Must be in milliseconds. | String |
| endTime   | No. Must be in milliseconds   | String |

* **KEY**:

| Field                                    | Required                                                                                  | Type                                  |
| ---------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------- |
| type                                     | Yes. The value MUST be KEY                                                                | String                                |
| id                                       | Yes                                                                                       | String                                |
| value                                    | Yes                                                                                       | String                                |
| exists                                   | Yes. Default true.                                                                        | Boolean                               |
| <p>matchMode<br><br><br><br><br><br></p> | <p>Default EXACT. Enum:<br>- START<br>- EXACT<br>- ANYWHERE<br>- END<br>- NOT\_EQUALS</p> | <p>String<br><br><br><br><br><br></p> |

* **LABEL**:

| Field  | Required                   | Type    |
| ------ | -------------------------- | ------- |
| type   | Yes. The value MUST be KEY | String  |
| label  | Yes                        | String  |
| exists | Yes. Default true.         | Boolean |

## Refused Transactions Flow (*REFUSED*)

The result *REFUSED* will occur in updates and enrollments when a new transaction matches an existing transaction that is associated with a pending biometric exception.

### Synchronous Transactions

When a transaction is submitted to a synchronous operation, the response will contain a field `data.status` with the value *REFUSED*:

```json
{
	"data":
	{
		"status":"REFUSED",
		"tguid": "string"
	}
}
```

### Asynchronous Transactions

In the case of an enrollment transaction submitted asynchronously, the response will contain a field `data.status` with the value *ENQUEUED*:

```json
{
	"data":
	{
		"status":"ENQUEUED",
		"tguid": "string"
	}
}
```

#### Receiving the Notification

When GBDS finishes processing a transaction, the *GBS Notifier* sends a notification to a *endpoint* configured with the TGUID and the processing result (*status*) of the transaction. If the transaction is refused, the *Notifier* will send a notification in the format:

```json
{
	"operation": "ENROLL",
	"tguid": "string",
	"status": "REFUSED"
}
```

or

```json
{
	"operation": "UPDATE",
	"tguid": "string",
	"status": "REFUSED"
}
```

{% hint style="warning" %}
After receiving the notification of a refused transaction (*REFUSED* ), a call to *getTransaction* must be submitted to GBDS with the TGUID as a parameter so that details about the transaction and its exceptions can be obtained.

The *getTransaction* operation is described in the next section, while the information on how to handle a refused transaction is described in the section [Handling a Refused Transaction](#tratando-uma-transacao-recusada-refused).
{% endhint %}

#### Performing Active Query

To perform an active query to obtain the results of a transaction, a call to *getTransaction* must be submitted to GBDS with the enrollment TGUID as a parameter with the following *endpoint*:

`http://<ip>:8085/gbds/v2/people/transactions/{tguid}`

The result of this call will contain a field `data.status` with the value *REFUSED*, as shown in the example below:

```json
{
	"data":
	{
		"tguid": "string",
		"pguid": "string",
		"status": "REFUSED",
		"timestamp": 0,
		"progress": 0,
		"Candidates": [],
		"Person": {},
		"qualityAnalysis": {},
		"failReason": "Enroll matches 2 person(s) that are already involved in a pending exception. PGUIDs: 75ABF575-6825-41D7-A2A7-2C0D64CF9FE7, B393C481-C0AF-456C-9155-1510AFDC7D86",
		"isCurrentTransaction": false
	}
}
```

### Handling a Refused Transaction (REFUSED)

As mentioned previously, a refused transaction occurs when an incoming profile matches an existing one that is linked to an active exception. When a transaction ends with this status, the incoming profile is discarded and a new transaction must be submitted for that profile after the pending active exceptions are handled.

After identifying the refused enrollment and performing the calls to *getTransaction* , the field *`failReason`* of the response to *getTransaction* will contain the PGUIDs of the reference profile that the incoming profile matched. The number of PGUIDs returned in the response is unlimited and separated by commas.

After all exceptions are handled, the refused enrollment can be resubmitted.

The complete workflow to resolve refused enrollments is:

{% hint style="warning" %}
The same workflow can be used to resolve refused updates using the equivalent commands.
{% endhint %}

**Example:**

1. Enrollment 1 - Generates TGUID 1 and PGUID 1;
   1. TGUID 1 - creates a biometric exception with an already existing PGUID 0;
   2. The application is notified with:

      ```json
      {
      	"operation": "ENROLL",
      	"tguid": "<TGUID 1>",
      	"status": "EXCEPTION"
      }
      ```
   3. Save TGUID 1 and PGUID 1
2. The application executes GET /gbds/v2/exceptions/{tguid}
   1. And the response is:

      ```json
      {
      	"data": [
      		{
      			"transactionTimestamp": 0,
      			"match": {
      				"matchedPersonPguid": "PGUID 0",
      				"matchedPersonTguid": "TGUID 0",
      				"biometricMatches": []
      			}
      		}
      	],
      	"pagination": {
      		"total": 0,
      		"count": 0,
      		"pageSize": 0,
      		"currentPage": 0,
      		"totalPages": 0
      	}
      }
      ```
   2. Create and save an artificial mapping from PGUID 0 to PGUID 1 / TGUID 1
3. Enrollment 2 - TGUID 2;
   1. TGUID 2 matches PGUID 0;
   2. TGUID 2 - receives status *REFUSED* because it matched PGUID 0 which was already linked to an exception;

      ```json
      {
      	"data": {
      		"tguid": "string",
      		"pguid": "string",
      		"status": "REFUSED",
      		"timestamp": 0,
      		"progress": 0,
      		"Candidates": [],
      		"Person": {},
      		"qualityAnalysis": {},
      		"failReason": "Enroll matches 1 person(s) that are already involved in a pending exception. PGUIDs: PGUID 0",
      		"isCurrentTransaction": false
      	}
      }
      ```
4. Save the PGUID `<PGUID 0>` associated with TGUID 2;
   1. Update the mapping indicating that PGUID 0 / PGUID 1 / TGUID 1 / TGUID 2 are linked
5. An examiner resolves the exception generated in Step 1:
   1. The application is notified with:

      ```json
      {
      	"operation": "TREAT_EXCEPTION",
      	"tguid": "<TGUID 1>",
      	"status": "OK",
      	"treatment": "TREATMENT_OPTION"
      }
      ```
6. Submit a new enrollment for TGUID 2.

{% hint style="warning" %}
It is possible that a PGUID that matched has multiple exceptions linked to it. In this scenario, all exceptions for the PGUID must be handled before attempting to resubmit the refused enrollment or update.
{% endhint %}

It is important to mention that the above workflow should be implemented to automatically complete transactions without any manual intervention.

In other words, to obtain the final result for this transaction (TGUID 2), it is necessary to wait for the notification from the *GBS Notifier* informing the treatment of the exception for the existing exception (TGUID 1) and execute the call to *getTransaction* to retrieve information about the PGUIDs that matched from GBDS (see the sections [Receiving the Notification](#recebendo-a-notificacao) and [Performing Active Query](#realizando-consulta-ativa)).

## Using Wildcards to Retrieve Information from GBDS

When retrieving information from GBDS using [List Transactions](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions) and [List People](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list), it is possible to use wildcard operators to filter the results.

When making a call to [List Transactions](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions) using the parameter `qualityStatus`the fields `key`, `biographic`, and `label` can be filtered using wildcard operators.

The wildcard operators are described below:

### List Transactions

#### Suffixes

The key or biographic fields can contain an `id:value` or `id|value`, for example `Name:John Doe`, where four suffixes can be inserted.

* **\[anywhere]**: This is the default suffix; if none is written, this will be selected. In this case, the application will search for the id or value provided anywhere in the string.

  > Example: If the key is `name[anywhere]:rob`, it will search for names (name) like "Robbin" and surnames (surname) "Robarts".
* **\[atstart]**: If this suffix is used, the application will search for the id or value provided at the beginning of the string.

  > Example: If the key is `passportNumber:123[atstart]`, it will search for passport numbers that start with 123 and will return all valid cases.
* **\[atend]**: If this suffix is used, the application will search for the id or value provided at the end of the string.

  > Example: If the key is `passportNumber:123[atend]`, it will search for passport numbers that end with 123. `name[atend]:son` will search for names (name) and surnames (surname) that end with "son".
* **\[exact]**: If this suffix is used, the application will search for matches identical to the one provided in the search string.

  > Example: If the key is `passportNumber:123[exact]`, it will search for passport numbers that are exactly equal to 123.

{% hint style="warning" %}
These wildcard operators are **SUFFIXES**, so they must be inserted AFTER the ID and/or AFTER the VALUE.
{% endhint %}

{% hint style="info" %}
Additionally, id and value can have different suffixes for each, so operations like: `name[exact]:rob[atstart]`, where it will search for fields that are named exactly `name` by values that start with "rob".
{% endhint %}

#### Prefixes

The biographic field can also have a prefix. This prefix can be used only on the FIRST biographic, before the `id`. Other prefixes will be ignored. This prefix will define which logical operation the application will perform between **ALL** the biographic and key fields. The accepted values are `[and]` and `[or]`, the first being the default value.

> Example: If the biographic is `[or]id:value`, an OR operation will be performed across all keys and biographics, such as: (Key1 OR Biographic1 OR Biographic2).

This prefix can be combined with a suffix, so values like `[or]id:value[exact]` are accepted.

### List People

When making a call to [List People](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list), the parameter `operator` can be either `and` or `or`. The selected operator will be applied in the comparisons between `key`, `biographic` and `label`. Afterwards, a `and` comparison will be made with the desired data value to filter the data.

Example: If the selected operator is `or`, the comparison for filtering the data will be: ((Key1 OR Biographic1 OR Biographic2 OR Label1) AND Date).

#### Restrictions matchMode

Within the restrictions object (restrictions), it is possible to select one of five `matchMode` when the restriction is a Biographic or a Key. The possible values and their operations are listed below.

{% hint style="danger" %}
Anything that is not a letter, a number or an underscore is a separator. A separator between numbers or letters will cause tokenization of the whole word/number in all modes except EXACT and NOT\_EQUALS.
{% endhint %}

{% hint style="warning" %}
In the restriction filter value, only the whitespace \`\` \`\` is a delimiter and will tokenize words/numbers. This behavior does not occur in EXACT and NOT\_EQUALS.
{% endhint %}

{% hint style="warning" %}
The search parameter is sensitive to special characters in letters, such as â, é, ñ and others.
{% endhint %}

{% stepper %}
{% step %}

#### EXACT

The *exact* operation searches the entire provided value. The use of *exact* will not tokenize the restricted expression. This mode is case-sensitive.

* Example: The call should return the value "Jose Arruda". Using EXACT with "Jose" or "Arruda" will work to return the desired value.

{% hint style="info" %}
Searches like "Jo" or "rrud" will not return Jose Arruda.
{% endhint %}

* Example 2: The call should return a numeric document value, like "123456". Using EXACT the value MUST be "123456".

{% hint style="info" %}
Searches with the value "123" or "456" will not return the correct value.
{% endhint %}

{% hint style="warning" %}
If the value is stored with a separator, the separator must be present in the restriction value.
{% endhint %}
{% endstep %}

{% step %}

#### START

The *start* will filter the values by tokenizing each word or set of numbers split by a separator.

* Example: If the user is restricting START to the value "Jo", some possible returns could be:

  ```default
  Jose Arruda
  John Doe
  Marie Johnson
  ```
* Example 2: If the user is restricting START to the value "Jose Arruda", some possible returns could be:

  ```default
  Jose Arruda
  Jose Silva
  Pedro Thomas Arruda
  ```
* Example 3: If the user is restricting START to the value "123", some possible returns could be:

  ```default
  1234567
  123.456
  456-123
  a-b 123
  ```
* Example 4: If the user is restricting START to the value "123.456", some possible returns could be:

  ```default
  123.456
  123.456.789-90
  ```

{% endstep %}

{% step %}

#### ANYWHERE

The operation in *anywhere* will search the value in any part of the word or number.

* Example: If the user's restriction is ANYWHERE for the value "Jo", some possible returns could be:

  ```default
  Jose Arruda
  Major
  Pejorative
  Banjo
  ```
* Example 2: Searching for "12" may return:

  ```default
  123456
  641256
  114-4312
  a-b 123
  ```
* Example 3: If the user's restriction is ANYWHERE for the value "Jo Ru", some possible returns could be:

  ```default
  Jose Arruda
  Ruth Silva
  Havier Russel
  ```

{% endstep %}

{% step %}

#### END

The *end* will search the value at the END of the token. Like START, this operation will tokenize words/numbers by each separator.

* Example: If the user's END restriction is for the value "son", some possible returns could be:

  ```default
  Eric Johnson
  Hudson Santos
  ```
* Example 2: If the user is restricting END to the value "Jose Arruda", some possible returns could be:

  ```default
  Jose Arruda
  Jose Silva
  Pedro Thomas Arruda
  Arruda Bastos
  ```
* Example 3: If the user is restricting END to the value "123", some possible returns could be:

  ```default
  4567123
  123.456
  456-123
  a-b 123
  ```
* Example 4: If the user is restricting END to the value "123.456", some possible returns could be:

  ```default
  123.456
  789.123.456
  ```

{% endstep %}

{% step %}

#### NOT\_EQUALS

The *Not equals* works inversely to the EXACT operation. It will filter out and DISCARD exact matches for the provided value and show ALL OTHER values. This mode is case-sensitive.

* Example: Using NOT\_EQUALS with the value "Jose" may return:

  ```default
  John Doe
  Marie Johnson
  Josemar Rodrigues
  ```
* Example 2: Using NOT\_EQUALS with the value "123" may return:

  ```default
  4567123
  123456
  ```

{% endstep %}
{% endstepper %}
