Nexiel Credentials for employers

This page is for an employer, background-check provider, or another institution verifying an academic credential a candidate holds in their EU Digital Identity (EUDI) wallet: an awarded degree, or proof that someone is still enrolled and studying. It covers how a verification session works, what a Nexiel-vetted credential proves, and how the disclosed academic facts reach your own systems. For what a Nexiel-issued credential is and how an institution gets vetted before it can issue one, read how credential issuance works first if you have not already. If you are the institution issuing credentials rather than verifying them, see Nexiel Credentials for universities.

Not yet live in production. compliance.nexiel.io is not serving /v1/credentials/verify/* yet. Every request and response below is real, executed against a sandbox-mode instance seeded with an approved example institution, so you can see the exact shape you will integrate against. Run your own instance locally to try these same requests today.

What you can verify

Two check types exist today. academic-credential confirms an already-awarded degree or qualification and discloses the institution, degree title, ECTS (European Credit Transfer and Accumulation System) credit total, EQF (European Qualifications Framework) level, and award date. academic-enrolment-status confirms a candidate is currently enrolled, useful for an internship or placement decision, and discloses the institution, enrolment status, programme name, and expected completion date instead.

Neither check type discloses the candidate's name, date of birth, or any other identity field as part of the verification. Correlating the credential to the specific candidate you are checking, since you already know who you invited to complete the verification, is your own process, not a claim this API returns.

Before you can verify anything: an API key

Verifying requires a credentials-api-verifier-scoped API key, gated by the same KYB (Know Your Business) approval a Nexiel Verify or Nexiel Screen customer needs today. This key is structurally separate from the key an issuing institution holds. A leaked employer key can never be used to submit or approve a credential batch, and an issuing institution's own key can never read your verification sessions.

There is no self-serve dashboard workflow for requesting this key yet. Once your organization's KYB status is APPROVED, Nexiel issues the key directly.

How a verification session works

The flow reuses the same OpenID4VP (OpenID for Verifiable Presentations) session pattern every other Nexiel wallet check already uses: your backend creates a session, the candidate's wallet resolves it and discloses the requested claims, and your backend reads the result back. A session expires 10 minutes after creation if nobody responds.

1. Create a session

curl -s -X POST https://compliance.nexiel.io/v1/credentials/verify/sessions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <verifier_access_token>" \
  -d '{"checkType": "academic-credential"}'
200
{
  "sessionId": "e2f4a8b1-9c3d-4e6a-8f21-5b7d3c9a1f04",
  "templateVersion": "academic-credential@1",
  "authorizationRequest": {
    "client_id": "https://verify.nexiel.eu",
    "response_type": "vp_token",
    "response_mode": "direct_post",
    "response_uri": "https://compliance.nexiel.io/v1/credentials/verify/sessions/e2f4a8b1-9c3d-4e6a-8f21-5b7d3c9a1f04/responses",
    "dcql_query": {
      "credentials": [
        {
          "id": "nexiel_academic_credential",
          "format": "dc+sd-jwt",
          "meta": {
            "vct_values": [
              "urn:nexiel:credential:degree-award:v1"
            ]
          },
          "claims": [
            {
              "path": [
                "institution"
              ]
            },
            {
              "path": [
                "degree_title"
              ]
            },
            {
              "path": [
                "ects_credits"
              ]
            },
            {
              "path": [
                "eqf_level"
              ]
            },
            {
              "path": [
                "award_date"
              ]
            }
          ]
        }
      ]
    },
    "nonce": "xk3Rb9mQeUfL2yZaVc7pNdT4wHsJ8gAo1iBnE0lYqOr",
    "state": "q6Vn2Kd8mXs1RtLc9UbAeYw4ZoGpDfNjHi3JlOvQx7T"
  },
  "authorizationRequestUri": "openid4vp://authorize?client_id=https%3A%2F%2Fverify.nexiel.eu&response_type=vp_token&...(truncated)",
  "expiresAt": "2026-08-25T14:12:11.203Z"
}

Show authorizationRequestUrito the candidate as a QR code or, on a mobile device the candidate is already using, as a tappable link. Nexiel's @nexiel/credentials-widget package renders this step and the polling below for you, so you do not have to build the QR code and poll loop by hand.

2. The candidate's wallet responds

The wallet discloses the requested claims and posts the presentation directly to response_uri. This step happens between the candidate's wallet and Nexiel. Your backend is not involved and receives nothing at this point:

200, returned to the wallet, not to your backend
{
  "sessionId": "e2f4a8b1-9c3d-4e6a-8f21-5b7d3c9a1f04",
  "method": "eudi_wallet",
  "booleanProofs": {
    "claimsVerified": true
  },
  "academicIssuerId": "7a6dfd13-15ed-4e44-9721-6e60f1369a1a",
  "disclosedClaimsDelivered": true
}

disclosedClaimsDelivered reports whether an encrypted claims pack was generated for this decision, which depends on whether your organization has an active evidence-pack key registered (see below). It is false when no key is registered. The verification itself still completes normally either way.

3. Read the result

Poll GET /v1/credentials/verify/sessions/{sessionId} from your own backend. This is the real delivery channel for the disclosed claims, not the wallet callback above:

curl -s https://compliance.nexiel.io/v1/credentials/verify/sessions/e2f4a8b1-9c3d-4e6a-8f21-5b7d3c9a1f04 \
  -H "Authorization: Bearer <verifier_access_token>"
200
{
  "sessionId": "e2f4a8b1-9c3d-4e6a-8f21-5b7d3c9a1f04",
  "clientId": "docs-example-employer",
  "checkType": "academic-credential",
  "templateVersion": "academic-credential@1",
  "status": "completed",
  "createdAt": "2026-08-25T14:02:11.203Z",
  "expiresAt": "2026-08-25T14:12:11.203Z",
  "decision": {
    "issuer": {
      "academicIssuerId": "7a6dfd13-15ed-4e44-9721-6e60f1369a1a",
      "verifiedDomain": "sandbox-university.nexiel-docs.example",
      "vettingStatus": "nexiel_vetted_eaa",
      "legalWeightNotice": "This credential is a non-qualified Electronic Attestation of Attributes (EAA). Its issuing institution was vetted through Nexiel's own institution-accreditation review, not through a qualified trust service provider -- it does not carry eIDAS 2.0's qualified legal presumption of accuracy. Treat it as strong, verified evidence from a vetted source, and apply your own organization's usual corroboration standard for a non-qualified attestation."
    },
    "disclosedClaims": "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSJ9..(truncated)",
    "disclosedClaimsHash": "4f9c2e7b1a8d3f6045b1c9d7e2a4f8b3c6d9e1f5a7b2c4d8e6f1a3b9c5d7e2f0",
    "revocationStatus": "status_check_unavailable",
    "revocationCheckedAt": "2026-08-25T14:03:47.912Z",
    "frozenVerificationArtifact": {
      "templateVersion": "academic-credential@1",
      "academicIssuerId": "7a6dfd13-15ed-4e44-9721-6e60f1369a1a",
      "issuerVerifiedDomain": "sandbox-university.nexiel-docs.example",
      "kid": "docs-example-key-1",
      "vettingStatus": "nexiel_vetted_eaa",
      "vpTokenHash": "b7a2f1e4c9d83a56f0e17c2b6d4a9f83e1c5b7a2f9e4d8c1b6a3f7e2d5c9b8a4",
      "disclosedClaimsHash": "4f9c2e7b1a8d3f6045b1c9d7e2a4f8b3c6d9e1f5a7b2c4d8e6f1a3b9c5d7e2f0",
      "verifiedAt": "2026-08-25T14:03:47.912Z"
    },
    "decidedAt": "2026-08-25T14:03:47.912Z"
  }
}

Naming a sessionId that exists but belongs to a different employer returns the same 404 an unknown id would, never a 403 that would confirm it exists. Add ?claimsDelivery=peekto inspect a session's status without consuming its one-time claims delivery, covered next. GET /v1/credentials/verify/sessions lists your organization's own sessions the same way, without triggering the live revocation check or consuming any delivery.

What nexiel_vetted_eaa and qeaa mean

Every credential Nexiel issues today comes back as nexiel_vetted_eaa. This is a real legal distinction, not a technicality to skim past. A QEAA (Qualified Electronic Attestation of Attributes) is issued by a qualified trust service provider under formal EU supervision and sits on an EU-wide eIDAS Trusted List, giving it eIDAS 2.0's strongest, most portable legal presumption of accuracy. A Nexiel-vetted EAA (Electronic Attestation of Attributes) does not carry that presumption. It rests on Nexiel's own institution-vetting review instead, described on how credential issuance works.

legalWeightNotice in the response above is the exact sentence your compliance or legal team should read for this. It is fixed per vettingStatus and never varies with what was disclosed. Treat a Nexiel-vetted EAA as strong, verified evidence from an institution that passed real vetting, and apply whatever corroboration standard your own organization already uses for a non-qualified attestation. The qeaavalue exists in the response shape for a QTSP-backed issuance path Nexiel's signing layer is built to support later. It is not reachable from any credential Nexiel issues today.

This is a screening and verification result, not legal advice, and using it does not itself discharge whatever due diligence obligation your own organization has for this hire or decision. See the legal disclaimer.

Claims delivered once, then purged

disclosedClaims is a JWE (JSON Web Encryption) ciphertext, encrypted to a public key your organization registers and controls. Nexiel generates the key pair for nothing, holds no copy of your private key, and cannot decrypt this value itself. This reuses the exact same client-side key registration flow Nexiel Verify and Nexiel Screen already use for their own evidence packs. See setting up evidence pack encryption for how to generate and register a key from your dashboard. A key registered for that purpose already works here too, since registration is not tied to one specific product.

Decrypted, the claims pack holds the check type, the decision timestamp, and the disclosed claim values themselves, for example:

Decrypted disclosedClaims payload
{
  "method": "academic-credential",
  "timestamp": "2026-08-25T14:03:47.912Z",
  "disclosedClaims": {
    "institution": "Nexiel Sandbox University",
    "degree_title": "BSc Computer Science",
    "ects_credits": 180,
    "eqf_level": 6,
    "award_date": "2026-06-15"
  }
}

The ciphertext is delivered exactly once: the first GET request that returns it consumes that delivery, and every later request, including a retry, gets null there instead. It is also purged automatically 7 days after the decision was made if nobody ever fetches it. disclosedClaimsHash is permanent and survives that purge either way, whether or not you ever registered a key: it is a SHA-256 (Secure Hash Algorithm 256-bit) digest proving exactly which claim values were disclosed and verified, without revealing them itself.

Without a registered key, Nexiel has nothing to encrypt to, so disclosedClaims is always null for that decision. The verification itself still completes and is still recorded. Only the delivery of the actual claim values depends on a key being registered.

Revocation status: what is checked today

The response distinguishes two different guarantees on purpose. frozenVerificationArtifact is permanent: it records who signed the credential, what was verified, and when, exactly as it was at the moment of verification, and never changes afterward. revocationStatus is the opposite: it is re-checked live on every single GET request to a specific session, never cached, and answers whether the credential is still valid right now rather than whether it was validly presented at the time.

A live check depends on the issuing institution publishing a status list Nexiel can query. No real institution does that yet, so status_check_unavailable is the honest, expected answer for a real verification today, not a fallback edge case. An institution with no published status list returns status_check_unavailable, never a silently reassuring current. The mechanism itself is real and already built: Nexiel fetches and reads a real Status List Token (RFC 9901) whenever one exists, and reports back revoked or suspended the moment that list says so.

What gets persisted

Polling, webhooks, and the embeddable widget

Polling GET /v1/credentials/verify/sessions/{sessionId} works for any integration. If you would rather be notified than poll, Nexiel also fires webhook events: credentials.verification.completed and credentials.verification.failed when a session finishes, and credentials.credential.status_changed when a live revocation re-check observes a change from whatever was last seen. Every webhook payload carries metadata only, session id, check type, and status fields, never disclosedClaims, the same discipline every other Nexiel webhook event follows. See advanced guides for how webhook signing and retries work.

@nexiel/credentials-widget wraps the session-create and poll steps above into a drop-in embed, either a script tag or a React component, so you do not have to write that loop yourself. It never decrypts disclosedClaimson its own: decryption is always your own backend's job, either by relaying the ciphertext from the widget over your own authenticated channel, or, more simply, by having your backend call GET /v1/credentials/verify/sessions/{sessionId} directly with its own API key.

Idempotency, rate limits, and authentication

POST /v1/credentials/verify/sessions honors an Idempotency-Key header: resending the exact same request with the same key returns the original session rather than creating a second one. Every request against a production deployment requires the credentials-api-verifier bearer token described above, validated per request via RFC 7662 introspection so a revoked key is rejected immediately, and is rate limited and evaluated for the same volume, geography, and behavior-shift anomaly signals as every other Nexiel API. See the Screen API quickstart's Authentication section for exactly how that works.