For Relying Parties
Getting Started
Install the SDK
npm install @nexiel/eudi-sdk # or yarn add @nexiel/eudi-sdk
Retrieve an API key
Five-line quick start
import { NexielAPI } from '@nexiel/eudi-sdk';
const nexiel = new NexielAPI({ apiKey: process.env.NEXIEL_API_KEY });
// Gate mode: returns booleans only (no PII)
const verification = await nexiel.verify({ mode: 'gate', scope: ['age_over_18'] });
console.log(verification.decisions); // { over18: true }When the wallet completes, Nexiel fires a verification.completed webhook. Keep reading for callback details.
Code snippets
One-click QR flows, deep links, and webhook handling. Minimal disclosure for age-gated use cases.
<!-- Frontend button + QR -->
<button id="nexiel-verify-btn">Verify with EU Digital Identity</button>
<div id="nexiel-qr-container"></div>
<script src="https://sdk.nexiel.ie/v1/nexiel.js"></script>
<script>
const nexiel = Nexiel({ clientKey: "YOUR_PUBLIC_CLIENT_KEY" });
document.getElementById("nexiel-verify-btn").addEventListener("click", async () => {
const session = await nexiel.verifications.create({
mode: "qr_code",
verificationMode: "gate", // or "match" | "data" (data requires allow list/approval)
policyId: "{{POLICY_ID}}",
redirectUrl: "https://yourdomain.com/callback",
});
nexiel.displayQRCode("#nexiel-qr-container", session.qrCode);
session.on("verified", (data) => {
console.log("Verification successful:", data);
// data.checks.age_over_18 / age_over_21, audit metadata
});
session.on("error", (error) => {
console.error("Verification failed", error);
});
});
</script>Sample JSON response
{
"verification_id": "v_abc123",
"status": "completed",
"checks": { "age_over_18": true },
"qr_code_url": "https://cdn.nexiel.ie/qr/v_abc123.png",
"deep_link": "eudi-wallet://verify?v=v_abc123",
"audit": { "assurance_level": "substantial", "verified_at": "2026-01-06T10:30:00Z" }
}Interactive
Kick off sessions, poll status, and inspect verification payloads directly in the docs. Sandbox keys only; no production credentials required.
Select endpoint
Kick off an OpenID4VP session. The response contains wallet deep links and polling ids.
Verification modes
Gate (default)
Match
Data (exception)
Verification modes (access)
Live Playground
Trigger a real sandbox verification flow using our publishable client key. Swap the key with your own to embed this widget directly in your onboarding forms.
Interactive sandbox
We auto-provision a publishable sandbox key for this demo. Replace it with your own NEXT_PUBLIC_NEXIEL_SANDBOX_CLIENT_KEY in your app before going live. Each preset below updates the code sample automatically.
Loading sandbox widget…
Scope requested: name, email, address • Name + email + address for CRM hydration
Example snippet
Replace the environment variable with your publishable key. The scope and optional useCase below match the preset you have selected.
import { NexielVerifyButton } from '@nexiel/eudi-react';
export function VerifyButton() {
return (
<NexielVerifyButton
clientKey={process.env.NEXT_PUBLIC_NEXIEL_SANDBOX_CLIENT_KEY!}
scope={['name', 'email', 'address']}
onSuccess={(receipt) => {
console.log('Verification receipt', {
session: receipt.session_id,
result: receipt.result,
checks: receipt.checks,
});
}}
onError={(error) => console.error(error)}
/>
);
}Integration presets
Pick a use case (login, age-gate, KYC, QES) and we pre-fill the React widget snippet, verify() call, and presentation definition + workflow JSON.
Login + profile hydration
Authenticate users and hydrate CRM records with verified name, email, and address attributes.
scope: name, email, address
Age-gated checkout
Request zero-knowledge age booleans (18+ / 21+) for alcohol, gaming, or payments compliance.
scope: age_over_18, age_over_21
Full KYC onboarding
Capture PID, address, tax ID, and assurance level for regulated onboarding. Enhanced checks can be layered later.
scope: name, address, tax_id, citizenship
Qualified electronic signature
Bind wallet identity to signature ceremonies with LoA tracking and webhook receipts for audit.
scope: name, citizenship
DC4EU Education QEAA
Qualified Electronic Attestation of Attributes for diplomas and professional qualifications (WP5).
scope: legal_name, date_of_birth, citizenship, education.institution_name, education.programme_name, education.programme_level, education.qualification_status, education.qualification_issue_date, education.qualification_valid_to
Aligned with DC4EU WP5 education pilots.
DC4EU Social Security (PDA1 / EHIC)
Portable Document A1 & European Health Insurance Card payloads for labour mobility (WP6).
scope: legal_name, date_of_birth, citizenship, social_security.number, social_security.member_state, social_security.coverage_start, social_security.coverage_end, social_security.ehic_number, employment.employer_name
Aligned with DC4EU WP6 social security pilots.
Drop-in snippet
import { NexielVerifyButton } from '@nexiel/eudi-react';
export function NexielPresetButton() {
return (
<NexielVerifyButton
clientKey="pk_test_your_publishable_key"
scope={[
"name",
"email",
"address"
]}
label="Continue with EUDI Wallet"
onSuccess={(receipt) => {
console.log('Verification receipt', {
session: receipt.session_id,
result: receipt.result,
});
}}
/>
);
}Backend request
const verification = await nexiel.verify({
scope: [
"name",
"email",
"address"
],
purpose: 'sso_login',
fallback: {
"strategy": "bank_ident",
"provider": "fin-id"
},
});
console.log({
id: verification.verification_id,
result: verification.result,
checks: verification.checks,
});Presentation definition
Workflow & policy config
DC4EU alignment
Nexiel’s `use_case` parameter now mirrors the Digital Credentials for the EU (DC4EU) blueprint so your wallet flows stay compatible with the EU’s large-scale pilots.
DC4EU Education QEAA
Work package: WP5
Qualified Electronic Attestation of Attributes for diplomas, professional qualifications, and student cards.
use_case: dc4eu_education_qeaa
Required scope: legal_name, date_of_birth, citizenship, education.institution_name, education.programme_name, education.programme_level, education.qualification_status, education.qualification_issue_date, education.qualification_valid_to
DC4EU Social Security (PDA1 / EHIC)
Work package: WP6
Portable Document A1 and European Health Insurance Card attributes for cross-border labour mobility.
use_case: dc4eu_social_security_pda1
Required scope: legal_name, date_of_birth, citizenship, social_security.number, social_security.member_state, social_security.coverage_start, social_security.coverage_end, social_security.ehic_number, employment.employer_name
{
"verification_id": "v_abc123xyz",
"status": "completed",
"checks": { "age_over_18": true },
"assurance_level": "substantial",
"verification_method": "eudi_wallet",
"timestamp": "2025-01-15T10:30:00Z",
"audit": {
"event_id": "evt_9f2c",
"policy_id": "pol_age_gate",
"verified_at": "2025-01-15T10:30:15Z"
}
}Add metadata (e.g. { userId: "123" }) or callbackUrl per request if you prefer push notifications over global webhooks.
import { NexielVerifyButton } from '@nexiel/eudi-react';
export function SignupForm() {
return (
<NexielVerifyButton
clientKey="pk_sandbox_abc123"
credentialTypes={['age_attestation']}
verificationMode="gate"
scope={['age_over_18']}
onSuccess={(verification) => {
console.log('Verification receipt:', {
session: verification.session_id,
result: verification.result,
checks: verification.checks,
});
}}
onError={(error) => console.error(error)}
/>
);
}Handles QR vs deep link detection, wallet polling, localization, and theming. Vue/Angular/vanilla bundles share the same props.
import { NexielAPI } from '@nexiel/eudi-sdk';
const nexiel = new NexielAPI({ apiKey: process.env.NEXIEL_API_KEY });
export async function verifyUser(req, res) {
// Gate mode (default): booleans only, no PII returned
const verification = await nexiel.verify({
mode: 'gate',
scope: ['age_over_18'],
});
res.json({
verification_id: verification.verification_id,
decisions: verification.decisions, // { over18: true }
});
}from nexiel_eudi import NexielAPI
import os
client = NexielAPI(api_key=os.environ["NEXIEL_API_KEY"])
# Match mode: compare user input vs wallet attributes (no raw PII returned)
verification = client.verify(
mode="match",
scope=["name", "dob"],
user_input={"name": "Jane Doe", "dob": "1990-01-02"},
)
print(verification.matches)client := nexiel.New(os.Getenv("NEXIEL_API_KEY"))
// Data mode: allow-listed attributes only (requires tenant approval)
verification, err := client.Verify(nexiel.VerifyParams{
Mode: "data",
Scope: []string{"address"},
Allow: []string{"address"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(verification.Data)Register URLs inside the dashboard. Nexiel signs every payload with X-Nexiel-Signature (HMAC-SHA256). Retries occur up to 5 times with exponential backoff.
verification.completed
Wallet proof accepted. Includes hashed attributes + assurance level.
verification.failed
Wallet rejected, expired, or violated policy.
user.deleted
EUDI wallet initiated GDPR erasure; mirror the deletion downstream.
app.post('/webhook/nexiel', verifyHmac(process.env.NEXIEL_WEBHOOK_SECRET), (req, res) => {
const { verification_id, status, user } = req.body;
if (status === 'verified') {
saveUserIdentity(user);
}
res.json({ received: true });
});Scopes & claims
name
Substantial+Full legal name supplied by the wallet issuer.
age_over_18
Substantial+Zero-knowledge boolean for regulated commerce.
age_over_21
Substantial+Additional gating for alcohol/gaming flows.
address
Substantial+Residence with issuer attestation.
Verified contact email.
citizenship
HighConfirmed EU citizenship with issuer signature.
tax_id
HighNational tax identifier for AML/KYC.
driving_licence
HighLicence number + category metadata.
try {
await nexiel.verify({ scope: ['name'] });
} catch (error) {
switch (error.code) {
case 'VERIFICATION_TIMEOUT':
promptUserToRetry();
break;
case 'USER_DENIED':
surfaceAlternateFlow();
break;
case 'INVALID_SCOPE':
requestSupportedScopes();
break;
case 'RATE_LIMIT':
wait(error.retryAfter);
break;
}
}Pricing & rate limits
Tier 1
€0.50 / verification + VAT
1 – 1,000 verifications/month
Rate limit: 10 req/sec burst
Support: Email support
Tier 2
€0.35 / verification + VAT
1,001 – 10,000 verifications/month
Rate limit: 100 req/sec burst
Support: Email support (priority inbox optional)
Tier 3
€0.20 / verification + VAT
10,001 – 100,000 verifications/month
Rate limit: Custom burst + dedicated SLAs
Support: Email support + governance add-ons
Tier 4
€0.15 / verification + VAT
100,001+ verifications/month
Rate limit: Custom burst + dedicated SLAs
Support: Email support + governance add-ons
Use-case playbooks
Fintech onboarding
Prove identity + address before account opening.
Age-gated commerce
Protect checkouts without storing PII.
Rental platforms
Screen tenants with full wallet attributes.
Healthcare intake
Verify patients before unlocking records.
User has not yet opened their wallet or the wallet is still syncing trust lists. Remind the user or allow manual fallback.
Most flows finish under 60 seconds. Complex credential bundles may take up to 2 minutes.
Offer bank ident or photo ident through the /ident API as a fallback and merge results into the same audit trail.
Gate/Match avoid PII. Data mode is allow-listed per tenant/use case with retention + audit. Store only what your purpose needs, purge on schedule.
All EU member states plus EEA pilots. New issuers are added automatically as EU trust lists expand.
Request logs & observability
Every API request is captured with method, path, latency, API key prefix, and scrubbed payload previews. Trace wallet flows without leaving the dashboard.
/metrics for Prometheus / Grafana.