AI Integration Skill
Biometry Integration Architect
This document is an instruction set for AI coding agents (Claude, GPT, Copilot, etc.) building biometric authentication systems with the Biometry platform. Feed this to your AI tool as context when generating integration code.
System Architecture
Biometry follows an API proxy pattern. The customer’s backend proxies all Biometry API calls. The frontend never calls Biometry directly.
┌─────────────────────┐ ┌──────────────────────┐ ┌─────────────────────┐│ Customer Frontend │ │ Customer Backend │ │ Biometry API ││ │ │ │ │ ││ Web SDK / Flutter │────▶│ /api/verify │────▶│ /api-gateway/ ││ captures video + │ │ /api/enroll │ │ process-video ││ displays phrase │ │ /api/session/start │ │ enroll/face ││ │◀────│ /api/session/end │◀────│ sessions/start ││ Shows results to │ │ │ │ docauth/check ││ user │ │ Stores API key │ │ │└─────────────────────┘ │ Manages sessions │ │ api.biometrysolutions│ │ Handles decisions │ │ .com │ └──────────────────────┘ └─────────────────────┘Key rules:
- The API key (JWT) MUST only live on the customer’s backend. Never expose it to the frontend.
- The frontend uses our Web SDK (
@niceid/biometry-web) or Flutter SDK (biometry) to capture video and display the verification phrase. - The backend receives the captured video from the frontend and proxies it to Biometry.
- The backend interprets the Biometry response (score, decision) and decides what to show the user.
API Base URL
https://api.biometrysolutions.comService path prefixes:
/api-gateway— core biometric operations (sessions, video, enrollment, docauth, face match)/api-transactions— transaction history and queries/api-projects— API key management/api-consent— consent management/api-auth— user authentication (dashboard only, not for SDK integration)
Authentication
Every request to the Biometry API requires an API key passed as a Bearer token:
Authorization: Bearer <API_KEY_JWT>The API key is a JWT containing:
project_id— which project this key belongs toselected_services— which ML services are enabled (e.g., “Face Recognition”, “Voice Recognition”)scores_id— optional custom scoring rules IDid— the API key’s unique identifier
Important: API keys do not expire automatically. They must be explicitly revoked. Store them as secrets (env vars, secret manager).
Required Headers
Every request MUST include:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <API_KEY_JWT> |
X-User-Fullname | Yes* | Unique identifier for the end-user (email, username, or UUID). Used for consent lookup, enrollment, and transaction tracking. |
X-Session-ID | Recommended | Session ID from /sessions/start. Groups related operations. |
*Required for all /api-gateway endpoints except /sessions/start.
Optional Headers
| Header | Description |
|---|---|
X-Action-Trigger | What triggered this action: "authentication", "registration", "confirmation" |
X-Device-Info | JSON-encoded device metadata from the frontend SDK |
X-Geo-Location | JSON-encoded {lat, lng, country, city}. Falls back to IP geolocation if omitted. |
X-Request-Tags | Comma-separated labels for categorizing requests |
X-Inhouse-Docauth | "true" (default) for in-house doc auth, "false" for IDScan |
X-Inhouse-MRZ | "true" to enable MRZ (Machine Readable Zone) validation on documents |
Integration Flow: Biometric Authentication
This is the standard flow for authenticating a returning user with face and voice recognition.
Step 1: Start a Session
POST /api-gateway/sessions/startAuthorization: Bearer <API_KEY>Response:
{ "data": "session-uuid-here", "message": "session started" }Store the session ID. Pass it as X-Session-ID in all subsequent requests.
Step 2: Ensure Consent
Before biometric processing, the end-user must have given two types of consent:
Authorization Consent — allows biometric processing:
POST /api-consent/consentAuthorization: Bearer <API_KEY>Content-Type: application/json
{ "is_consent_given": true, "user_fullname": "[email protected]" }Storage Consent — allows biometric data to be stored for future verification (required for enrollment):
POST /api-consent/strg-consentAuthorization: Bearer <API_KEY>Content-Type: application/json
{ "is_consent_given": true, "user_fullname": "[email protected]" }Gotcha: If authorization consent is not given, Face Recognition and Voice Recognition services are silently removed from the request. Check the X-Removed-Services: true response header to detect this.
Gotcha: If storage consent is not given, auto-enrollment will NOT happen — even if the video quality is perfect. No error is returned; enrollment is silently skipped.
Consent only needs to be given once per user per project. It persists across sessions.
Step 3: Capture Video (Frontend)
Use our frontend SDK to capture the user’s video:
Web SDK:
<biometry-scanner phrase="one two three four five" on-capture="handleCapture"></biometry-scanner>Flutter SDK:
BiometryScannerWidget( phrase: "one two three four five", onCapture: (videoFile) => uploadToBackend(videoFile),)The SDK handles:
- Camera access and permissions
- Displaying the verification phrase
- Recording the video
- Returning the video file to your application
Your frontend sends the captured video to your backend (NOT to Biometry directly).
Step 4: Process Video (Backend Proxy)
Your backend receives the video from the frontend and forwards it to Biometry:
POST /api-gateway/process-videoAuthorization: Bearer <API_KEY>X-User-Fullname: [email protected]X-Session-ID: <session_id>Content-Type: multipart/form-data
video: <video_file> (required, max 50MB)phrase: "one two three four five" (required, must match what was displayed)vocabulary: "" (optional)trigger: "authentication" (optional)Response:
{ "data": { "Active Speaker Detection": { "code": 200, "result": 0.95 }, "Face Liveness Detection": { "code": 200, "result": true }, "Visual Speech Recognition": { "code": 200, "result": "one two three four five" }, "Voice Recognition": { "status": "identified", "score": 0.89 }, "Face Recognition": { "instances": [{ "search": { "probability": 0.97, "searchName": "[email protected]" } }] } }, "scoring_result": { "status": "pass", ... }, "score": 92.5, "decision_reasons": ["face_match_passed", "voice_match_passed"], "message": "video processed successfully"}Response headers to check:
X-Request-Id— unique request ID for debugging/supportX-Auto-Enroll: true— face/voice were auto-enrolled in background (first-time user)X-Removed-Services: true— some services were removed due to missing consent
Step 5: Interpret the Decision
The scoring_result.status field contains the final decision: "pass" or "fail".
Your backend should:
- Check
scoring_result.status— is it"pass"? - Check
score— is it above your threshold? - Check
decision_reasons— understand why it passed/failed - Decide whether to authenticate the user in YOUR system
- Return the result to the frontend
Never trust the frontend with the raw Biometry response. Your backend makes the authentication decision.
Step 6: End Session
POST /api-gateway/sessions/end/<session_id>Authorization: Bearer <API_KEY>Content-Type: application/json
{ "phone_number": "+61400000000" }The optional phone_number triggers a SIM-swap fraud check.
Integration Flow: First-Time Enrollment
For new users who haven’t been enrolled yet:
Option A: Auto-Enrollment (Recommended)
If both consents are given, Biometry automatically enrolls the user’s face and voice during process-video. No extra API calls needed.
- Ensure both consents are given (Step 2 above)
- Call
process-video— enrollment happens in the background - Check the
X-Auto-Enroll: trueresponse header to confirm
Option B: Explicit Enrollment
For more control, enroll face and voice separately:
Face Enrollment:
POST /api-gateway/enroll/faceAuthorization: Bearer <API_KEY>X-User-Fullname: [email protected]X-Session-ID: <session_id>Content-Type: multipart/form-data
face: <image_file>is_document: "false"Voice Enrollment:
POST /api-gateway/enroll/voiceAuthorization: Bearer <API_KEY>X-User-Fullname: [email protected]X-Session-ID: <session_id>Content-Type: multipart/form-data
voice: <audio_file>phrase: "one two three four five"Both require authorization consent AND storage consent.
Integration Flow: Document Verification (KYC Add-on)
For identity verification flows that need document checks:
Step 1: Check Document
POST /api-gateway/docauth/checkAuthorization: Bearer <API_KEY>X-User-Fullname: [email protected]X-Session-ID: <session_id>X-Inhouse-MRZ: trueContent-Type: multipart/form-data
document: <image_file> (jpg/jpeg/png only)Response includes extracted fields: name, DOB, document number, expiry, nationality, etc.
Step 2: Face Match Against Document
After process-video, match the document photo against the live video:
POST /api-gateway/match-facesAuthorization: Bearer <API_KEY>X-Session-ID: <session_id>X-Use-Prefilled-Video: trueContent-Type: multipart/form-data
image: <document_photo>Setting X-Use-Prefilled-Video: true reuses the video from the previous process-video call in the same session — no need to re-upload it.
ML Services Reference
The API key’s selected_services controls which services run during process-video:
| Service | Key Name | What It Does |
|---|---|---|
| Active Speaker Detection | Active Speaker Detection | Verifies the person in the video is actually speaking |
| Visual Speech Recognition | Visual Speech Recognition | Reads lips to verify the spoken phrase matches |
| Face Liveness Detection | Face Liveness Detection | Detects if the face is live (not a photo/video replay) |
| Voice Recognition | Voice Recognition | Identifies the speaker by voice (requires enrollment) |
| Face Recognition | Face Recognition | Identifies the person by face (requires enrollment) |
Consent dependency: Voice Recognition and Face Recognition require authorization consent. Without it, they are silently removed from processing. The response header X-Removed-Services: true indicates this happened.
Scoring System
Biometry applies scoring rules to ML results and returns a final decision.
Scoring hierarchy:
- Custom scoring rules (if
scores_idis set in the API key) - Project-specific scoring rules (fallback)
- Default scoring rules (ultimate fallback)
Response fields:
scoring_result— detailed scoring breakdownscore— numeric confidence score (0-100)decision_reasons— human-readable reasons for the decisionscoring_result.status— final verdict:"pass"or"fail"
Customers can create custom scoring rules via the dashboard to tune thresholds.
Error Handling
HTTP status codes:
200— success400— bad request (missing fields, invalid file format, file too large)401/403— authentication/authorization failure500— server error (includes API key validation failures)
Error response format:
{ "error": "error description" }// or{ "message": "error description" }Common errors:
| Error | Cause | Fix |
|---|---|---|
missing authorization token | No Authorization header | Add Bearer <API_KEY> header |
invalid api key format | Token doesn’t start with Bearer | Check header format |
api key is not active | Key was revoked | Generate a new key |
file size exceeds 50MB | Video/image too large | Compress or reduce resolution |
X-User-Fullname header is required | Missing required header | Add the header |
Common Gotchas
-
User fullname is an identifier, not a display name. Use email or UUID. It MUST be consistent across all requests for the same user — it’s used to look up enrollment data and consent.
-
Consent is per-user per-project. Once given, it persists. You don’t need to re-submit consent every session.
-
Auto-enrollment is silent. If storage consent isn’t given, enrollment doesn’t happen and no error is returned. Always ensure storage consent before the first
process-video. -
Session fullname is locked after first request. The first request in a session sets the user fullname. Subsequent requests with a different fullname will be rejected (403).
-
The phrase must match. The phrase passed to
process-videomust exactly match what was displayed to the user in the frontend SDK. Mismatches cause Visual Speech Recognition to fail. -
Face Match can reuse video. After
process-video, useX-Use-Prefilled-Video: true+X-Session-IDon/match-facesto avoid re-uploading the video. -
Webhook secret is shown only once. When creating a webhook, the secret is returned in the response. Store it immediately — it cannot be retrieved later (only rotated).
-
Services must be enabled on the API key. If your API key doesn’t include “Voice Recognition”, that service won’t run during
process-videoregardless of other settings.
Backend Implementation Checklist
When generating backend integration code, ensure:
- API key stored as environment variable / secret, never in source code
- All Biometry API calls made server-side (never from frontend)
-
X-User-Fullnameset to a consistent, unique user identifier -
X-Session-IDpassed to all requests within a session - Both consents (authorization + storage) submitted before first
process-video - Video received from frontend via your own upload endpoint
-
process-videoresponse’sscoring_result.statuschecked for pass/fail -
X-Auto-Enrollresponse header checked to confirm enrollment -
X-Removed-Servicesresponse header checked for consent issues -
X-Request-Idlogged for debugging and support requests - Error responses handled gracefully with user-friendly messages
- Session ended after the verification flow completes