Installation
1. Get your publishable key
Sign in to your Veridia dashboard and copy a publishable key from the API keys section.
- Test key — looks like
qv_pub_test_.... Use this while integrating. - Live key — looks like
qv_pub_.... Use this in production.
Publishable keys are safe to expose in client-side HTML. They identify your tenant and the widget origin, but they can't read or modify other tenants' data.
:::tip Domain whitelist On the dashboard, configure the allowed origins for each key. The widget refuses to load on any domain not in that list — protects you from someone else dropping your key in their site. :::
2. Embed the widget
Drop two script tags and the custom element on any page:
<!-- 1. Load face-api.js (UMD), then the widget bundle (ESM module) -->
<script src="https://widget.xxuxe.online/face-api.js"></script>
<script type="module" src="https://widget.xxuxe.online/veridia-widget.min.js"></script>
<!-- 2. Drop in the widget -->
<veridia-widget
publishable-key="qv_pub_test_YOUR_KEY_HERE"
api-base="https://api.xxuxe.online"
user-ref="customer-12345"
country="PY"
document-type="dni"
locale="es">
</veridia-widget>
<!-- 3. Listen for events -->
<script>
document.querySelector('veridia-widget')
.addEventListener('veridia:complete', (e) => {
console.log('verification:', e.detail.verificationId);
// Poll GET /v1/verify/:id for the final verdict
});
</script>
That's the full integration. Open the page on a phone or laptop with a camera, hit "Start", and you have a working biometric verification.
Configuration attributes
| Attribute | Required | Description |
|---|---|---|
publishable-key | Yes | Your qv_pub_* or qv_pub_test_* key from the dashboard |
api-base | Yes | Veridia API endpoint — https://api.xxuxe.online for production |
user-ref | No | Your own user identifier — echoed back in events and webhooks (max 128 chars) |
country | No | ISO 3166-1 alpha-2 country code (e.g., PY, BR, MX) — improves OCR accuracy |
document-type | No | One of: dni, passport, drivers_license, national_id, other |
submitted-full-name | No | The user's full name for fuzzy matching against the document (max 255 chars) |
require-doc-back | No | Set to "true" if your document type requires a back-side photo (default: "false") |
locale | No | UI language: en, es, or pt. Defaults to browser locale, fallback to English |
accent-color | No | Hex color for buttons and active states (e.g., "#2563EB") |
Framework examples
React
import { useEffect, useRef } from 'react';
export function VeridiaVerification({ userRef, onComplete }) {
const widgetRef = useRef(null);
useEffect(() => {
const handler = (e) => onComplete(e.detail);
const node = widgetRef.current;
node?.addEventListener('veridia:complete', handler);
return () => node?.removeEventListener('veridia:complete', handler);
}, [onComplete]);
return (
<veridia-widget
ref={widgetRef}
publishable-key={process.env.NEXT_PUBLIC_VERIDIA_KEY}
api-base="https://api.xxuxe.online"
user-ref={userRef}
locale="es"
/>
);
}
Make sure to load the script tags once in your _document.tsx or index.html:
<script src="https://widget.xxuxe.online/face-api.js"></script>
<script type="module" src="https://widget.xxuxe.online/veridia-widget.min.js"></script>
Vue 3
<template>
<veridia-widget
ref="widget"
:publishable-key="publishableKey"
api-base="https://api.xxuxe.online"
:user-ref="userRef"
locale="es"
/>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const props = defineProps(['publishableKey', 'userRef']);
const emit = defineEmits(['complete']);
const widget = ref(null);
const handler = (e) => emit('complete', e.detail);
onMounted(() => {
widget.value?.addEventListener('veridia:complete', handler);
});
onUnmounted(() => {
widget.value?.removeEventListener('veridia:complete', handler);
});
</script>
Vue treats <veridia-widget> as a custom element automatically — no extra config needed.
Plain JavaScript (no framework)
<!DOCTYPE html>
<html>
<head>
<script src="https://widget.xxuxe.online/face-api.js"></script>
<script type="module" src="https://widget.xxuxe.online/veridia-widget.min.js"></script>
</head>
<body>
<veridia-widget
id="kyc"
publishable-key="qv_pub_test_YOUR_KEY"
api-base="https://api.xxuxe.online"
user-ref="user-001"
locale="es">
</veridia-widget>
<script>
const widget = document.getElementById('kyc');
widget.addEventListener('veridia:complete', async (e) => {
const { verificationId } = e.detail;
// Hit your own backend, which will call GET /v1/verify/:id
await fetch('/api/kyc-completed', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ verificationId }),
});
});
widget.addEventListener('veridia:error', (e) => {
console.error('Veridia error:', e.detail);
});
</script>
</body>
</html>
Verify it works
Open the page in a browser. You should see:
- A "Start" button with the title "Identity verification" (or its translated equivalent)
- After clicking start, a camera permission prompt
- Three capture steps: front of document, back of document (if
require-doc-back="true"), then selfie - A "Submitted ✓" confirmation screen
If you see "This widget is misconfigured", check:
- The
publishable-keyis valid and not revoked - Your domain is in the allowed origins list on the dashboard
- The
api-baseis correct (https://api.xxuxe.online)
Next step
Run a real verification end-to-end and inspect the result.