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

# Identity Matching Logic

> Detailed specification of how identity fields are compared, scored, and weighted to determine match level

## Overview

Identity matching compares the **candidate** (the person being screened) against the **subject** found in a criminal record. Each identity field is independently evaluated and assigned a match status, then weighted to produce an overall score that determines the identity level used for routing.

## Match Statuses

Every field comparison produces one of the following statuses:

| Status            | Value | Description                                               |
| ----------------- | ----- | --------------------------------------------------------- |
| **Missing**       | —     | Field is empty or unavailable on one or both sides        |
| **Invalid**       | —     | Field is present but contains invalid or unparseable data |
| **Not Match**     | 0     | Fields are present on both sides but do not match         |
| **Match**         | 1     | Fields are present on both sides and fully match          |
| **Partial Match** | 0–1   | Fields partially match (applies to Name and DOB only)     |

***

## Field-Level Matching Rules

### Name

Name matching compares `first_name`, `last_name`, and optionally `middle_name` between the candidate and the record subject. Aliases are also considered.

| Component          | Rule                                                                                                             |
| ------------------ | ---------------------------------------------------------------------------------------------------------------- |
| **Last Name**      | Required. If the last name is an empty string, the field is treated as **Missing**.                              |
| **First Name**     | Must match exactly. Any single character difference results in **Not Match**.                                    |
| **Middle Name**    | Optional. Not required for a full match.                                                                         |
| **Partial Match**  | If only the last name matches (first name does not), the result is **Partial Match**.                            |
| **Alias Matching** | If the primary name does not match, aliases are checked. A first name alias match counts as a **Partial Match**. |

### Date of Birth (DOB)

DOB is compared component by component: year (YYYY), month (MM), and day (DD).

| Scenario                                    | Result                              |
| ------------------------------------------- | ----------------------------------- |
| All three components match (YYYY + MM + DD) | **Match**                           |
| Only the year matches                       | **Partial Match**                   |
| Year matches but month does not match       | **Not Match** (even if day matches) |
| Only month or only day available (no year)  | **Not Match**                       |
| DOB missing or unparseable on either side   | **Missing**                         |

### SSN (Social Security Number)

SSN matching is strict with no fuzzy logic. Partial SSNs from the court are not treated as a match.

| Scenario                                                     | Result                              |
| ------------------------------------------------------------ | ----------------------------------- |
| All 9 digits match exactly                                   | **Match**                           |
| Even 1 digit differs                                         | **Not Match**                       |
| Court provides only last 4 digits and candidate has full SSN | **Partial Match** (last 4 compared) |
| Either side is empty or missing                              | **Missing**                         |
| Court provides a partial SSN (not last-4 format)             | **Not considered a match**          |

### Address

Address matching uses standardized address comparison. There is no partial match for addresses.

| Scenario                       | Result        |
| ------------------------------ | ------------- |
| Standardized addresses match   | **Match**     |
| Addresses do not match         | **Not Match** |
| Address missing on either side | **Missing**   |

***

## Scoring Weights

Each field's match score is multiplied by its weight, and the results are summed to produce the overall identity score.

### Current Weight Configuration

| Field       | Weight   |
| ----------- | -------- |
| **Name**    | 45%      |
| **DOB**     | 40%      |
| **SSN**     | 10%      |
| **Address** | 5%       |
| **Total**   | **100%** |

### Score Calculation

```
overall_score = (name_score × 0.45) + (dob_score × 0.40) + (ssn_score × 0.10) + (address_score × 0.05)
```

### Common Score Scenarios

| Available Fields              | Name | DOB | SSN | Address | Max Score |
| ----------------------------- | ---- | --- | --- | ------- | --------- |
| Name + DOB + SSN + Address    | 45%  | 40% | 10% | 5%      | **100%**  |
| Name + DOB + Address (no SSN) | 45%  | 40% | 0%  | 5%      | **90%**   |
| Name + DOB only               | 45%  | 40% | 0%  | 0%      | **85%**   |
| Name only                     | 45%  | 0%  | 0%  | 0%      | **45%**   |
| DOB only                      | 0%   | 40% | 0%  | 0%      | **40%**   |

***

## Identity Level Thresholds

The overall score maps to an identity level:

| Score Range          | Identity Level                                                     |
| -------------------- | ------------------------------------------------------------------ |
| `≤ −1`               | **Not Matching** — subject explicitly does not match the candidate |
| Below `0.7`          | **Not Enough Info** — insufficient data or weak match              |
| `0.7` to below `0.9` | **Medium** — moderate confidence in identity match                 |
| `0.9` and above      | **High** — strong confidence in identity match                     |

<Note>
  The qualifying threshold for `is_match` is **0.85** (`is_match: true` when `match_score >= 0.85`). A Name + DOB match with no SSN or address yields exactly `0.85` and qualifies as a positive match. This is separate from the `identity_level` label, which only reaches **High** at `0.9` and above.
</Note>

***

## Routing

Identity match results feed directly into charge-level routing. See [Routing & Queues](/api-reference/routing) for the full routing matrix and queue rollup logic.

***

## Examples

### High Match — Name + DOB + Address

```
Name Score:    45% (Weight: 45%) → Full name match
DOB Score:     40% (Weight: 40%) → Exact DOB match
SSN Score:      0% (Weight: 10%) → SSN empty on record
Address Score:  5% (Weight: 5%)  → Address match
Overall Score: 90% (Qualify: 85%)
Identity Level: High
is_match: true
```

### Medium Match — Name + DOB (no SSN, no address)

```
Name Score:    45% (Weight: 45%) → Full name match
DOB Score:     40% (Weight: 40%) → Exact DOB match
SSN Score:      0% (Weight: 10%) → SSN missing
Address Score:  0% (Weight: 5%)  → Address missing
Overall Score: 85% (Qualify: 85%)
Identity Level: Medium
is_match: true
```

### Weak Match — Different Person

```
Name Score:     0% (Weight: 45%) → Name does not match
DOB Score:     40% (Weight: 40%) → DOB matches (coincidence)
SSN Score:      0% (Weight: 10%) → SSN missing
Address Score:  0% (Weight: 5%)  → Address missing
Overall Score: 40% (Qualify: 85%)
Identity Level: Not Enough Info
is_match: false
```

***

## Related

* [Identity Match Endpoint](/api-reference/endpoints/identity-match) — API endpoint for standalone identity comparison
* [Routing & Queues](/api-reference/routing) — How identity level feeds into charge routing
* [Evaluate](/api-reference/endpoints/evaluate) — Full evaluation endpoint that includes identity matching
