Skip to content

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.com

Service 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 to
  • selected_services — which ML services are enabled (e.g., “Face Recognition”, “Voice Recognition”)
  • scores_id — optional custom scoring rules ID
  • id — 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:

HeaderRequiredDescription
AuthorizationYesBearer <API_KEY_JWT>
X-User-FullnameYes*Unique identifier for the end-user (email, username, or UUID). Used for consent lookup, enrollment, and transaction tracking.
X-Session-IDRecommendedSession ID from /sessions/start. Groups related operations.

*Required for all /api-gateway endpoints except /sessions/start.

Optional Headers

HeaderDescription
X-Action-TriggerWhat triggered this action: "authentication", "registration", "confirmation"
X-Device-InfoJSON-encoded device metadata from the frontend SDK
X-Geo-LocationJSON-encoded {lat, lng, country, city}. Falls back to IP geolocation if omitted.
X-Request-TagsComma-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/start
Authorization: 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.

Before biometric processing, the end-user must have given two types of consent:

Authorization Consent — allows biometric processing:

POST /api-consent/consent
Authorization: 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-consent
Authorization: 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-video
Authorization: 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/support
  • X-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:

  1. Check scoring_result.status — is it "pass"?
  2. Check score — is it above your threshold?
  3. Check decision_reasons — understand why it passed/failed
  4. Decide whether to authenticate the user in YOUR system
  5. 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:

If both consents are given, Biometry automatically enrolls the user’s face and voice during process-video. No extra API calls needed.

  1. Ensure both consents are given (Step 2 above)
  2. Call process-video — enrollment happens in the background
  3. Check the X-Auto-Enroll: true response header to confirm

Option B: Explicit Enrollment

For more control, enroll face and voice separately:

Face Enrollment:

POST /api-gateway/enroll/face
Authorization: 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/voice
Authorization: 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/check
Authorization: Bearer <API_KEY>
X-User-Fullname: [email protected]
X-Session-ID: <session_id>
X-Inhouse-MRZ: true
Content-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-faces
Authorization: Bearer <API_KEY>
X-Session-ID: <session_id>
X-Use-Prefilled-Video: true
Content-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:

ServiceKey NameWhat It Does
Active Speaker DetectionActive Speaker DetectionVerifies the person in the video is actually speaking
Visual Speech RecognitionVisual Speech RecognitionReads lips to verify the spoken phrase matches
Face Liveness DetectionFace Liveness DetectionDetects if the face is live (not a photo/video replay)
Voice RecognitionVoice RecognitionIdentifies the speaker by voice (requires enrollment)
Face RecognitionFace RecognitionIdentifies 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:

  1. Custom scoring rules (if scores_id is set in the API key)
  2. Project-specific scoring rules (fallback)
  3. Default scoring rules (ultimate fallback)

Response fields:

  • scoring_result — detailed scoring breakdown
  • score — numeric confidence score (0-100)
  • decision_reasons — human-readable reasons for the decision
  • scoring_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 — success
  • 400 — bad request (missing fields, invalid file format, file too large)
  • 401/403 — authentication/authorization failure
  • 500 — server error (includes API key validation failures)

Error response format:

{ "error": "error description" }
// or
{ "message": "error description" }

Common errors:

ErrorCauseFix
missing authorization tokenNo Authorization headerAdd Bearer <API_KEY> header
invalid api key formatToken doesn’t start with Bearer Check header format
api key is not activeKey was revokedGenerate a new key
file size exceeds 50MBVideo/image too largeCompress or reduce resolution
X-User-Fullname header is requiredMissing required headerAdd the header

Common Gotchas

  1. 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.

  2. Consent is per-user per-project. Once given, it persists. You don’t need to re-submit consent every session.

  3. 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.

  4. 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).

  5. The phrase must match. The phrase passed to process-video must exactly match what was displayed to the user in the frontend SDK. Mismatches cause Visual Speech Recognition to fail.

  6. Face Match can reuse video. After process-video, use X-Use-Prefilled-Video: true + X-Session-ID on /match-faces to avoid re-uploading the video.

  7. 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).

  8. Services must be enabled on the API key. If your API key doesn’t include “Voice Recognition”, that service won’t run during process-video regardless 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-Fullname set to a consistent, unique user identifier
  • X-Session-ID passed 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-video response’s scoring_result.status checked for pass/fail
  • X-Auto-Enroll response header checked to confirm enrollment
  • X-Removed-Services response header checked for consent issues
  • X-Request-Id logged for debugging and support requests
  • Error responses handled gracefully with user-friendly messages
  • Session ended after the verification flow completes