> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.id.me/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.id.me/_mcp/server.

# Attribute matching

> Learn about attribute matching

The following guide offers a high-level overview of how an ID.me integration for attribute matching functions.

# Design overview

<Steps>
  <Step title="Policy setup">

   **a.** ID.me provides a public key for the encryption of the JSON Web Encryption (JWE) token

   **b.** Customer provides ID.me with the certificate used for signing which enables ID.me to validate the signature

  <Info>
  The ID.me policy will be configured to:
  - Require a JWE token on OAuth requests
  - Accept certain attributes in the JWE
  - Match on certain attributes in specific ways as defined by the customer
  </Info>

  </Step>

  <Step> 
    ID.me must receive a JWE in the request URL parameter within the initial *./oauth/authorize* call"
  

  <Error>
  If the JWE is invalid (e.g. missing, encryption, signature, payload), the user will be returned to the customer and presented with an error message
  </Error>
  </Step>

  <Step>
    The user will sign in and verify their properties
  </Step>
  <Step>
    ID.me will compare the attributes in the JWE with the user properties and store the matching results
  </Step>
  <Step>
    The user will be asked to consent to providing the customer with their:
    - Name
    - Date of birth
    - Other data (depending on configuration)
  </Step>

  <Step>
    ID.me will issue an *access_token*

    <Warning>
      If there is a mismatch, ID.me will prevent the user from continuing the flow
    </Warning>
  </Step>

  <Step>
    Customer will use the *access_token* to request attributes of the user

    <Error>
    Customers will **not** receive a payload if there is a mismatch due to ID.me preventing the user from completing the flow
    </Error>
  </Step>
</Steps>

# JWE

Customers send matching attributes as a JWE object in the initial OAuth request.

## Payload

Attribute keys in the payload are configured during integration setup.
The payload contains the attribute keys and values (in JSON) that will be used for matching.

**`Key / value pair example`**

```json title="Key / value pair example"
{
  “first_name”: “John”, 
  “last_name”: “Doe”
}
```

**`Good match example`**

```json title="Good match example"
    {
      "handle": "attributes_match",
      "name": "Verified attributes match requested attributes",
      "value": true
    }
```

## Creation

The JWE will be created by:

<Steps>
  <Step>
    Signing the payload to create a JWS
  </Step>
  <Step>
    Encrypting the JWS using the public key provided by ID.me
  </Step>
</Steps>

When decrypted, the JWE will contain a JWS with a valid signature that can be verified by the public certificate provided by the customer.

**`JWE`**

```txt title="JWE" wordWrap
eyJraWQiOiJBYWNSMjZ2RkdWeVFlajFzU3NMcTFCLTVBQTBSa1NfN2xqUGZ0ZURoWlNFIiwiY3R5IjoiSldUIiwiYWxnIjoiUlNBLU9BRVAiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIn0.s2dgRUICmkTnqSONQxJjXRbUnPxtXEDl_VVI0iv-Kxn2L9R3kir0Prk8tAmwDkHv-M-3gTq4yEv1VRQWsfbiWn9EOjO6C24buLMEyJ1Jx2lUu-KTdMxRI2VbuuyruDYKI7eAp9Xld2icrzGmeHMNjiZ1_jnK5GGe1WfVDWlMh68bNQcN6IT0md6TJWUoP5xxDu_C0SJd_XinSm-WJ2MUPiM_Lcub53o8rJpudEhad7MQXqO16-8M-2mInLiblAs_M17uFYZYp26jq51m0co_LZS9sS0Pe31yzpBq3G51KwGevjN19AuyygXHVY352QzrT0L6__t8o1dhXAa9N1AWCg.H0X_ib45DZbV9iWBJZGrKg.bTXAYJwynvqpFGuckhd5z7VpPsmNJoL9PMC1lY0EVFLaoy3beHVRMm2l5_oMfwzhiR4OocCJfOIwNwoKSP96fIXbHRLOX9lfusMKT7wZGvOr0eLtkr1dULuoDk-P6_9joDZNfn1DhN_nTsQ9k4DVum2r_lPtWnl_Txie1yip-NMLfFTvGP_6ukj4b0U-qMK3NNb2vPwaPPL-ztrcZP2tEQjn8XIoahp0g2Lx7jp4DcvwHxJOA9XGKaAORTd50Wb_YyAPluEUo_d1arigA0_H3th5JHx1QEIvUm1UNSahxOGDc0qSdvOhFNihN7LPzKrMVePyjufb4q202Xu5jJV5BL9X0djPausnRO0jmw5waM47mW1Ohlg9KbNmjHDGwwdSXP8EJD0M3riRRocdEPL-E56mvlRrcaBoVD-AzamU7CbDdMjDxOHjBebnM0da84JtP5L4v-javZkzeIWfdHXxRasB34ijtKIG7nVG1Bv-frbrhwWOV-yiS0dHEJKAZ1jjQXVTnCqP7GFFxccwyvzW9r-jvK_u4kwVz-SdiBedi3ICy8RCPy2clOcgx6aUiRq6Z0B45Gqemoibr_Vo22w-IkvUaXeFkDYtiKHsFRdAWeMFtN0JgYtIjPJ2JEdEj8_00LXfYxvmKxrO-Gr_xSGW9JAa4joZY_kHyJQd0RIkpF-Jx2di35wdZcrk0dFPvCKENbbbgRkMDLHLx84PE1eSqw.vQ7lscwflpLwcaPeX-OiD9nVEyNxHxJKJtC4WHm3gdo
```

**`Decrypted payload (JWS)`**

```txt title="Decrypted payload (JWS)" wordWrap
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkpPYkJGakozSjNOejdkMHlpWGhLbXotMThyMGlWeXJtUnhDc0ZRTWhWU1UifQ.eyJmbmFtZSI6IlRlc3RGaXJzdCIsImxuYW1lIjoiVGVzdExhc3QiLCJiaXJ0aF9kYXRlIjoiMjAwMC0wMS0wMSJ9.4eu1GukTXbpOJ1lpwSyzZ_SFQwHi4e5xV_S5Hpzoju1Cc81_VxkjNF1eAC5Z7c-8o3qslDou5h36up2iBIrgJPU9hPPMMalReTqRJYDSgSw9EItCxl8dN0OCfHHE61zXz5QDDit-6syB1lb9qsB5bZU-H8_EB--bxbQom9HjdcVdrOiBbFy_IcH_5leGZy8aVoh5Cz9xITewsFcSJuKN-DZ0WQuGswMmimi0jGQxeXiDLqegGFMNjQKeGny6bGX7kzJ1WM8gvIx43Ugr0Nn8Bup7O4SIFR8PyeucADQYXQga1cHOGMyLYZTSv4V2VPRf25ManTonqMyUpWKGpJ0xKL0
```

The above contains the following JSON payload:

```json
{"fname"=>"TestFirst", "lname"=>"TestLast", "birth_date"=>"2000-01-01"}
```

Decoding the JWE/JWS using code or another tool will show the parameters used in this example.

# Attribute matching logic

ID.me uses two well-established algorithms which are used by software systems to compare two strings for matching purposes.

## Jaro-Winkler

The Jaro-Winkler distance algorithm to compare text values, such as names, and determine whether they are likely a match.

### How it works

- Compares two strings and measures similarity based on matching characters and order
- Gives more weight to characters at the start of the string (useful for names where typos or variations occur)
- Returns a score between 0 (no similarity) and 1 (exact match)

### Our matching rules

- Score > 0.8 → treated as a match
- Score < 0.8 → treated as a mismatch

<Note>
  Match scores can be configured per policy and attribute, so if you want to set a threshold higher or lower than the standard configuration, that can be supported
</Note>

**`Example`**

```txt title="Example"
Bob Adam <-> Robert Adams
```

- Jaro-Winkler score: **0.819 (81.9%)**
- Result: **Match**

## NYSIIS

The NYSIIS algorithm (New York State Identification and Intelligence System) to match names that sound alike but may be spelled differently.

### How it works

- Converts a name into a **phonetic code**
- Applies a set of transformation rules to letters and letter groups
- Produces a simplified, standardized representation of the name’s pronunciation

### Why it's useful

- Matches names that have multiple valid spellings
- Handles variations due to spelling conventions or regional accents
- Makes it easier to compare names based on sound instead of spelling

**`Example`**

```txt title="Example"
"Ashley" <-> "Ashleigh"
"Phoebe" <-> "Febe"
```

- Both pairs are reduced to the same phonetic code
- Result: **Match**