OIDC claims
Every standard and custom claim VEREID Auth emits in the id_token and userinfo response — including the killer vereid_verification claim.
Last updated 2026-05-20
VEREID Auth emits a strict superset of OpenID Connect Core 1.0 claims. This page documents every claim you can request, the scopes that gate them, and the wire shape of our headline custom claim: vereid_verification.
Standard claims
These follow the OpenID Connect Core spec exactly. We do not redefine semantics — if it is here, it means what the spec says it means.
| Scope | Claim | Type | Notes |
|---|---|---|---|
openid | sub | string | Stable, opaque, never reassigned. |
openid | iss | string | Always https://auth.vereid.com. |
openid | aud | string | Your client_id. |
openid | iat, exp, nbf | number | Unix seconds. |
openid | auth_time | number | When the user actually authenticated. |
openid | nonce | string | Reflected from /authorize. |
openid | acr, amr | string / array | Authentication context + methods. |
email | email, email_verified | string / bool | |
profile | name, preferred_username, picture, locale, updated_at | various | |
phone | phone_number, phone_number_verified | string / bool | |
address | address | object | RFC-compliant address object. |
Custom claim: vereid_verification
Requesting the scope vereid:verification adds a single, well-typed claim to both the id_token and the userinfo response. This is the differentiator that makes "Login with VEREID" valuable even for apps that don't otherwise care about the social graph.
{
"vereid_verification": {
"tier": "T2",
"badges": ["photo", "liveness"],
"issued_at": "2026-05-18T03:14:02Z",
"issued_by": "vereid",
"scheme": "https://docs.vereid.com/concepts/verification-tiers"
}
}Field reference
| Field | Type | Meaning |
|---|---|---|
tier | enum: T0–T6 | Highest contiguous tier the user has unlocked. Read Verification tiers for what each value actually proves. |
badges | string[] | The unordered set of unlocked badges. Allowed values: photo, liveness, sanctions_clear, business, chip, gov_record:<iso2>. |
issued_at | string (ISO 8601) | When this tier was last refreshed. Tiers can downgrade if a sanctions feed adds the user, in which case issued_at updates. |
issued_by | string | Always vereid today. Reserved for federation. |
scheme | string | Stable URL to the human-readable tier scheme. Pin this in your trust policy so you know exactly which version of the ladder you are reading. |
What you must not do
- Do not treat
tieras a numeric trust score. Use thebadgesarray. - Do not display "government-verified" UI based on T1–T5. Only
gov_record:<iso2>inbadgespermits that copy, and only for the country whose code appears in the suffix. - Do not cache the claim longer than the
id_tokenlifetime. Re-request a freshuserinfoif you need an authoritative read.
Requesting custom claims
Add the scope to your /authorize call:
scope=openid email profile vereid:verificationYou can also request the claim via the claims parameter for finer-grained control:
{
"id_token": {
"vereid_verification": { "essential": true }
}
}If you mark it essential and the user has no verification record at all, the auth server returns error=interaction_required with a hint URL to the verification flow. Your app can then redirect the user to id.vereid.com and resume the OIDC handshake when they return.
Address and phone
Both behave as defined in OpenID Core. We additionally surface a phone_number_country claim if the user has a verified phone — useful for jurisdictional routing without parsing the raw E.164 string.
SAML and the verification attribute
For SAML 2.0 federation, the same data is exposed as a single XML attribute named urn:vereid:verification containing the JSON document above as a base64-encoded value. See the SAML setup guide for the assertion XPath your IdP-side service expects.
Validation pseudocode
function trustsAtLeast(payload, requiredBadges) {
const have = new Set(payload.vereid_verification?.badges ?? []);
return requiredBadges.every((b) => have.has(b));
}
if (!trustsAtLeast(payload, ["photo", "liveness"])) {
return res.redirect("/upgrade?tier=T2");
}The badges array is canonical — it is not the same as tier. A user can hold the chip badge without holding liveness (chip-auth uses photo-only). Always check the badge you actually need.