Python client for the FaceVault identity verification API — privacy-first KYC with liveness detection, face matching, and document verification.
- Sync & async clients — use
FaceVaultClientorAsyncFaceVaultClient - Webhook verification — HMAC-SHA256 signature validation
- Typed models — dataclasses for sessions, status, and webhook events
- Secure by default — HTTPS enforced, API keys validated, secrets redacted from logs
- Lightweight — only depends on httpx
pip install facevaultfrom facevault import FaceVaultClient
client = FaceVaultClient("fv_live_your_api_key")
# Create a verification session
session = client.create_session(external_user_id="user-123")
print(session.webapp_url) # Send this URL to your user
# With proof of address required
session = client.create_session(external_user_id="user-123", require_poa=True)
# Check session status
status = client.get_session(session.session_id)
print(status.status) # "in_progress", "passed", "failed", "review"
print(status.trust_score) # 0-100 trust score
print(status.trust_decision) # "accept", "review", "reject"
client.close()from facevault import AsyncFaceVaultClient
async def verify_user():
async with AsyncFaceVaultClient("fv_live_your_api_key") as client:
session = await client.create_session(external_user_id="user-123")
print(session.webapp_url)from facevault import verify_signature, parse_event
# Verify the webhook signature
body = request.body
signature = request.headers["X-Signature"]
if verify_signature(body, signature, secret="your_webhook_secret"):
event = parse_event(body)
print(event.event) # "verification.completed"
print(event.session_id)
print(event.face_match_passed)
print(event.trust_score) # 0-100
print(event.trust_decision) # "accept", "review", "reject"
print(event.sanctions_hit) # True/Falsefrom facevault import FaceVaultClient, AuthError, NotFoundError, RateLimitError
client = FaceVaultClient("fv_live_your_api_key")
try:
session = client.get_session("nonexistent")
except AuthError:
print("Invalid API key")
except NotFoundError:
print("Session not found")
except RateLimitError:
print("Too many requests")The SDK enforces security best practices out of the box:
- HTTPS only —
http://URLs are rejected at init to prevent credentials leaking over plaintext - Key validation — empty or whitespace-only API keys raise
ValueErrorimmediately - Secret redaction —
Session.__repr__maskssession_tokenand URL tokens, safe for logging - Client redaction —
FaceVaultClient.__repr__masks the API key - Path traversal protection —
get_session()validates session IDs
require_poaparameter oncreate_session()— per-session proof of address overridetrust_scoreandtrust_decisiononSessionStatus— unified 0-100 trust scorerequire_poa,poa,anti_spoofing,credentialonSessionStatustrust_score,trust_decision,sanctions_hit,poaonWebhookEventchallenge_nonceonSession— capture integrity nonce