Fintech & lending
Most teams spend months building KYC: camera handling, liveness, document parsing and face matching. Veris gives you all of it on one API key, with no face images stored.
Sandbox ready in minutes · no card · all three products
Pricing, rollout or a security review
Scan the front of your ID
Hold steady. We'll capture it automatically.
Checking your result…
This only takes a moment.
ID photo
SelfieMatching faces
Comparing your selfie with your ID photo.
You're verified
Welcome aboard, Amara.
Continue1 of 5
SureLifeInsurance
CarevoHealthcare
ShoplyE-commerceEach product works on its own. Together they cover a full verification flow, on one key and one subscription. Your app keeps the screens; Veris does the hard parts.
A guided selfie with a quality gate and liveness detection. Every session returns one signed result your backend can trust.
Point the camera at a Nigerian ID or utility bill, or pass in an image. The fields come back as structured data.
Send two face images from your server. Get back a similarity score, a match decision and a recommendation.
Scan hands you the photo from the ID. Capture hands you a live selfie. Compare tells you whether they are the same person. Use the pieces you need and add the rest later.
// your backend
const COMPARE_URL = "https://compare.verisinfra.com/v1/compare/base64"
const res = await fetch(COMPARE_URL, {
method: "POST",
headers: { Authorization: `Bearer ${VERIS_KEY}` },
body: JSON.stringify({
captured_b64, reference_b64,
use_case: "kyc_onboarding"
})
})
// → { match, confidence, recommendation, … }
Every paid plan includes all three products; liveness starts on Launch. See plans
Lenders, marketplaces, engineering teams and compliance leads use Veris differently. Open a use case to see the problem, how Veris fits, and where to start.
Fintech & lending
Marketplaces & platforms
Developers
Regulated teams
Building for Nigeria
Startups
Face and ID images stay on the
Capture and Scan run on the deviceCamera frames, the selfie and the photo of the ID are processed on the phone. They are never sent to Veris..
Your server gets a
ES256-signed, single-use"status": "SUCCESS","liveness_score": 0.88,"face_hash": "7d2e…c41a"Tied to a one-time nonce from your server. A replayed result is rejected.,
not a photo, unless your app sends one. Compare reads
In memory, then deletedYour backend sends both images to Compare. They are processed in memory and deleted after every request, including requests that fail.
and deletes them. Veris keeps your account and usage records, and
What Veris keepsYour account, license and usage records. Never face images, video or biometric templates. License keys are stored as hashes..
Every connection uses TLS 1.2 or later, with HSTS on every Veris domain. Veris supports your compliance work; it does not replace it.
Native SDKs for Android, iOS, Flutter and React Native, and a REST API for Compare. Build against the free sandbox, then swap in a live key. Your code stays the same.
// build.gradle (app module)implementation 'com.verisinfra:veris-capture-android:1.3.0'one dependency// MainActivity.kt, in onCreateVerisCapture.init( context = this, config = VerisConfig( licenseKey = "veris_sandbox_…",sandbox key from your dashboard initNonce = fetchNonceFromBackend(), ),) { if (it is VerisInitResult.Ready) { /* ready */ } }
val verisLauncher = VerisCapture.registerForResult(this) { result -> when (result) {always one of four results is VerisResult.Success -> verifyWithBackend(result.signedResult) is VerisResult.Failure -> showError(result.humanReadableReason) is VerisResult.Cancelled -> { /* user closed it */ } is VerisResult.SubscriptionInactive -> showUpgradePrompt() }}VerisCapture.startCapture( launcher = verisLauncher, config = VerisSessionConfig(nonce = fetchNonceFromBackend()),a fresh nonce per session)
# Podfile (iOS 15+), or add the Swift packagepod 'VerisCapture'one dependency// once, at launchVerisCapture.initialise( config: VerisConfig( licenseKey: "veris_sandbox_…",sandbox key from your dashboard initNonce: fetchNonceFromBackend() )) { result in if case .ready = result { /* ready */ }}
VerisCapture.startVerification( from: self, session: VerisSessionConfig( nonce: fetchNonceFromBackend()a fresh nonce per session )) { [weak self] result in switch result {a typed result, every time case .success(let capture): self?.verifyWithBackend(capture.signedResult) case .failure(_, let reason, _): self?.showError(reason) case .cancelled: break case .subscriptionInactive: self?.showUpgradePrompt() case .error(_, let message): self?.showError(message) }}
# pubspec.yamldependencies: veris_capture: ^1.3.0one dependency// main.dart, once at startupawait VerisCapture.instance.initialise( config: VerisConfig( licenseKey: 'veris_sandbox_…',sandbox key from your dashboard initNonce: await fetchNonceFromBackend(), ),);
final result = await VerisCapture.instance.startVerification( session: VerisSessionConfig( nonce: await fetchNonceFromBackend(),a fresh nonce per session ),);switch (result) {a typed result, every time case VerisSuccess s: verifyWithBackend(s.signedResult); case VerisFailure f: showError(f.humanReadableReason); case VerisCancelled _: break; case VerisSubscriptionInactive _: showUpgradePrompt(); case VerisError e: showError(e.message);}
# Terminalnpm install @verisinfra/react-native-captureone dependencycd ios && pod install// App.tsx, once at startupimport { VerisCapture } from '@verisinfra/react-native-capture';await VerisCapture.initialise({ licenseKey: 'veris_sandbox_…',sandbox key from your dashboard initNonce: await fetchNonceFromBackend(),});
const result = await VerisCapture.startVerification({ nonce: await fetchNonceFromBackend(),a fresh nonce per session});switch (result.type) {a typed result, every time case 'success': verifyWithBackend(result.signedResult);signed result, ready to verify break; case 'failure': showError(result.reason); break; case 'subscriptionInactive': showUpgradePrompt(); break; case 'cancelled': break; case 'error': showError(result.message); break;}
// Your license key stays on your server, never in the appconst res = await fetch('https://api.verisinfra.com/v1/sdk/verify-result', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ license_key: process.env.VERIS_LICENSE_KEY, token: signedResult, // from the SDK, unchanged }),});const { valid, nonce_status } = await res.json();if (valid) await markUserVerified(user);true once; a replay is rejected
Running…
SDK ready. Sandbox keys work straight away: all three products, 50 validations a day.
→SuccessFailureCancelledSubscriptionInactiveAlways one of four. Never a crash.
→200{ "valid": true, "nonce_status": "fresh" }A replayed result is rejected.
Learn how to design NDPR-compliant identity verification systems for Nigerian applications without sacrificing security or user experience.
Learn how to build fast, reliable identity verification that works well on the low-end Android devices commonly used across Africa.
Learn how to design a fast, secure, user-friendly KYC onboarding experience that improves conversion while reducing fraud.
Create an account and start building straight away with all three products. No card, no KYC. Go live free on Spark, cancel any time, and get your first payment back within 14 days if Veris isn't right for you.
Can't find yours? Write to [email protected] or talk to us. The docs go deeper.
No. Capture and Scan process images on the user's phone and never send them to Veris. Images sent to Compare are processed in memory and deleted after every request, including requests that fail. Veris does not store face images, video or biometric templates.
Capture and Scan have native SDKs for Android, iOS, Flutter and React Native. Compare is a REST API you call from any backend, in any language.
The NIN slip, national ID card, driver's licence, international passport (including the MRZ), voter's card, electricity, water and waste bills, and bank statements. AUTO_DETECT works out the type for you. Scan reads the document; it does not judge whether it is genuine.
No. Veris does not look people up in government databases. Scan reads what is printed on the document, Capture confirms a live person is present, and Compare tells you whether two faces match. If you need a database check, use it alongside Veris.
Yes. Create an account and verify your email; there is no card and no KYC. The sandbox includes all three products, with 50 validations a day and 10 Compare calls in total. Sandbox results are marked as sandbox and are rejected in production.
Start free in the sandbox. To go live at low volume, Spark is free. For real users, Launch ($19 a month) adds passive liveness, and Scale ($39) adds active liveness and our help going live. Pro adds stricter liveness and video. You can change plan at any time.
Yes. Every plan includes all three, but you only integrate what you need. You could start with Capture for liveness at sign-up, then add Scan for KYC and Compare when you need to re-verify people.
Choose a plan, register your app's production package name, and swap your sandbox key for a live key. Your integration code stays the same. Each live key is tied to one production app.
Plans are subscriptions, not a charge per verification. Prices are in US dollars and charged in naira at checkout, at the day's rate. Compare calls come with a monthly allowance. See the pricing page for what each plan includes.
Yes. If Veris isn't right for you, you can get your first payment for a paid plan back in full within 14 days. Write to [email protected] from your account email. It applies once per account and doesn't cover Compare overage. You can also cancel any time from the dashboard.
There is a short grace period while you update your payment. After that, the SDK returns a SubscriptionInactive result instead of crashing, so your app can show its own message.