Official Python SDK for the FaceAPI — privacy-first face recognition
Project description
faceapi-client
Official Python SDK for the FaceAPI — a privacy-first face recognition service.
- No images ever stored — only AES-256 encrypted face descriptors
- Anti-replay protection built in (nonces handled automatically)
- Multi-tenant collections — one key, many isolated user pools
- GDPR purge endpoint included
Live API: https://face-recognition-api-om7k.onrender.com
Get your free API key: https://face-recognition-api-om7k.onrender.com/portal/
Interactive docs: https://face-recognition-api-om7k.onrender.com/docs/
Installation
pip install faceapi-client
You also need a face recognition library to extract descriptors from images. The most common:
pip install face-recognition
face-recognitionrequirescmakeanddlib. On Mac:brew install cmake. On Ubuntu:sudo apt install cmake.
Get an API Key
- Go to https://face-recognition-api-om7k.onrender.com/portal/register/
- Create a free account
- Click New Key on the dashboard
- Copy your key — it starts with
fk_live_and is shown only once
Quick Start
import face_recognition
from faceapi import FaceAPIClient
client = FaceAPIClient(api_key="fk_live_your_key_here")
# 1. Extract descriptor from a photo (runs locally — no photo sent to API)
image = face_recognition.load_image_file("photo.jpg")
descriptor = face_recognition.face_encodings(image)[0].tolist()
# 2. Enroll a face
result = client.enroll(descriptor=descriptor, label="john_doe")
face_id = result.face_id # save this in your database
# 3. Verify — is this the same person?
result = client.verify(descriptor=descriptor, face_id=face_id)
print(result.verified) # True / False
print(result.confidence) # 0.93
# 4. Identify — who is this person?
result = client.identify(descriptor=descriptor)
print(result.label) # "john_doe"
print(result.confidence) # 0.91
Full API Reference
FaceAPIClient(api_key, base_url, timeout)
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str | required | Your API key (fk_live_...) |
base_url |
str | production URL | Override for self-hosted instances |
timeout |
int | 30 | Request timeout in seconds |
client = FaceAPIClient(api_key="fk_live_...")
client.enroll(descriptor, label, collection_id)
Enroll a face. Call this once per person and store the returned face_id.
| Parameter | Type | Required | Description |
|---|---|---|---|
descriptor |
list[float] | Yes | 128-float list from your face model |
label |
str | No | Human-readable ID (e.g. "emp_001") |
collection_id |
str | No | Namespace for tenant isolation |
result = client.enroll(
descriptor=descriptor,
label="alice",
collection_id="my_company",
)
print(result.face_id) # "3f2a1b..." — store this
print(result.enrolled) # True = new face, False = existing label updated
client.verify(descriptor, face_id, collection_id)
1:1 match — check if a face matches a specific enrolled face.
result = client.verify(
descriptor=descriptor,
face_id="3f2a1b...",
)
if result.verified:
print(f"Identity confirmed! Confidence: {result.confidence:.0%}")
else:
print("Face does not match")
| Field | Type | Description |
|---|---|---|
verified |
bool | True if faces match |
confidence |
float | Match score 0.0–1.0 |
threshold |
float | The threshold used for this key |
processing_ms |
int | Server-side processing time |
client.identify(descriptor, collection_id)
1:N search — find who this person is among all enrolled faces.
result = client.identify(
descriptor=descriptor,
collection_id="my_company", # search only this namespace
)
if result.identified:
print(f"Hello, {result.label}! Confidence: {result.confidence:.0%}")
else:
print("Unknown person — access denied")
| Field | Type | Description |
|---|---|---|
identified |
bool | True if a match was found |
label |
str | The matched person's label |
face_id |
str | The matched face_id |
confidence |
float | Match score 0.0–1.0 |
client.list_faces(collection_id)
List all enrolled faces for your API key.
result = client.list_faces(collection_id="my_company")
print(f"Total enrolled: {result.count}")
for face in result.faces:
print(face.face_id, face.label, face.enrolled_at)
client.delete_face(face_id)
Delete a single enrolled face permanently.
client.delete_face(face_id="3f2a1b...")
client.purge(collection_id)
Permanently delete all faces — useful for GDPR right-to-erasure.
# Delete one user's data only
result = client.purge(collection_id="user_123")
print(f"Deleted {result.deleted_count} faces")
# Delete everything for your API key
result = client.purge()
client.usage()
Check your API key usage and quota.
stats = client.usage()
print(f"Plan: {stats.tier}")
print(f"Used today: {stats.used_today} / {stats.daily_limit or 'unlimited'}")
print(f"Total requests: {stats.total_requests}")
print(f"Confidence threshold: {stats.confidence_threshold}")
Collections — Multi-Tenant Isolation
If your app serves multiple users or companies, use collection_id to keep their faces completely isolated from each other.
# Enroll faces under different tenants
client.enroll(descriptor=d1, label="alice", collection_id="company_a")
client.enroll(descriptor=d2, label="bob", collection_id="company_b")
# Identify only searches within the given collection
client.identify(descriptor=d1, collection_id="company_a") # finds alice
client.identify(descriptor=d1, collection_id="company_b") # finds nothing
Error Handling
from faceapi import (
FaceAPIClient,
AuthenticationError, # Invalid or revoked API key
RateLimitError, # Daily limit reached or IP locked
NotFoundError, # face_id not found
InvalidDescriptorError,# Descriptor must be 128 floats
NonceError, # Nonce expired or already used
FaceAPIError, # Base class for all errors
)
try:
result = client.verify(descriptor=descriptor, face_id=face_id)
except AuthenticationError:
print("Check your API key")
except RateLimitError as e:
print(f"Slow down: {e}")
except NotFoundError:
print("face_id not found — was it deleted?")
except FaceAPIError as e:
print(f"API error [{e.code}]: {e}")
Real-World Examples
Attendance System
import face_recognition
from faceapi import FaceAPIClient
client = FaceAPIClient(api_key="fk_live_...")
def enroll_employee(photo_path: str, employee_id: str) -> str:
image = face_recognition.load_image_file(photo_path)
descriptor = face_recognition.face_encodings(image)[0].tolist()
result = client.enroll(descriptor=descriptor, label=employee_id, collection_id="staff")
return result.face_id
def clock_in(photo_path: str):
image = face_recognition.load_image_file(photo_path)
descriptor = face_recognition.face_encodings(image)[0].tolist()
result = client.identify(descriptor=descriptor, collection_id="staff")
if result.identified:
print(f"Welcome, {result.label}! Clocked in.")
else:
print("Face not recognized. Access denied.")
enroll_employee("john.jpg", "EMP001")
clock_in("camera.jpg")
Door Access Control
def check_access(camera_frame_path: str, allowed_face_ids: list) -> bool:
image = face_recognition.load_image_file(camera_frame_path)
descriptor = face_recognition.face_encodings(image)[0].tolist()
for face_id in allowed_face_ids:
result = client.verify(descriptor=descriptor, face_id=face_id)
if result.verified:
print(f"Access granted (confidence: {result.confidence:.0%})")
return True
print("Access denied")
return False
Delete a User's Data (GDPR)
def delete_user(user_id: str):
result = client.purge(collection_id=user_id)
print(f"Deleted {result.deleted_count} face records for user {user_id}")
Pricing
| Tier | Requests/day | Price |
|---|---|---|
| Free | 100 | $0 forever |
| Pro | 10,000 | $29/month |
| Enterprise | Unlimited | Contact us |
Get started free: https://face-recognition-api-om7k.onrender.com/portal/
Support
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file faceapi_client-1.0.1.tar.gz.
File metadata
- Download URL: faceapi_client-1.0.1.tar.gz
- Upload date:
- Size: 7.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9bcd3acf082f2e1436c88cd0d7bf8b68199faf969766d8b5d7307b86d74d24a
|
|
| MD5 |
b1c57a3f5b0b87face5f507ac0162000
|
|
| BLAKE2b-256 |
635028b07ec781245f5e2f995f4ba2a76d81c5c5c1060aadc6c0b46bd270df22
|
File details
Details for the file faceapi_client-1.0.1-py3-none-any.whl.
File metadata
- Download URL: faceapi_client-1.0.1-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe3c6e6546d71216f65f9601545bea797a1d6a3089051e56f5f0779284449222
|
|
| MD5 |
b3b67ccd56179e95b4e6eb73aeae5235
|
|
| BLAKE2b-256 |
65bb5627247d6aec075d47b4bef8c64bdcc46f6d34ea75bf8fe883829172bb40
|