> 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.

# Pre-verified events

> The verification_status resource delivered on the session.verification_status user verification event.

`session.verification_status` carries a `verification_status` on `event.object`: what IDMe already knows about the user at the moment they arrive. It is emitted after login or signup and before multifactor authentication, so you can tell early in the flow whether the user already holds the identity credential your policy requires, whether they have been to your application before, and whether they are brand new to IDMe.

See [User verification events](/shared-signals-framework/user-verification-events) for the delivery envelope and the fields every event carries.

# The verification status resource

| Field                        | Type              | Description                                                                                                                                                                                                                                                    |
| ---------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `is_existing_wallet`         | boolean           | Whether the user's IDMe wallet existed before this session. `true` for a returning user, `false` for a user who just signed up.                                                                                                                                |
| `is_preverified_for_policy`  | boolean           | Whether the wallet holds a verified identity credential right now. `true` when the user is already pre-verified for the requesting policy, `false` when they do not yet hold the level it requires.                                                            |
| `credential_option`          | nullable string   | How the user obtained their IAL2 credential. See [Credential options](#credential-options). `null` when the wallet holds no credential.                                                                                                                        |
| `credential_ial_highest`     | nullable string   | The highest identity assurance level the wallet holds. `1` for KBA, KYC, or Fortified Identity; `2` for IAL2; `classic_loa3` for LOA3 without a selfie. `null` when the wallet holds no credential.                                                            |
| `credential_expiration_date` | nullable datetime | When the held credential expires, in ISO 8601 format. Most relevant to community credentials such as student status, and to credentials that require an annual network renewal. `null` when the credential does not expire, or the wallet holds no credential. |
| `level_of_assurance`         | nullable integer  | The level of assurance the wallet holds. IAL2 is level `3`. `null` when the wallet holds no credential.                                                                                                                                                        |
| `identity_subgroups`         | array of strings  | Every identity subgroup the user holds. Use it to recognize step-up scenarios, such as a user who has already completed KYC. See [Identity subgroups](#identity-subgroups). Empty when the wallet holds none.                                                  |
| `previously_accessed`        | boolean           | Whether the user has accessed this policy and this application before, not merely IDMe generally.                                                                                                                                                              |
| `previously_accessed_at`     | nullable datetime | When the user last accessed this policy and this application, in ISO 8601 format. `null` when they never have.                                                                                                                                                 |
| `credentialed_at`            | nullable datetime | When the held credential was granted, in ISO 8601 format. `null` when the wallet holds no credential.                                                                                                                                                          |

## Credential options

`credential_option` names the path the user took to their IAL2 credential:

`Document`, `License`, `Passcard`, `Passport`, `In-person Verification`, `Trusted Referee`, `Trusted Referee v2`, or `Upgrade IAL2 Selfie`.

## Identity subgroups

`identity_subgroups` lists every subgroup the user holds, drawn from:

`IAL2`, `LOA3`, `KYC`, `Fortified`, and `KBA-R`.

> **Note**
>
> Values are echoed exactly as IDMe stores them, with no code or enum translation, so new credential options, assurance levels, and identity subgroups appear here without a breaking change. Every field is always present: a user who holds no identity credential gets `null` for the credential fields rather than a missing key.

# Example payload

**`session.verification_status`**

```json session.verification_status
{
  "host": "events.idmelabs.com",
  "source": "idme:dev",
  "sourcetype": "idme:auth",
  "event": {
    "event_id": "5a1c8e3d-9f47-4b62-8d05-1e6a2c7f4b93",
    "event": "session.verification_status",
    "uuid": "c3850702f02f4f948cede41610c2a715",
    "user_email": "xbzi.gqcv@gmail.com",
    "application_name": "Auth Portal",
    "ipaddress": "55.55.55.55",
    "device_fingerprint": "lu2pFqAQyLIr0MqVpDEV",
    "useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
    "created_at": "2026-07-04T13:11:58.204617Z",
    "eid": null,
    "app_id": null,
    "state": null,
    "object": {
      "is_existing_wallet": true,
      "is_preverified_for_policy": true,
      "credential_option": "Passport",
      "credential_ial_highest": "2",
      "credential_expiration_date": "2027-01-31T00:00:00.000Z",
      "level_of_assurance": 3,
      "identity_subgroups": ["IAL2", "Fortified"],
      "previously_accessed": true,
      "previously_accessed_at": "2026-08-01T12:00:00.000Z",
      "credentialed_at": "2025-05-05T09:30:00.000Z"
    }
  }
}
```

A user who is new to IDMe and holds no credential yet:

**`session.verification_status`**

```json session.verification_status
{
  "host": "events.idmelabs.com",
  "source": "idme:dev",
  "sourcetype": "idme:auth",
  "event": {
    "event_id": "e0c4b82f-71a9-4d36-b5f8-9c204ae71d63",
    "event": "session.verification_status",
    "uuid": "7b1f4a90de234c0b9f6c8e2a5d41738c",
    "user_email": "kvto.mpqz@gmail.com",
    "application_name": "Auth Portal",
    "ipaddress": "55.55.55.55",
    "device_fingerprint": "Rq8tZmW3oPbK1nVxYcEu",
    "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
    "created_at": "2026-07-04T13:15:07.884213Z",
    "eid": null,
    "app_id": null,
    "state": null,
    "object": {
      "is_existing_wallet": false,
      "is_preverified_for_policy": false,
      "credential_option": null,
      "credential_ial_highest": null,
      "credential_expiration_date": null,
      "level_of_assurance": null,
      "identity_subgroups": [],
      "previously_accessed": false,
      "previously_accessed_at": null,
      "credentialed_at": null
    }
  }
}
```

> **Warning**
>
> New fields may be added to the verification status resource without a breaking change. Ignore fields you do not recognize rather than rejecting the payload.