The integration is very simple: we recommend webview on your frontend for native apps and iframe for web apps. Both of these need a token that you get from the backend endpoints at the end of these docs. After this, all you need is to make sure webview url is saved on your surt dashboard.
For native mobile applications (iOS/Android), we recommend using our WebView integration. This provides seamless camera access and optimal user experience within your app.
Embed Surt Verify inside a WebView with these exact parameters for optimal performance. Use a dark background for the WebView to match our UI.
import { WebView } from 'react-native-webview';
<WebView
source={{ uri: 'https://identity.surt.ai/intro?token=YOUR_TOKEN_HERE' }}
style={{
width: '100%',
height: '100%',
backgroundColor: '#000000' // Dark background
}}
allowsInlineMediaPlayback={true}
mediaPlaybackRequiresUserAction={false}
geolocationEnabled={true}
javaScriptEnabled={true}
domStorageEnabled={true}
originWhitelist={['*']}
androidLayerType="hardware"
allowsProtectedMedia={true}
onMessage={(event) => {
const data = JSON.parse(event.nativeEvent.data);
// Handle messages from the verification flow
if (data.type === 'surt:completed') {
// Verification completed
console.log('Verification status:', data.status);
}
}}
/>Important: Always use a dark background (#000000) for the WebView to ensure the best visual experience and consistency with our UI design.
For web applications, we recommend integrating through our QR code page. This automatically detects when users are on desktop and gives them the option to scan a QR code and complete the flow on their phone, which is often more convenient for document scanning and liveness checks.
This method automatically detects desktop users and provides a QR code option. Users can scan the QR code to continue the verification on their mobile device, which is ideal for document scanning and liveness detection.
<iframe
id="surtQrCodeFrame"
src="https://identity.surt.ai/qrcode?token=YOUR_TOKEN_HERE"
allow="camera; microphone; fullscreen; geolocation"
allowfullscreen
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
style="width: 300px; height: 300px; border: 0; display: block; margin: auto;"
title="QR Code Verification"
></iframe>The QR code page automatically detects if the user is on desktop and displays a QR code. When scanned, it opens the same verification session on mobile via https://identity.surt.ai/intro?token=YOUR_TOKEN
You can also integrate our intro page directly into your platform. Note the /intro in the URL.
<iframe
id="surtIdentityFrame"
src="https://identity.surt.ai/intro?token=YOUR_TOKEN_HERE"
allow="camera; microphone; fullscreen; geolocation"
allowfullscreen
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
style="width: 100%; height: 100%; border: 0"
title="Identity Verification"
></iframe>Note: For Chromium-based browsers (Chrome, Edge, Brave, Opera), camera access inside iframes is restricted. The QR code integration method is recommended for these browsers.
Listen for events from the verification flow to handle completion and status updates.
const iframe = document.getElementById("surtIdentityFrame");
let ready = false;
function startVerification(token) {
iframe.src = "https://identity.surt.ai/intro?token=" + token;
}
window.addEventListener("message", (e) => {
if (e.data?.type === "surt:ready") {
ready = true;
console.log("Surt Verify is ready");
}
if (e.data?.type === "surt:completed") {
const status = e.data.status; // "Accepted", "Rejected", or "Manual Review"
console.log("Verification completed:", status);
// Update your UI or call your backend
// You can also poll the status endpoint (see Backend section)
}
});
// Start verification with your token
const token = "your_jwt_token_here";
startVerification(token);Simple backend integration with just 2 endpoints and webhook configuration
After we provide you with login credentials, an API key will be created for your organization. You'll also need to create a workflow in your dashboard, which will give you a workflow_id.
workflow_idCall this endpoint with your API key, customer details, workflow ID, and product ID to get a JWT token for the verification session.
curl --location 'https://api.surt.ai/kyc-session/portal' \
--header 'Authorization: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"workflow_id": "8eabd458-96c8-4ad7-8c57-d72b56240037",
"product_id": "idv",
"customer": {
"customer_id": "edwinmorning",
"email": "customer@example.com",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1990-01-15",
"phone": "+1234567890",
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
}
}
}'Important: This token is used in the frontend integration URLs (?token=YOUR_TOKEN). The token contains session information and has an expiration time.
The customer_id is a unique identifier you use to identify a user on your end. This should be something unique like their username or user ID. This same identifier is sent during token creation and will be used throughout the verification process. It will always be the unique identifier you use to identify the customer in your system.
The product_id field specifies which Surt product you're using:
idv - Identity Verificationgeolocation - Geolocation Servicestransaction_monitoring - Transaction MonitoringThe more details you provide about the customer (email, name, date of birth, phone, address), the more information we have upfront and the less we need to collect from your customer during the verification flow. All customer fields are optional except customer_id, but providing more details improves the verification experience.
Poll this endpoint anytime to get the current status of a customer's verification. You can call this endpoint as frequently as needed to check if verification is complete. Use the same customer_idthat you sent when creating the token.
curl --location 'https://api.surt.ai/organizations/customers/{customer_id}/status' \
--header 'Authorization: YOUR_API_KEY'Note: Replace {customer_id} with the same unique identifier you used when creating the token (e.g., username or user ID). This is the identifier you use to identify the customer in your system.
Set up webhooks in your dashboard to receive real-time notifications when customer status is updated. This is especially important for customers that undergo manual review, as you'll be notified when a decision is made. Webhooks are sent as POST requests to your configured URL whenever a customer's status changes.
After setting up your integration, make sure to save your webview URL in your Surt dashboard. This ensures proper configuration and allows the verification flow to work correctly with your application.
All webhook requests include security headers for verification:
X-Hub-Signature-256 - HMAC SHA-256 signature of the JSON bodyX-Webhook-Timestamp - Unix timestamp used for signature generationContent-Type: application/jsonUse the webhook secret from your dashboard to verify the signature and ensure the request is authentic. This ensures you receive all status updates automatically and securely.
// Example webhook payload (POST request)
{
"organization_id": "org-123456",
"product_id": "idv",
"workflow_id": "8eabd458-96c8-4ad7-8c57-d72b56240037",
"customer_id": "edwinmorning",
"new_status": "approved",
"changed_at": "2024-01-15T10:30:00Z",
"reviewer_id": "reviewer-789",
"notes": "Customer approved after manual review"
}
// Alternative status formats:
// "new_status": "rejected"
// "new_status": "manual_review"
// "new_status": "reverification"
// Status with session config:
{
"new_status": {
"approved_with_config": {
"session": {
"session_id": "session-abc123",
"organization_id": "org-123456",
"product_id": "idv",
"workflow_id": "8eabd458-96c8-4ad7-8c57-d72b56240037",
"customer_id": "edwinmorning",
"retry": false,
"active": true,
"expiration": 1705320000,
"created_at": 1705233600,
"email": "customer@example.com",
"phone": "+1234567890",
"first_name": "John",
"last_name": "Doe",
"dob": "1990-01-15",
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
"metadata": {},
"cost": {
"amount": 0.50,
"currency": "USD"
}
}
}
}
}That's all you need! Get started by contacting our sales team to receive your credentials and API key.