API Endpoints
This guide details the available endpoints in the ThirdFactor AI API Gateway v0.1.0.
Overview
ThirdFactor.ai provides AI-powered identity verification and document understanding services through this secure API gateway.
- Base URL
https://<CUSTOM_URL>— issued to your organisation by ThirdFactor.ai.- Authentication
HTTP Bearer Token — issued to your organisation by ThirdFactor.ai.
Authorization: Bearer <YOUR_ACCESS_TOKEN>
Content Types
Content-Type |
Used for |
|---|---|
|
Most image-as-base64 inputs |
|
JSON payloads (e.g., face comparison) |
|
File uploads (e.g., raw image conversion) |
HTTP Status Codes
Code |
Meaning |
|---|---|
200 |
Success |
401 |
Authentication error |
422 |
Input validation failed |
500 |
Internal server error |
All requests are authenticated and encrypted over HTTPS. API tokens must be kept confidential.
Note regarding Image Inputs: All endpoints that accept image data (detect face, compare face, etc.) require the images to be uploaded in Base64 format. This design ensures consistent handling of image data across various client platforms and network environments, simplifying the JSON payload structure.
Error Model
Sample validation error (HTTP 422):
{
"detail": [
{
"loc": ["body", "field_name"],
"msg": "Field is required",
"type": "value_error.missing"
}
]
}
—
1. Health Check
Verifies that the API service is operational.
Method:
GETEndpoint:
/healthAuth: Not required
Headers
Response (200 OK)
{
"status": "healthy",
"service": "thirdfactor-ai-gateway"
}
2. Image to Base64
Converts an uploaded image file into a base64 string. Use this if your client application needs to convert files before sending them to the analysis endpoints.
Method:
POSTEndpoint:
/image-to-base64/Auth: Required
Content-Type:
multipart/form-data
Form Data
Key |
Type |
Required |
Description |
|---|---|---|---|
|
File |
Yes |
Image file to convert. |
Response (200 OK)
{
"data_url": "data:image/jpeg;base64,/9j/4AAQ...",
"content_type": "image/jpeg",
"filename": "uploaded_image.jpg"
}
3. Detect Face
Detects faces and optional attributes (age range, gender, occlusion, etc.).
Method:
POSTEndpoint:
/detect-face/Auth: Required
Content-Type:
application/x-www-form-urlencoded
Body Parameters
Response (200 OK — faces found)
{
"result": true,
"total_faces": 1,
"faces": [
{
"confidence": 0.84,
"age_range": { "min_age": 27, "max_age": 32, "detected_age": 29 },
"gender": "Male",
"occluded": false
}
]
}
Response (200 OK — no faces found)
{ "result": false, "total_faces": 0, "faces": [] }
4. Analyze Liveness
Analyzes a video file to verify liveness and detecting potential spoofing attempts.
Method:
POSTEndpoint:
/api/analyze-livenessAuth: Not required
Content-Type:
multipart/form-data
Body Parameters (form-data)
Response (200 OK)
{
"analysis": {
"liveness_score": "0.70",
"antispoof_score": "1.00",
"blink_count": 0
},
"antispoof_score": "1.00",
"blink_count": 0,
"liveness_score": "0.70",
"frames": [
0: "data:image/jpeg;base64,/9j/4AAQ...",
1:"data:image/jpeg;base64,/9j/4AAQ..."
],
"is_live": true
}
5. Compare Face (1:1)
Compares two face images to verify if they belong to the same person.
Method:
POSTEndpoint:
/compare-face/Auth: Required
Content-Type:
application/json
Query Parameters
Key |
Default |
Description |
|---|---|---|
|
|
Similarity threshold (float) for matching. |
|
|
Optional liveness check (boolean). |
|
|
Check for face obstructions (boolean). |
Body (JSON Array)
[
"<BASE64_IMAGE_1>",
"<BASE64_IMAGE_2>"
]
Response (200 OK — match)
{
"verified": true,
"confidence": 98.5,
"percentage_match": 99.9
}
Response (200 OK — no match)
{
"verified": false,
"percentage_match": 0
}
6. Compare Face (1:N)
Performs a reverse search to find a face match within a pre-ingested database.
Method:
POSTEndpoint:
/api/face-reverse-searchAuth: Not required
Content-Type:
binary
Body
Binary File: Upload the image file as the raw body content.
Response (200 OK)
{
"matches": [
{
"id": 6,
"score": 0.0,
"metadata": {
"filename": "ingest_1764663714_user.jpg"
}
},
{
"id": 25,
"score": 0.32,
"metadata": {
"filename": "ingest_1768883379_FRONT.jpg"
}
}
],
"query_time_seconds": 1.38,
"search_time_seconds": 0.00007,
"query_image": "/static/uploads/query_1769539703.jpg",
"total_time_seconds": 1.39
}
7. Ingest Face (1:N Search)
Ingests an image into the database for future 1:N reverse face searches.
Method:
POSTEndpoint:
/batch_ingestContent-Type:
binary
Body
Binary File: Upload the image file as the raw body content.
Response (200 OK)
{
"results": [
{
"filename": "test.jpeg",
"id": 35
}
]
}
8. Detect & Crop Document
Automatically detects the type of document and returns a cropped image.
Method:
POSTEndpoint:
/type-of-document-crop/Auth: Required
Content-Type:
application/x-www-form-urlencoded
Supported Document Types:
The API recognises the following document types:
citizenship-front/citizenship-backdriving-licensepassport-front/passport-backpan-iddisability-idnational-idvoter-idforeign-passport
Body Parameters
Key |
Type |
Required |
Description |
|---|---|---|---|
|
string |
Yes |
Base64 encoded string of the document image. |
Response (200 OK)
{
"document_type": "national-id-front",
"score": 0.98,
"cropped_image": "data:image/jpeg;base64,/9j/..."
}
9. Analyze Document (OCR)
Performs OCR and structured information extraction from supported document types.
Method:
POSTEndpoint:
/document-extract-information/Auth: Required
Content-Type:
application/x-www-form-urlencoded
Body Parameters
Key |
Type |
Required |
Description |
|---|---|---|---|
|
string |
Yes |
Base64 encoded string of the document image. |
Response (200 OK)
{
"success": true,
"data": {
"id_number": "XXXX-XXXX-XXXX",
"name": "Jane Smith",
"address": "Sample Address",
"gender": "F",
"dob": { "year": "1995", "month": "07", "day": "10" },
"detected_type": "national-id",
"confidence": 0.97
}
}
10. Detect Forgery
Analyzes an image to detect potential manipulation or forgery.
Method:
POSTEndpoint:
/api/analyzeAuth: Not required
Content-Type:
multipart/form-data
Body Parameters (form-data)
Response (200 OK)
{
"is_forged": false,
"original_image": "/static/uploads/original_ID.png",
"highlighted_image": "/static/uploads/overlay_ID.png",
"analysis": {
"status": "AUTHENTIC",
"forgery_score": "0.13",
"details": "No manipulation detected"
}
}
11. Generate KYC URL (SDK)
Generates a dynamic URL for the ThirdFactor SDK authentication process. To use this endpoint, you must first generate a signed JWT token.
1. Generate JWT Token
Create a JWT token signed with HMAC SHA256 (HS256) using your provided Secret.
Header:
{ "alg": "HS256", "typ": "JWT" }
Payload:
{ "sub": "1234567890", "name": "Jane User", "iss": "<YOUR_ISSUER_ID>", "token": "<YOUR_TOKEN>", "iat": 1516239022, "identifier": "9888888888", "label": "Jane User", "secondary_label": "jane", "callback": "https://your-webhook.com/callback-id", "is_sdk": true }
callback: The URL where the results of the KYC Verification will be sent via webhook.
2. Make the Request
Method:
POSTRequest URL:
https://<thirdfactor_URL>/tfauth/get-kyc-url/Content-Type:
application/json
Request Body:
Include the generated JWT token in the JSON body.
{
"jwt_token": "<YOUR_GENERATED_JWT_TOKEN>"
}
Response (200 OK)
{
"url": "https://endpoint/tfauth/start?",
"remaining_credits": 97
}
Response (Error - Invalid Token)
{
"error": "Invalid token or token does not belong to tenant: <Org Name>"
}
Response (Error - Insufficient Credits)
{
"error": "Insufficient credits. Available credits: 0. 1 credit is required to generate KYC URL."
}
11.1 Webhook Notification (Full Payload)
When the KYC process is completed, the SDK server sends a notification to the callback URL specified in the payload. The payload provides a complete log of the detection and verification process.
Example Payload Structure:
{
"documentDetectionLog": [
{
"created_at": "2026-01-27 10:43:26.644142+00:00",
"is_verified": true,
"nationality": "nepali",
"document_number": "11111111",
"photo": "<BASE64_STRING_OF_SCANNED_DOC>",
"original_photo": "<BASE64_STRING_OF_ORIGINAL_FRAME>",
"claimed_doc_type": "citizenship-back",
"detected_doc_type": "citizenship-back",
"reason": "Valid Type"
},
{
"created_at": "2026-01-27 10:43:27.201931+00:00",
"is_verified": true,
"nationality": "nepali",
"document_number": "11111111",
"photo": "<BASE64_STRING>",
"original_photo": "<BASE64_STRING>",
"percentage_match": 64.7401,
"claimed_doc_type": "citizenship-front",
"detected_doc_type": "citizenship-front",
"reason": "Valid"
}
],
"documentPhoto": [
{
"created_at": "2026-01-27 10:43:26.644142+00:00",
"is_verified": true,
"nationality": "nepali",
"document_number": "11111111",
"photo": "<BASE64_STRING>",
"claimed_doc_type": "citizenship-back",
"detected_doc_type": "citizenship-back",
"reason": "Valid Type"
}
],
"gestureDetectionLog": [
{
"created_at": "2026-01-27 10:43:10.255518+00:00",
"is_verified": true,
"challenged_gesture": "Thumb_Down",
"detected_gesture": "Thumb_Down",
"percentage_match": 80.8998,
"photo": "<BASE64_STRING_OF_GESTURE>",
"reason": "Valid",
"is_passive_live": true,
"passive_score": 99.998
}
],
"faceDetectionLog": [
{
"created_at": "2026-01-27 10:42:58.538744+00:00",
"is_verified": false,
"photo": "<BASE64_STRING_OF_FACE>",
"age": "-1",
"gender": "N/A",
"reason": "Face Occluded or Blurry.",
"force_next": true
}
],
"nationality": "nepali",
"completed_at": "2026-01-27T10:43:27.882837+00:00",
"bypassed": 1,
"document_uplaod_retries": 2,
"session": "F7bgp2I",
"faceDetectionSuccess": false,
"document_number": "11111111",
"gestureSuccess": true,
"gender": "N/A",
"documentDetectionSuccess": true,
"in_progress": 0,
"age": -1,
"expires_at": "2026-01-29T18:24:26.141586+00:00",
"userPhoto": "<BASE64_STRING_OF_USER>",
"gesture_photo": "<BASE64_STRING>",
"gesture_challenge": [
"Thumb_Down"
],
"percentage_match": 64.7401,
"face_detection_retries": 1,
"allow_force_next": 1,
"started_at": "2026-01-27T10:42:46.141586+00:00",
"gesture_verification_retries": 1,
"label": "Jane User",
"secondary_label": "jane",
"identifier": "1715",
"jwt": "<JWT_TOKEN>",
"is_verified": true,
"forced_next": false,
"signature": "<SIGNATURE>"
}
Note: The
photo,original_photo,userPhoto, andgesture_photofields contain the full Base64 string of the respective images.
12. Generate KYC URL (SaaS with OCR)
This is the SaaS with OCR version of the KYC URL generation flow.
Use the same initialization flow as #11 for generating the JWT token, making the request, and handling remaining credits and error responses.
For the JWT payload:
If initiating on the web:
set
"is_sdk": falseinclude
"return_url": "https://yourapp.example.com/kyc/complete"
If initiating via Flutter SDK:
set
"is_sdk": truedo not include
return_url
12.1 Webhook Notification (Full Payload - SaaS with OCR)
When the KYC process is completed, the server sends a notification to the callback URL specified in the JWT payload. The SaaS + OCR flow returns a different payload shape (and includes additional OCR results).
Unicode rendering (Nepali): Some fields (e.g.
issue_date) may be returned in Nepali/Devanagari Unicode (sometimes serialized as escapes like"\u0968\u0966..."). Clients should treat the payload as UTF-8 and render these characters as-is.PII: The example below is redacted. Do not store or display raw PII (names, addresses, document numbers, IP addresses, JWTs, signatures) unless required and permitted by your compliance requirements.
Images (Base64): Any image fields are replaced with placeholders like
<BASE64_IMAGE_REDACTED>to indicate they are Base64 strings.
{
"ocr_image_results": [
{
"image_index": 0,
"page_identifier": "citizenship-front",
"page_title": "Citizenship Front Page",
"selected_nationality": "nepali",
"selected_document_type": "citizenship",
"is_front_page": true,
"is_photo_page": true,
"detected_type": "citizenship",
"normalized_document_type": "citizenship",
"success": true,
"found": true,
"is_document_valid": true,
"confidence": 0.9538843631744385,
"error": null,
"forgery_result": {
},
"forgery_checked": false,
"is_forged": false,
"forgery_decision": null,
"heatmap_image": null,
"forgery_error": null,
"data": {
"detected_type": "citizenship",
"id_number": "<string — Devanagari numerals, format: DD-CC-PP-NNNNNNN>",
"name": "<string — Devanagari script full name>",
"address": "<string — Devanagari script, ward/municipality/district>",
"dob": {
"year": "<string — unicode>",
"month": "<string — unicode>",
"day": "<string — unicode>"
},
"gender": "<string — Devanagari: पुरुष | महिला | अन्य>",
"fathers_name": "<string — Devanagari script>",
"mothers_name": "<string — Devanagari script>",
"place_of_issue": "<string — Devanagari script, district office name>"
},
"translations": {
"en": {
"detected_type": "citizenship",
"id_number": "<string>",
"name": "<string>",
"address": "<string>",
"gender": "<string>",
"fathers_name": "<string>",
"mothers_name": "<string>",
"place_of_issue": "<string>",
"dob": {
"year": "2052",
"month": "05",
"day": "18"
}
}
},
"faces": [
{
"confidence": 0.9996335506439209,
"facial_area": {
"x_min": 61.21208190917969,
"y_min": 239.77182006835938,
"x_max": 158.7705535888672,
"y_max": 337.3302917480469,
"left_eye": [
93,
274
],
"right_eye": [
129,
276
]
}
}
]
},
{
"image_index": 1,
"page_identifier": "citizenship-back",
"page_title": "Citizenship Back Page",
"selected_nationality": "nepali",
"selected_document_type": "citizenship",
"is_front_page": false,
"is_photo_page": false,
"detected_type": "citizenship-back",
"normalized_document_type": "citizenship-back",
"success": true,
"found": true,
"is_document_valid": true,
"confidence": 0.9573695659637451,
"error": null,
"forgery_result": {
},
"forgery_checked": false,
"is_forged": false,
"forgery_decision": null,
"heatmap_image": null,
"forgery_error": null,
"data": {
"detected_type": "citizenship-back",
"id_number": "<string>",
"name": "<string>",
"address": "<string>",
"dob": {
"year": "2050",
"month": "09",
"day": "12"
},
"gender": "<string>",
"issue_date": "<string — unicode>",
"issue_date_type": "BS"
},
"translations": null,
"faces": []
}
],
"ocr_frames": [
{
"index": 0,
"type": "citizenship-front",
"title": "Citizenship Front Page",
"image": "<image/jpeg>"
},
{
"index": 1,
"type": "citizenship-back",
"title": "Citizenship Back Page",
"image": "<image/jpeg>"
}
],
"gesture_verification_retries": 1,
"expires_at": "2026-04-28T06:15:47.961877+00:00",
"gender": "<string>",
"ocr_summary": {
"document_type": "citizenship",
"selected_document_type": "citizenship",
"selected_nationality": "nepali",
"detected_document_type": "citizenship",
"document_type_status": "Matched selected document type",
"confidence": 0.9573695659637451,
"is_document_valid": true,
"found": true,
"successful_images": 2,
"uploaded_image_count": 2,
"front_page_identifier": "citizenship-front",
"forgery_detected": false,
"forgery_checked_page_count": 0,
"forged_page_count": 0,
"forgery_decision": null,
"page_results": [
{
"image_index": 0,
"page_identifier": "citizenship-front",
"page_title": "Citizenship Front Page",
"selected_nationality": "nepali",
"selected_document_type": "citizenship",
"is_front_page": true,
"is_photo_page": true,
"detected_type": "citizenship",
"normalized_document_type": "citizenship",
"success": true,
"found": true,
"is_document_valid": true,
"confidence": 0.9538843631744385,
"error": null,
"forgery_result": {
},
"forgery_checked": false,
"is_forged": false,
"forgery_decision": null,
"heatmap_image": null,
"forgery_error": null,
"data": {
"detected_type": "citizenship",
"id_number": "<string — Devanagari numerals, format: DD-CC-PP-NNNNNNN>",
"name": "<string — Devanagari script full name>",
"address": "<string — Devanagari script, ward/municipality/district>",
"dob": {
"year": "<string — unicode>",
"month": "<string — unicode>",
"day": "<string — unicode>"
},
"gender": "<string — Devanagari: पुरुष | महिला | अन्य>",
"fathers_name": "<string — Devanagari script>",
"mothers_name": "<string — Devanagari script>",
"place_of_issue": "<string — Devanagari script, district office name>"
},
"translations": {
"en": {
"detected_type": "citizenship",
"id_number": "<string>",
"name": "<string>",
"address": "<string>",
"gender": "<string>",
"fathers_name": "<string>",
"mothers_name": "<string>",
"place_of_issue": "<string>",
"dob": {
"year": "2052",
"month": "05",
"day": "12"
}
}
},
"faces": [
{
"confidence": 0.9996335506439209,
"facial_area": {
"x_min": 61.21208190917969,
"y_min": 239.77182006835938,
"x_max": 158.7705535888672,
"y_max": 337.3302917480469,
"left_eye": [
93,
274
],
"right_eye": [
129,
276
]
}
}
]
},
{
"image_index": 1,
"page_identifier": "citizenship-back",
"page_title": "Citizenship Back Page",
"selected_nationality": "nepali",
"selected_document_type": "citizenship",
"is_front_page": false,
"is_photo_page": false,
"detected_type": "citizenship-back",
"normalized_document_type": "citizenship-back",
"success": true,
"found": true,
"is_document_valid": true,
"confidence": 0.9573695659637451,
"error": null,
"forgery_result": {
},
"forgery_checked": false,
"is_forged": false,
"forgery_decision": null,
"heatmap_image": null,
"forgery_error": null,
"data": {
"detected_type": "citizenship-back",
"id_number": "<string>",
"name": "<string>",
"address": "<string>",
"dob": {
"year": "2050",
"month": "09",
"day": "12"
},
"gender": "<string>",
"issue_date": "<string — unicode>",
"issue_date_type": "BS"
},
"translations": null,
"faces": []
}
],
"reviewed_document_type": "citizenship",
"reviewed_field_count": 5,
"face_match_page_identifier": "citizenship-front"
},
"ocr_extra_fields": {
"fathers_name": "<string — Devanagari script>",
"mothers_name": "<string — Devanagari script>",
"place_of_issue": "<string — Devanagari script, district office name>",
"issue_date": "<string — unicode>",
"issue_date_type": "BS"
},
"gesture_photo": "<image/jpeg>",
"ocr_data": {
"detected_type": "citizenship",
"id_number": "<string — Devanagari numerals, format: DD-CC-PP-NNNNNNN>",
"name": "<string — Devanagari script full name>",
"address": "<string — Devanagari script, ward/municipality/district>",
"dob": {
"year": "<string — unicode>",
"month": "<string — unicode>",
"day": "<string — unicode>"
},
"gender": "<string — Devanagari: पुरुष | महिला | अन्य>",
"fathers_name": "<string — Devanagari script>",
"mothers_name": "<string — Devanagari script>",
"place_of_issue": "<string — Devanagari script, district office name>",
"issue_date": "<string — unicode>",
"issue_date_type": "BS"
},
"document_forgery_results": [],
"userPhoto": "<image/jpeg>",
"documentDetectionLog": [
{
"created_at": "2026-04-28T05:51:51.450412+00:00",
"is_verified": true,
"photo": "<image/jpeg>",
"original_photo": "<image/jpeg>",
"nationality": "nepali",
"document_number": "<string — unicode>",
"percentage_match": 46.615300000000005,
"claimed_doc_type": "citizenship",
"detected_doc_type": "citizenship",
"reason": "Valid"
}
],
"session": "<string>",
"gesture_challenge": [
"Pointing_Up"
],
"ocr_review_field_keys": [
"id_number",
"name",
"address",
"dob",
"gender"
],
"completed_at": "2026-04-28T05:51:56.347779+00:00",
"document_forgery_summary": {
},
"percentage_match": 46.615300000000005,
"ocr_primary_image": "<image/jpeg>",
"ocr_review_fields_display": [
{
"key": "id_number",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "name",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "address",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "dob",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "gender",
"label": "<string>",
"value": "<string — unicode>"
}
],
"documentPhoto": [
{
"created_at": "2026-04-28T05:51:51.450412+00:00",
"is_verified": true,
"photo": "<image/jpeg>",
"original_photo": "<image/jpeg>",
"nationality": "nepali",
"document_number": "<string — unicode>",
"percentage_match": 46.615300000000005,
"claimed_doc_type": "citizenship",
"detected_doc_type": "citizenship",
"reason": "Valid"
}
],
"document_number": "<string — unicode>",
"in_progress": 0,
"ocr_extra_fields_display": [
{
"key": "fathers_name",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "mothers_name",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "place_of_issue",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "issue_date",
"label": "<string>",
"value": "<string — unicode>"
},
{
"key": "issue_date_type",
"label": "<string>",
"value": "BS"
}
],
"ocr_reviewed_fields": {
"id_number": "<string — Devanagari numerals, format: DD-CC-PP-NNNNNNN>",
"name": "<string — Devanagari script full name>",
"address": "<string — Devanagari script, ward/municipality/district>",
"dob": "<string — Devanagari numerals, BS date YYYY-MM-DD>",
"gender": "<string — Devanagari: पुरुष | महिला | अन्य>"
},
"gestureSuccess": true,
"ocr_document_type": "citizenship",
"age": 32,
"ocr_raw_results": [
{
"success": true,
"found": true,
"detected_type": "citizenship",
"data": {
"detected_type": "citizenship",
"id_number": "<string — Devanagari numerals, format: DD-CC-PP-NNNNNNN>",
"name": "<string — Devanagari script full name>",
"address": "<string — Devanagari script, ward/municipality/district>",
"dob": {
"year": "<string — unicode>",
"month": "<string — unicode>",
"day": "<string — unicode>"
},
"gender": "<string — Devanagari: पुरुष | महिला | अन्य>",
"fathers_name": "<string — Devanagari script>",
"mothers_name": "<string — Devanagari script>",
"place_of_issue": "<string — Devanagari script, district office name>"
},
"translations": {
"en": {
"detected_type": "citizenship",
"id_number": "<string>",
"name": "<string>",
"address": "<string>",
"gender": "<string>",
"fathers_name": "<string>",
"mothers_name": "<string>",
"place_of_issue": "<string>",
"dob": {
"year": "2052",
"month": "05",
"day": "18"
}
}
},
"is_document_valid": true,
"confidence": 0.9538843631744385,
"error": null,
"faces": [
{
"confidence": 0.9996335506439209,
"facial_area": {
"x_min": 61.21208190917969,
"y_min": 239.77182006835938,
"x_max": 158.7705535888672,
"y_max": 337.3302917480469,
"left_eye": [
93,
274
],
"right_eye": [
129,
276
]
}
}
],
"page_identifier": "citizenship-front",
"page_title": "Citizenship Front Page",
"selected_nationality": "nepali",
"selected_document_type": "citizenship",
"is_front_page": true,
"is_photo_page": true
},
{
"success": true,
"found": true,
"detected_type": "citizenship-back",
"data": {
"detected_type": "citizenship-back",
"id_number": "<string>",
"name": "<string>",
"address": "<string>",
"dob": {
"year": "2050",
"month": "09",
"day": "12"
},
"gender": "<string>",
"issue_date": "<string — unicode>",
"issue_date_type": "BS"
},
"translations": null,
"is_document_valid": true,
"confidence": 0.9573695659637451,
"error": null,
"faces": [],
"page_identifier": "citizenship-back",
"page_title": "Citizenship Back Page",
"selected_nationality": "nepali",
"selected_document_type": "citizenship",
"is_front_page": false,
"is_photo_page": false
}
],
"faceDetectionSuccess": true,
"faceDetectionLog": [
{
"created_at": "2026-04-28 05:50:57.985303+00:00",
"is_verified": true,
"age": 32,
"gender": "<string>",
"photo": "<image/jpeg>",
"reason": "Face Attributes Clearly Visible."
}
],
"ocr_face_match_page_identifier": "citizenship-front",
"documentDetectionSuccess": true,
"face_detection_retries": 1,
"_access_session_id": 16,
"ocr_document_face_image": "<string>",
"nationality": "nepali",
"ocr_selected_nationality": "nepali",
"document_upload_with_ocr_retries": 1,
"ocr_detected_document_type": "citizenship",
"ocr_selected_document_type": "citizenship",
"gestureDetectionLog": [
{
"created_at": "2026-04-28 05:51:13.332434+00:00",
"is_verified": true,
"challenged_gesture": "Pointing_Up",
"detected_gesture": "Pointing_Up",
"percentage_match": 82.0312,
"photo": "<image/jpeg>",
"reason": "Valid",
"is_passive_live": true,
"passive_score": 99.92410242557526
}
],
"ocr_face_match_image": "<image/jpeg>",
"started_at": "2026-04-28T05:50:47.961877+00:00",
"client_ip": "157.119.70.92",
"label": "<string>",
"secondary_label": "<string>",
"identifier": "<string>",
"jwt": "<string>",
"is_verified": true,
"forced_next": false,
"signature": "<string>"
}
13. KYB - Business Document Detection
Set of endpoints for detecting and validating business-related documents.
13.1 Single Inference
Detects business document class in a single uploaded image.
Method:
POSTEndpoint:
/api/v1/business_doc_detection/inference/singleContent-Type:
multipart/form-data
Parameters
Key |
Type |
Description |
|---|---|---|
|
File Text Number |
Required. The image file to analyze.
Optional. The expected class name for validaton.
Optional. Confidence threshold. Default: |
Response (200 OK)
{
"filename": "image.jpg",
"predicted_class": "business_vat_pan",
"expected_class": "business_vat_pan",
"confidence": 0.95,
"is_correct": true,
"bbox": [100, 150, 400, 500],
"output_path": "/app/media_files/results/image.jpg"
}
13.2 Folder Inference
Batch processes images within a specified folder path.
Method:
POSTEndpoint:
/api/v1/business_doc_detection/inference/folderContent-Type:
multipart/form-data
Parameters
Key |
Type |
Description |
|---|---|---|
|
Text Number |
Required. Path to the folder containing imgs
Optional. Confidence threshold. Default: |
Response (200 OK)
{
"total_images": 10,
"correct_predictions": 8,
"incorrect_predictions": 1,
"no_predictions": 1,
"files": [
{ "filename": "doc1.jpg", "predicted_class": "vat", "confidence": 0.98 },
{ "filename": "doc2.jpg", "predicted_class": "pan", "confidence": 0.92 }
]
}
13.3 Health Check (KYB)
Checks the status of the Business Document Detection service.
Method:
GETEndpoint:
/api/v1/business_doc_detection/health
Response (200 OK)
{ "status": "Ok" }
—
Security & Compliance
Transport Security — All traffic must use HTTPS (TLS 1.2+). Plain HTTP requests are rejected.
Transient Processing — Face and document data are processed transiently. No images are stored unless explicitly configured for audit logging.
Privacy Compliance — ThirdFactor.ai is mostly compliant with major privacy frameworks, including:
GDPR (General Data Protection Regulation)
Token Confidentiality — API Bearer tokens must be kept confidential and must never be exposed in client-side code or public repositories.