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

# Return Data Model

> What we return after User Verification

<img src="https://mintcdn.com/hopae-a83466ba/87cF-Rmy7UVipV4A/images/returndata.png?fit=max&auto=format&n=87cF-Rmy7UVipV4A&q=85&s=722def57621b4962e6fb244fc78df804" alt="Return Data" width="2382" height="1648" data-path="images/returndata.png" />

## Overview

* Who is the user? → returned under `user`.
* How was this identity verified? → described by `provenance`.
* Did the user's claimed values match the source? → returned under `match` for match-capable providers.

## Verification models

The top-level `verification_model` field tells you which payload shape to read:

| `verification_model` | When                                                                                                          | Read from                       | `user`          |
| -------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------- | --------------- |
| `disclosure`         | The provider returned user attributes from an authoritative source. Default for all classic providers.        | `user.*` (PII) and `provenance` | object with PII |
| `match`              | The provider compared RP-submitted values against the authoritative source and returned only a match outcome. | `match.*` and `provenance`      | always `null`   |

`verification_model` is always present. Verifications created before this field existed default to `"disclosure"`. `provider_id` mirrors the single element in `amr` and is also always present.

For match-capable providers, `matchData` (the values the RP wants verified) must be supplied at session creation. The keys you submit appear back in `match.submitted_fields`. See [Create Verification](/api-reference/verifications/create-verification) (`matchData` body field) and [OIDC Authorization](/api-reference/oidc/auth) (`match_request` JWT param).

## What “Provenance” Means

Provenance explains the verification story — who vouched for the identity, how it was presented, and when it happened.

* Presentation
  * Channel: the route and transport (for example, `centralized_idp` over `internet`, `chip_based` via `nfc`, `wallet` over `internet`).
  * Credentials\[]: the documents or assertions that were presented (`type` is the provider identifier, alongside issuer details and raw upstream claims).
  * Evidence (when provided)
    * Evidence is included when the credential provides it; the object relays the upstream `token` payload and a semicolon-delimited `names` list describing the keys. Key names are provider-specific—always read them from `names`. Content is relayed from the credential source.
* Metadata
  * Verification identifiers and timestamps for audit and support (`verification_id`, `verified_at`).

### UserInfo Payload Structure

Here is a conceptual map of the UserInfo payload. This tree view shows how the data is organized, with a brief explanation for each major component. For detailed field specifications, refer to the Schema Tables that follow this section.

```jsonc theme={null}
{
  // --- Identity ---
  "sub": "...",                 // Subject identifier (stable per source identity)
  "provider_id": "smartid",     // Provider that authenticated the subject (mirrors amr[0])
  "amr": ["smartid"],
  "verification_model": "disclosure", // "disclosure" | "match" — always present
  "user": {                     // Personal attributes; null when verification_model is "match"
    "name": "...",
    "birthdate": "..."
  },

  // --- Assurance ---
  "acr": "...",
  "hopae_loa": 3,
  "hopae_loa_label": "substantial",
  "missing_claims": ["email", "address"],

  // --- Verification Story ---
  "provenance": {
    "presentation": {
      "channel": { "type": "...", "transport": "..." },
      "credentials": [
        {
          "type": "smartid",
          "issuer": { "id": "...", "authority_name": "...", "is_government": false },
          // `type` matches the providerId you supplied when creating the session; evidence keys vary per provider
          "evidence": {
            "token": {
              "<token_key>": "...",
              "<another_key>": "...",
              "...": "..."
            },
            "names": "<token_key>;<another_key>;..."
          }, // optional, may be absent
          "claims": { ... }
        }
      ]
    },
    "_metadata": { "verification_id": "...", "verified_at": "..." }
  },

  // --- Match (only when verification_model is "match") ---
  "match": {
    "matched": true,                          // aggregate outcome
    "granularity": "per_field",               // "per_field" | "aggregate"
    "submitted_fields": ["fullName", "dateOfBirth"], // RP-submitted matchData keys
    "details": {                              // present only when granularity is "per_field"
      "fullName":    { "matched": true, "submitted_value": "Test User" },
      "dateOfBirth": { "matched": true, "submitted_value": "1990-01-01" }
    }
  }
}
```

### Match payload example

A complete `/userinfo` response from a match-capable provider:

```json theme={null}
{
  "sub": "dZwCCSTLVMlJlXKTgSERCsApC7OUnBKT",
  "amr": ["id-nik-match"],
  "provider_id": "id-nik-match",
  "verification_model": "match",
  "hopae_loa": 1,
  "hopae_loa_label": "none",
  "missing_claims": [],
  "user": null,
  "provenance": {
    "presentation": {
      "channel": { "type": "centralized_idp", "transport": "internet" },
      "credentials": [
        {
          "type": "id-nik-match",
          "claims": {
            "fullName": true,
            "dateOfBirth": true,
            "nationalIdNo": true
          },
          "issuer": {
            "authority_name": "Directorate General of Population and Civil Registration (Dukcapil)",
            "is_government": true
          },
          "evidence": {
            "token": {
              "integrator_jws": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
              "token_type": "integrator"
            },
            "names": "integrator_jws;token_type"
          }
        }
      ]
    },
    "_metadata": {
      "verification_id": "f34e2801c3914b3284f2829ea48eeafc",
      "verified_at": "2026-04-26T15:56:11.110Z",
      "status": "completed"
    }
  },
  "match": {
    "matched": true,
    "granularity": "per_field",
    "submitted_fields": ["fullName", "dateOfBirth"],
    "details": {
      "fullName":    { "matched": true, "submitted_value": "Test User" },
      "dateOfBirth": { "matched": true, "submitted_value": "1990-01-01" }
    }
  }
}
```

<Note>
  For match providers, `provenance.presentation.credentials[].claims` carries the upstream IDP response verbatim — typically per-field confirmation from the source authority. This is the audit trail for what the source agreed with — it is not a duplicate of `match.details`.
</Note>

<Note>
  `details` may include keys that are not in `submitted_fields` when the upstream provider emits additional verifier results (e.g., a liveness signal alongside the demographic match outcome).
</Note>

## Related

* [Data Types — User](/guides/data-types/user)
* [Data Types — Provenance](/guides/data-types/provenance)
* [Level Of Assurance (LoA)](/guides/concepts/assurance)
* [OIDC UserInfo](/api-reference/oidc/userinfo)
* [REST UserInfo](/api-reference/verifications/get-verification-userinfo)

## Next Steps

<CardGroup cols={2}>
  <Card title="OIDC Provider" icon="id-card" href="/guides/concepts/oidc-provider">
    How OIDC fits into User Verification
  </Card>

  <Card title="Verification Flow" icon="diagram-project" href="/guides/concepts/verification-flow">
    Understand the end-to-end lifecycle
  </Card>
</CardGroup>
