Skip to main content

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

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_modelWhenRead fromuser
disclosureThe provider returned user attributes from an authoritative source. Default for all classic providers.user.* (PII) and provenanceobject with PII
matchThe provider compared RP-submitted values against the authoritative source and returned only a match outcome.match.* and provenancealways 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 (matchData body field) and OIDC Authorization (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.
{
  // --- 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:
{
  "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" }
    }
  }
}
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.
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).

Next Steps

OIDC Provider

How OIDC fits into User Verification

Verification Flow

Understand the end-to-end lifecycle