Agent KYC API Documentation
Complete API Reference for Document Extraction, Face Matching & Liveness Detection
Version 3.0.0
📥 Download as PDF
🌐 Base Information
Base URL
[Link]
Content Type
multipart/form-data
Supported Document Types
PAN Card (India)
Aadhaar Card (India)
Driving License (India)
Voter ID (India)
Passport (India)
📄 1. Document Extraction
POST /api/extract-document
Description: Extracts text and structured data from identity documents using GPT-4o Vision.
Automatically detects document type and extracts relevant fields.
Request Parameters
Parameter Type Required Description
document_image File Yes Image file of the document (JPEG, PNG)
customer_id String No Unique identifier for the customer
save_to_db Boolean No Save result to database (default: false)
Example Request (cURL)
curl -X POST "[Link] \
-F "document_image=@/path/to/pan_card.jpg" \
-F "customer_id=CUST12345" \
-F "save_to_db=true"
Example Request (Python)
import requests
url = "[Link]
files = {
'document_image': open('pan_card.jpg', 'rb')
}
data = {
'customer_id': 'CUST12345',
'save_to_db': 'true'
}
response = [Link](url, files=files, data=data)
print([Link]())
Success Response (200 OK)
{
"success": true,
"document_type": "PAN",
"extracted_data": {
"pan_number": "ABCDE1234F",
"name": "RAJESH KUMAR SHARMA",
"father_name": "VIJAY KUMAR SHARMA",
"date_of_birth": "15/08/1990"
},
"raw_text": "INCOME TAX DEPARTMENT\nPermanent Account Number Card\n...",
"confidence": 0.95,
"processing_time_seconds": 2.34,
"timestamp": "2026-01-06T10:30:45.123456",
"extraction_id": 123,
"customer_id": "CUST12345"
}
Response Fields
Field Type Description
success Boolean Indicates if extraction was successful
document_type String Detected document type (PAN, AADHAAR, etc.)
extracted_data Object Structured data extracted from document
raw_text String All visible text from the document
confidence Float Confidence score (0.0 to 1.0)
processing_time_seconds Float Time taken to process the request
Error Response (500 Internal Server Error)
{
"detail": "Document extraction failed: No text detected in image"
}
📌 Note: The extracted_data fields vary based on document type. For example, Aadhaar includes
address and gender, while PAN includes father's name.
👤 2. Face Matching
POST /api/match-faces
Description: Detects faces in both reference (selfie) and document images, crops the document face,
and performs facial recognition matching. Returns similarity score and matched face images.
Request Parameters
Parameter Type Required Description
reference_image File Yes Selfie/live photo of the person
document_image File Yes Document image containing a face photo
customer_id String No Unique identifier for the customer
save_to_db Boolean No Save result to database (default: false)
return_images Boolean No Return base64 images in response (default: true)
Example Request (cURL)
curl -X POST "[Link] \
-F "reference_image=@/path/to/[Link]" \
-F "document_image=@/path/to/pan_card.jpg" \
-F "customer_id=CUST12345" \
-F "save_to_db=true" \
-F "return_images=true"
Example Request (Python)
import requests
url = "[Link]
files = {
'reference_image': open('[Link]', 'rb'),
'document_image': open('pan_card.jpg', 'rb')
}
data = {
'customer_id': 'CUST12345',
'save_to_db': 'true',
'return_images': 'true'
}
response = [Link](url, files=files, data=data)
result = [Link]()
print(f"Match: {result['is_match']}")
print(f"Similarity: {result['similarity_score']}%")
Success Response (200 OK)
{
"success": true,
"is_match": true,
"similarity_score": 87.45,
"face_distance": 0.1255,
"threshold_used": 0.6,
"status": "Faces Match",
"confidence_level": "high",
"face_detection": {
"reference_face_detected": true,
"document_face_detected": true,
"document_face_location": {
"top": 120,
"right": 380,
"bottom": 320,
"left": 180
}
},
"images": {
"reference_image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"document_face_cropped": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"image_size": "150x150"
},
"processing_time_seconds": 1.87,
"timestamp": "2026-01-06T10:35:22.789012",
"face_match_id": 456,
"customer_id": "CUST12345"
}
Response Fields
Field Type Description
is_match Boolean Whether faces match (based on threshold)
similarity_score Float Similarity percentage (0-100)
face_distance Float Face distance metric (lower = more similar)
threshold_used Float Threshold used for matching (default: 0.6)
status String Human-readable match status
confidence_level String very_high, high, medium, or low
images Object Base64 encoded images (if return_images=true)
Confidence Levels
Level Face Distance Description
very_high < 0.4 Faces Perfectly Match
high 0.4 - 0.6 Faces Match
medium 0.6 - 0.7 Faces Possibly Match
low > 0.7 Faces Do Not Match
Error Responses
// No face in reference image
{
"detail": "No face detected in reference image (selfie)"
}
// No face in document
{
"detail": "No face detected in document image"
}
// Face encoding failed
{
"detail": "Could not encode face from document"
}
⚠️ Important: Both images must contain clearly visible faces. Poor lighting, blurry images, or obscured
faces will result in detection failures.
🎥 3. Liveness Detection
POST /api/liveness-check
Description: Performs liveness detection by analyzing multiple video frames to determine if the subject
is a live person rather than a photo or video replay. Detects motion, depth, and natural variations.
Request Parameters
Parameter Type Required Description
video_frames File[] Yes Array of video frame images (min 3, max 30)
customer_id String No Unique identifier for the customer
save_to_db Boolean No Save result to database (default: false)
Example Request (cURL)
curl -X POST "[Link] \
-F "video_frames=@frame_001.jpg" \
-F "video_frames=@frame_002.jpg" \
-F "video_frames=@frame_003.jpg" \
-F "video_frames=@frame_004.jpg" \
-F "video_frames=@frame_005.jpg" \
-F "customer_id=CUST12345" \
-F "save_to_db=true"
Example Request (Python)
import requests
import os
url = "[Link]
# Prepare multiple frames
frame_files = []
frame_folder = "video_frames"
for i in range(1, 6): # 5 frames
frame_path = [Link](frame_folder, f"frame_{i:03d}.jpg")
frame_files.append(('video_frames', open(frame_path, 'rb')))
data = {
'customer_id': 'CUST12345',
'save_to_db': 'true'
}
response = [Link](url, files=frame_files, data=data)
result = [Link]()
# Close files
for _, file in frame_files:
[Link]()
print(f"Live: {result['is_live']}")
print(f"Confidence: {result['confidence']}")
Success Response (200 OK) - Live Person
{
"success": true,
"is_live": true,
"confidence": 0.92,
"checks_performed": [
"face_detection",
"motion_analysis",
"texture_analysis",
"eye_blink_detection"
],
"frames_analyzed": 5,
"frames_received": 5,
"message": "Liveness confirmed: Real person detected",
"processing_time_seconds": 3.45,
"timestamp": "2026-01-06T10:40:15.234567",
"liveness_id": 789,
"customer_id": "CUST12345"
}
Success Response (200 OK) - Spoof Detected
{
"success": true,
"is_live": false,
"confidence": 0.35,
"checks_performed": [
"face_detection",
"motion_analysis",
"texture_analysis"
],
"frames_analyzed": 5,
"frames_received": 5,
"message": "Spoof detected: Not a live person",
"processing_time_seconds": 3.21,
"timestamp": "2026-01-06T10:42:30.456789"
}
Response Fields
Field Type Description
is_live Boolean Whether the subject is a live person
confidence Float Confidence score (0.0 to 1.0)
checks_performed Array List of liveness checks performed
frames_analyzed Integer Number of frames actually processed
frames_received Integer Total frames received in request
message String Human-readable result message
Liveness Checks Performed
face_detection: Ensures face is present in all frames
motion_analysis: Detects natural head movement
texture_analysis: Analyzes skin texture for realness
eye_blink_detection: Detects natural eye blinking
depth_analysis: Checks for 3D depth information
Error Response (400 Bad Request)
{
"detail": "Minimum 3 frames required, received 2"
}
💡 Best Practices: