Skip to main content

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

AttributeRequiredDescription
publishable-keyYesYour qv_pub_* or qv_pub_test_* key from the dashboard
api-baseYesVeridia API endpoint — https://api.xxuxe.online for production
user-refNoYour own user identifier — echoed back in events and webhooks (max 128 chars)
countryNoISO 3166-1 alpha-2 country code (e.g., PY, BR, MX) — improves OCR accuracy
document-typeNoOne of: dni, passport, drivers_license, national_id, other
submitted-full-nameNoThe user's full name for fuzzy matching against the document (max 255 chars)
require-doc-backNoSet to "true" if your document type requires a back-side photo (default: "false")
localeNoUI language: en, es, or pt. Defaults to browser locale, fallback to English
accent-colorNoHex 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:

  1. A "Start" button with the title "Identity verification" (or its translated equivalent)
  2. After clicking start, a camera permission prompt
  3. Three capture steps: front of document, back of document (if require-doc-back="true"), then selfie
  4. A "Submitted ✓" confirmation screen

If you see "This widget is misconfigured", check:

  • The publishable-key is valid and not revoked
  • Your domain is in the allowed origins list on the dashboard
  • The api-base is correct (https://api.xxuxe.online)

Next step

Run a real verification end-to-end and inspect the result.

Step 2: First verification →