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

# UserInfo

> Returns user claims based on granted scopes. Requires a valid Bearer access token.

Fetch verified user claims using the access token from `/token`.

<Info>
  The ID Token contains no PII. All personal attributes are returned only by `/userinfo`.
  Unsupported (requested) standard claims are listed in `missing_claims`.
  Verification context is provided in `provenance`. Evidence is included when the credential source returns it; the object contains a `token` payload and a semicolon‑delimited `names` list describing the keys. Keys vary by provider, so always read them from `names`. Content is relayed from the credential source.
</Info>

## Headers

<ParamField header="Authorization" type="string" required default="Bearer eyJhbGci...">
  Bearer access token issued by `/token`.
</ParamField>

## Responses

<ResponseField name="sub" type="string" required>
  Subject identifier. Stable per source identity across all clients.
</ResponseField>

<ResponseField name="acr" type="string">
  Authentication Context Class Reference.
</ResponseField>

<ResponseField name="hopae_loa" type="number">
  Numeric assurance level.
</ResponseField>

<ResponseField name="hopae_loa_label" type="string">
  Human‑readable assurance label (e.g., `substantial`).
</ResponseField>

<ResponseField name="missing_claims" type="string[]">
  Requested standard claims not provided by the source. Always `[]` for match flows (`verification_model: "match"`).
</ResponseField>

<ResponseField name="provider_id" type="string">
  Provider identifier that authenticated the subject. Mirrors the single element in `amr`.
</ResponseField>

<ResponseField name="verification_model" type="string">
  Always present. One of `disclosure` (PII under `user`) or `match` (comparison envelope under `match`, with `user: null`).
</ResponseField>

<ResponseField name="user" type="object | null">
  Personal attributes (present per granted scopes and source availability). `null` when `verification_model` is `match`.

  <Expandable title="User fields">
    <ResponseField name="name" type="string">
      Display name
    </ResponseField>

    <ResponseField name="given_name" type="string">
      Given nam
    </ResponseField>

    <ResponseField name="family_name" type="string">
      Family name
    </ResponseField>

    <ResponseField name="birthdate" type="string">
      Birthdate in `YYYY-MM-DD`
    </ResponseField>

    <ResponseField name="email" type="string">
      Email address
    </ResponseField>

    <ResponseField name="email_verified" type="boolean">
      Whether the email is verified
    </ResponseField>

    <ResponseField name="phone_number" type="string">
      Phone number in E.164 format
    </ResponseField>

    <ResponseField name="phone_number_verified" type="boolean">
      Whether the phone number is verified
    </ResponseField>

    <ResponseField name="address" type="object | string">
      Structured address
    </ResponseField>

    <ResponseField name="nationality" type="string">
      ISO 3166-1 alpha‑2.
    </ResponseField>

    <ResponseField name="middle_name" type="string">
      Middle name(s)
    </ResponseField>

    <ResponseField name="nickname" type="string">
      Casual name or handle
    </ResponseField>

    <ResponseField name="preferred_username" type="string">
      Preferred username
    </ResponseField>

    <ResponseField name="profile" type="string">
      URL of the user's profile page
    </ResponseField>

    <ResponseField name="picture" type="string">
      Base64-encoded image data of the user's profile picture
    </ResponseField>

    <ResponseField name="gender" type="string">
      Gender value
    </ResponseField>

    <ResponseField name="zoneinfo" type="string">
      Time zone (IANA)
    </ResponseField>

    <ResponseField name="locale" type="string">
      Locale (BCP 47)
    </ResponseField>

    <ResponseField name="updated_at" type="number">
      Unix timestamp of last profile update
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="provenance" type="object">
  Verification context for this event.

  <Expandable title="Presentation">
    <ResponseField name="provenance.presentation.channel.type" type="string">`centralized_idp`, `wallet`, etc.</ResponseField>
    <ResponseField name="provenance.presentation.channel.transport" type="string">`internet`, `nfc`, etc.</ResponseField>
    <ResponseField name="provenance.presentation.credentials[]" type="array">Credentials presented for this verification.</ResponseField>
    <ResponseField name="provenance.presentation.credentials[].type" type="string">Provider identifier used when initiating the verification (for example, `smartid`).</ResponseField>
    <ResponseField name="provenance.presentation.credentials[].issuer.id" type="string">Issuer identifier.</ResponseField>
    <ResponseField name="provenance.presentation.credentials[].issuer.authority_name" type="string">Issuer display name.</ResponseField>
    <ResponseField name="provenance.presentation.credentials[].issuer.is_government" type="boolean">Government authority flag.</ResponseField>
    <ResponseField name="provenance.presentation.credentials[].claims" type="object">Raw source claims, when available.</ResponseField>
    <ResponseField name="provenance.presentation.credentials[].evidence" type="object">Token evidence object from the source (when provided). Includes `token` (provider-supplied key/value pairs) and `names` (semicolon-delimited list of keys present under `token`).</ResponseField>
  </Expandable>

  <Expandable title="Metadata">
    <ResponseField name="provenance._metadata.verification_id" type="string">Verification session id.</ResponseField>
    <ResponseField name="provenance._metadata.verified_at" type="string">ISO 8601 verification timestamp.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="match" type="object">
  Match envelope. Present only when `verification_model` is `match`.

  <Expandable title="Match fields">
    <ResponseField name="match.matched" type="boolean">Aggregate outcome across all submitted fields.</ResponseField>
    <ResponseField name="match.granularity" type="string">`per_field` or `aggregate`. Determines whether `details` is included.</ResponseField>
    <ResponseField name="match.submitted_fields" type="string[]">Field keys the RP submitted via `matchData`. Provider-native names — not OIDC-normalised.</ResponseField>
    <ResponseField name="match.details" type="object">Per-field outcomes, keyed by field name. Present only when `granularity` is `per_field`. Each entry exposes `matched` (boolean), `submitted_value` (RP-supplied value, userinfo only and only on matchData fields), and optionally `similarity` (0–100) when the upstream verifier provides it. May also carry passthrough verifier keys not in `submitted_fields` when the upstream provider emits them.</ResponseField>
  </Expandable>
</ResponseField>

## Example

<RequestExample>
  ```bash theme={null}
  curl -X GET 'https://sandbox.connect.hopae.com/userinfo' \
    -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...'
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "sub": "otV9EMJr-iG-dj-AHhrCslfdRkUUBQJ1",
    "hopae_loa": 3,
    "hopae_loa_label": "substantial",
    "missing_claims": [
      "email",
      "gender",
      "picture"
    ],
    "user": {
      "birthdate": "1905-04-04",
      "given_name": "OK",
      "family_name": "TESTNUMBER",
      "nationality": "LT",
      "name": "OK TESTNUMBER"
    },
    "provenance": {
      "presentation": {
        "channel": {
          "type": "centralized_idp",
          "transport": "internet"
        },
        "credentials": [
          {
            "type": "smartid",
            "issuer": {
              "id": "urn:hopae:issuer:ee:smartid",
              "authority_name": "SK ID Solutions AS",
              "is_government": false
            },
            "claims": {
              "documentNumber": "PNOLT-40504040001-MOCK-Q",
              "birthdate": "1905-04-04",
              "countryCode": "LT",
              "givenName": "OK",
              "surname": "TESTNUMBER"
            },
            "evidence": {
              "token": {
                "id_token": "<BASE64_ID_TOKEN>",
                "expires_at": "2025-10-31T05:43:14.000Z",
                "access_token": "<OPAQUE_ACCESS_TOKEN>",
                "token_type": "Bearer"
              },
              "names": "id_token;expires_at;access_token;token_type"
            }
          }
        ]
      },
      "_metadata": {
        "verification_id": "3162dd47a26b4218b5fa708761889e44",
        "verified_at": "2025-10-28T06:20:36.992Z"
      }
    }
  }
  ```
</ResponseExample>

<ResponseExample>
  ```json Match flow 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" }
      }
    }
  }
  ```
</ResponseExample>

<Note>
  Evidence keys are provider-specific. Inspect `names` to determine which fields are present under `evidence.token`.
</Note>

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