Face Matching API

Advanced biometric identification with 1:1 verification and 1:n search capabilities.

Base URL

https://api.zaits.net/v1/face-matching

Authentication

All requests require your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Tenant Isolation

How It Works

Zaits Customer A (API Key: acme_key_123)
├─ Subject: "EMP-001" → John Smith
├─ Subject: "EMP-002" → Jane Doe
└─ Subject: "EMP-003" → Bob Johnson

Zaits Customer B (API Key: beta_key_456)
├─ Subject: "CUST-A" → Alice Williams
├─ Subject: "CUST-B" → Charlie Brown
└─ Subject: "CUST-C" → Diana Prince

❌ Customer A can NEVER access Customer B's data
✅ Each customer has their own isolated face database

Enroll Face

Register a face in the database for future 1:n identification.

Endpoint

POST /v1/face-matching/enroll

Parameters

Parameter
Type
Required
Description

image

file

Face image to enroll

subject_id

string

Your app's user identifier (employee ID, customer ID, etc.)

quality_score

number

Image quality score (0-1)

liveness_score

number

Liveness detection score (0-1)

enrollment_source

string

Source of enrollment (e.g., "registration", "manual")

metadata

object

Custom metadata (employee info, department, etc.)

Understanding subject_id:

  • subject_id is YOUR application's user identifier (not a Zaits user ID)

  • Examples: employee ID ("EMP-001"), customer number ("CUST-456"), badge number ("B-8472")

  • Each Zaits customer has their own isolated namespace - your data never mixes with other customers

  • Use metadata to store additional user information (name, department, etc.)

Request Examples

curl -X POST https://api.zaits.net/v1/face-matching/enroll \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "subject_id=EMP-001" \
  -F "image=@employee_photo.jpg" \
  -F "quality_score=0.95" \
  -F "liveness_score=0.88" \
  -F "enrollment_source=hr_registration" \
  -F 'metadata={"name":"John Smith","department":"Engineering","badge":"B-8472"}'

Response

{
  "success": true,
  "embeddingId": "550e8400-e29b-41d4-a716-446655440000",
  "subjectId": "EMP-001",
  "embeddingDimension": 512,
  "processing_time": 0.85
}

Response Fields:

  • embeddingId - Unique ID for this face embedding

  • subjectId - Your app's user identifier that was enrolled

  • embeddingDimension - Vector dimensions (always 512 for ArcFace)

  • processing_time - Time taken to process in seconds


Search Faces (1:n Matching)

Find matching faces in the enrolled database.

Endpoint

POST /v1/face-matching/search

Parameters

Parameter
Type
Required
Description

image

file

Face image to search for

threshold

number

Similarity threshold (0-1, default: 0.6)

limit

number

Maximum results to return (default: 10)

Request Example

curl -X POST https://api.zaits.net/v1/face-matching/search \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@unknown_face.jpg" \
  -F "threshold=0.7" \
  -F "limit=5"

Response

{
  "success": true,
  "matches": [
    {
      "id": "embedding-id",
      "subject_id": "EMP-001",
      "similarity": 0.8523,
      "quality_score": 0.95,
      "liveness_score": 0.88,
      "enrollment_source": "registration",
      "metadata": {
        "name": "John Smith",
        "department": "Engineering",
        "badge": "B-8472",
        "label": "Employee Badge",
        "location": "HR Office"
      },
      "created_at": "2025-01-11T10:00:00Z"
    }
  ],
  "matchCount": 1,
  "thresholdUsed": 0.7,
  "processing_time": 1.23
}

Response Fields:

  • subject_id - Your app's user identifier (e.g., employee ID, customer number)

  • similarity - Match confidence score (0-1), higher is better

  • quality_score - Original enrollment image quality (0-1)

  • liveness_score - Liveness detection score from enrollment (0-1)

  • enrollment_source - Where this face was enrolled (e.g., "registration", "testing")

  • metadata - Custom data you stored during enrollment (name, department, etc.)

  • created_at - When this face was enrolled


Verify Face (1:1 Matching)

Verify if a face matches a specific subject's enrolled faces.

Endpoint

POST /v1/face-matching/verify/:subjectId

Parameters

Parameter
Type
Required
Description

subjectId

string

Subject ID to verify against (path parameter)

image

file

Face image to verify

threshold

number

Similarity threshold (default: 0.6)

Subject ID in Verification:

  • Use the same subject_id that was used during enrollment

  • Example: If you enrolled "EMP-001", verify against "EMP-001"

  • The verification is automatically scoped to your tenant (API key)

Request Example

curl -X POST https://api.zaits.net/v1/face-matching/verify/EMP-001 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@verification_selfie.jpg" \
  -F "threshold=0.7"

Response

{
  "success": true,
  "verified": true,
  "similarity": 0.8523,
  "threshold": 0.7,
  "embeddingId": "embedding-id-used",
  "enrollmentSource": "registration",
  "processing_time": 0.95
}

Get Tenant Embeddings

Retrieve all enrolled face embeddings for your tenant (all subjects enrolled under your API key).

Endpoint

GET /v1/face-matching/embeddings

Query Parameters

Parameter
Type
Required
Description

active_only

boolean

Only return active embeddings (default: true)

subject_id

string

Filter embeddings for a specific subject ID

Request Examples

curl -X GET 'https://api.zaits.net/v1/face-matching/embeddings?active_only=true' \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "success": true,
  "embeddings": [
    {
      "id": "embedding-id",
      "subject_id": "EMP-001",
      "quality_score": 0.95,
      "liveness_score": 0.88,
      "enrollment_source": "registration",
      "created_at": "2025-01-11T10:00:00Z",
      "verification_count": 15,
      "last_verified_at": "2025-01-11T14:30:00Z"
    }
  ],
  "count": 1
}

Response Fields:

  • subject_id - Your app's user identifier for this embedding

  • quality_score - Image quality score (0-1)

  • liveness_score - Liveness detection score (0-1)

  • enrollment_source - Source of enrollment

  • verification_count - Number of successful verifications

  • last_verified_at - Timestamp of last successful verification


Delete Embeddings

Delete face embeddings for your tenant.

Delete Specific Embedding

DELETE /v1/face-matching/embeddings/:embeddingId

Delete All Embeddings for Tenant

DELETE /v1/face-matching/embeddings

Delete All Embeddings for Specific Subject

DELETE /v1/face-matching/embeddings?subject_id=:subjectId

Request Examples

curl -X DELETE https://api.zaits.net/v1/face-matching/embeddings/embedding-id \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "success": true,
  "message": "Face embedding deleted successfully"
}

Similarity Thresholds

Choose the appropriate threshold based on your security requirements:

Threshold
Use Case
Security Level
Description

0.4 - 0.5

High security (banking, medical)

Very strict

May reject some valid matches

0.6

Recommended

Balanced

Good accuracy/security balance

0.7 - 0.8

Low security (social apps)

Permissive

May allow some false matches

Threshold Recommendations

// Banking/Financial Services
const BANKING_THRESHOLD = 0.4;

// Corporate Access Control
const ACCESS_CONTROL_THRESHOLD = 0.6;

// Social/Consumer Apps
const SOCIAL_THRESHOLD = 0.75;

Use Cases

1. Employee Access Control

// Enroll employee during registration
const formData = new FormData();
formData.append('subject_id', 'EMP-12345');  // Employee ID from your system
formData.append('image', employeePhoto);
formData.append('metadata', JSON.stringify({
  name: 'John Smith',
  department: 'Engineering',
  label: 'Employee Badge',
  location: 'Building A - Security',
  notes: 'Access level: Standard'
}));

const enrollResult = await fetch('https://api.zaits.net/v1/face-matching/enroll', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: formData
});

// Verify at entrance using 1:n search
const searchData = new FormData();
searchData.append('image', cameraImage);
searchData.append('threshold', '0.7');
searchData.append('limit', '1');

const searchResult = await fetch('https://api.zaits.net/v1/face-matching/search', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: searchData
}).then(r => r.json());

if (searchResult.matchCount > 0) {
  const employee = searchResult.matches[0];
  grantAccess(employee.subject_id);  // Use subject_id (EMP-12345)
  console.log(`Welcome, ${employee.metadata?.name || employee.subject_id}!`);
}

2. Customer Identification

// Enroll customer during first visit
const formData = new FormData();
formData.append('subject_id', 'CUST-789');  // Customer ID from your system
formData.append('image', customerPhoto);
formData.append('metadata', JSON.stringify({
  name: 'Jane Doe',
  membership: 'Gold',
  joined: '2024-01-15'
}));

await fetch('https://api.zaits.net/v1/face-matching/enroll', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: formData
});

// Search for returning customer
const searchData = new FormData();
searchData.append('image', customerPhoto);
searchData.append('threshold', '0.65');
searchData.append('limit', '5');

const result = await fetch('https://api.zaits.net/v1/face-matching/search', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: searchData
}).then(r => r.json());

if (result.matchCount > 0) {
  const customer = result.matches[0];
  console.log(`Welcome back, ${customer.metadata?.name}!`);
  loadLoyaltyInfo(customer.subject_id);  // Use subject_id (CUST-789)
}

3. Event Check-in (1:1 Verification)

// Enroll ticket holder during purchase
const formData = new FormData();
formData.append('subject_id', 'TICKET-12345');  // Ticket number
formData.append('image', ticketHolderPhoto);
formData.append('metadata', JSON.stringify({
  event: 'Concert 2024',
  section: 'VIP',
  seat: 'A-15'
}));

await fetch('https://api.zaits.net/v1/face-matching/enroll', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: formData
});

// Verify at entrance (1:1 verification)
const verifyData = new FormData();
verifyData.append('image', livePhoto);
verifyData.append('threshold', '0.7');

const verification = await fetch(
  'https://api.zaits.net/v1/face-matching/verify/TICKET-12345',
  {
    method: 'POST',
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
    body: verifyData
  }
).then(r => r.json());

if (verification.verified) {
  checkInAttendee('TICKET-12345');
  console.log('✅ Entry granted - ticket verified');
} else {
  console.log('❌ Entry denied - face does not match ticket holder');
}

Best Practices

Image Quality

  • Resolution: 640x640 or higher

  • Lighting: Well-lit, even lighting

  • Angle: Frontal face, minimal rotation

  • Expression: Neutral expression preferred

Enrollment Strategy

  • Enroll 2-3 images per user for better accuracy

  • Use different lighting conditions

  • Include slight angle variations

  • Check liveness before enrollment

Security

  • Always use liveness detection before enrollment

  • Implement rate limiting on verification endpoints

  • Log all face matching operations for audit

  • Use appropriate thresholds for your use case

Performance

  • Cleanup old embeddings periodically

  • Keep 3-5 most recent enrollments per user

  • Use indexed searches for large databases

  • Cache frequent verification results


Next: OCR API Documentation

Last updated