Skip to main content

iFrame Integration

Embed FaceGuard directly using an iframe for full control over sizing and layout.

Communication Method

The iframe integration uses postMessage for all communication. Events are sent via window.postMessage and received through the message event listener.

Mobile (Fullscreen)

HTML
<div
id="faceguard-container"
style="position: fixed; inset: 0; z-index: 9999; background: #0D141A;"
>
<iframe
src="https://faceguard.surt.com/intro?token=YOUR_PORTAL_TOKEN"
allow="camera"
style="width: 100%; height: 100%; border: none;"
></iframe>
</div>

Desktop (Phone-shaped Modal)

HTML
<div
id="faceguard-backdrop"
style="
position: fixed; inset: 0; z-index: 9999;
background: rgba(0, 0, 0, 0.6);
display: flex; align-items: center; justify-content: center;
"
>
<div style="
width: 420px; height: 760px;
border-radius: 24px; overflow: hidden;
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4);
">
<iframe
src="https://faceguard.surt.com/intro?token=YOUR_PORTAL_TOKEN"
allow="camera"
style="width: 100%; height: 100%; border: none;"
></iframe>
</div>
</div>

Desktop (QR Code)

For desktop users, use the /qrcode route to show a QR code that opens the verification on their phone:

HTML
<iframe
src="https://faceguard.surt.com/qrcode?token=YOUR_PORTAL_TOKEN"
allow="camera"
style="width: 420px; height: 760px; border: none; border-radius: 24px;"
></iframe>

Required Attributes

AttributePurpose
allow="camera"Grants camera access inside the iframe
Camera required

The allow="camera" attribute is mandatory. Without it, the browser blocks camera access and FaceGuard emits { action: 'close', reason: 'error', error: 'camera_insecure_context' }.

Event Handling

JavaScript
window.addEventListener('message', (event) => {
// Verify origin in production
if (event.origin !== 'https://faceguard.surt.com') return;

const data = event.data;

if (data.type === 'surt:ready') {
console.log('FaceGuard loaded');
return;
}

if (data.action === 'close') {
switch (data.reason) {
case 'approved':
console.log('Verified', data.confidence);
break;
case 'rejected':
console.log('Failed', data.confidence);
break;
case 'canceled':
console.log('User canceled');
break;
case 'bypass_active':
console.log('Bypass active until', data.bypass_expires_at);
break;
case 'no_base_photo':
console.log('No base photo on file');
break;
case 'error':
// `data.error` is a typed code — see Camera Error Codes in the reference
switch (data.error) {
case 'camera_permission_denied':
showToast('Please allow camera access in your browser settings, then try again.');
break;
case 'camera_unavailable':
showToast('No camera detected on this device.');
break;
case 'camera_in_use':
showToast('Your camera is in use by another app or tab.');
break;
case 'camera_insecure_context':
// Likely a misconfigured embed — log to your monitoring
console.error('FaceGuard: camera blocked, check HTTPS and allow="camera".');
break;
default:
console.log('FaceGuard error:', data.error);
}
break;
}

// Remove iframe
document.getElementById('faceguard-container')?.remove();
}
});

Events Reference

EventPayloadDescription
Ready{ type: 'surt:ready' }FaceGuard is loaded and ready
Approved{ action: 'close', reason: 'approved', confidence: number }Face verified (0-100 score)
Rejected{ action: 'close', reason: 'rejected', confidence: number }Face did not match (0-100 score)
Canceled{ action: 'close', reason: 'canceled' }User closed FaceGuard
Bypass{ action: 'close', reason: 'bypass_active', bypass_expires_at: string }Customer has active bypass
No Base Photo{ action: 'close', reason: 'no_base_photo' }No enrolled photo to compare against
Error{ action: 'close', reason: 'error', error: string }Something went wrong. The error value is a typed code — see Camera Error Codes.

URL Parameters

ParameterDescription
tokenPortal JWT (required)
langLanguage override: en, es, pt, de (optional)

Sizing

FaceGuard is designed at 375x812px and scales automatically.

  • Mobile: full viewport (100vw x 100vh)
  • Desktop: recommended 420x760px with 24px border-radius
  • Minimum: 320px width
Dark Background

Set background: #0D141A on the iframe container to prevent a white flash while loading.

Security Headers

If your site uses Content Security Policy or Permissions-Policy headers:

frame-src https://faceguard.surt.com;
Permissions-Policy: camera=(self "https://faceguard.surt.com")