A Python demonstration script showcasing the complete Know Your Customer (KYC) flow using the 2FACE API. This script provides a practical, developer-friendly example of how to integrate document validation, information extraction, and face comparison capabilities.
This demo implements a complete KYC verification workflow:
- Session Management - Creates and manages API sessions
- Document Validation - Validates that an image contains a valid CEDULA (Dominican ID card)
- Information Extraction - Extracts personal information from the document
- Face Comparison - Compares a selfie against the document photo
- Asynchronous Processing - Handles async jobs with intelligent polling
- Modular Architecture - Clean, reusable functions for each API endpoint
- Environment-Based Config - Easy configuration via
.envfile - Robust Error Handling - Comprehensive error messages and graceful failures
- Async Job Polling - Automatic polling with configurable timeouts
- Detailed Logging - Progress tracking and debugging information
- Type Hints - Full type annotations for better IDE support
- Python 3.7 or higher
- Valid 2FACE API credentials and endpoint URL
- Test images (CEDULA and selfie)
pip install -r requirements.txtCopy the example environment file and fill in your values:
cp .env.example .envEdit .env with your configuration:
TWOFACE_API_URL=https://your-api-url.com
CEDULA_IMAGE_PATH=/path/to/cedula.jpg
SELFIE_IMAGE_PATH=/path/to/selfie.jpgpython kyc_demo.py| Variable | Required | Description |
|---|---|---|
TWOFACE_API_URL |
β Yes | Base URL for the 2FACE API |
TWOFACE_API_KEY |
β Yes | API key for authentication (create via admin panel) |
CEDULA_IMAGE_PATH |
β Yes | Path to CEDULA image file |
SELFIE_IMAGE_PATH |
β Yes | Path to selfie image file |
LOG_LEVEL |
β No | Logging level (default: INFO) |
MAX_JOB_WAIT |
β No | Max wait time for jobs in seconds (default: 120) |
POLL_INTERVAL |
β No | Polling interval in seconds (default: 2) |
LOG_JOB_RESULTS |
β No | Set to true to print full JSON results of jobs |
CEDULA Image:
- Clear, well-lit photo of the front of a Dominican ID card
- Supported formats: JPG, JPEG, PNG
- Recommended: Minimum 800x600 resolution
Selfie Image:
- Clear frontal face photo
- Good lighting, no shadows
- Face should be clearly visible
- Supported formats: JPG, JPEG, PNG
The script executes the following steps:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Create Session β
β POST /session β
β β Returns: session_id β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. Validate Document Type β
β POST /documents/validate-document-type β
β β Returns: job_id β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. Poll Job Status β
β GET /jobs/{job_id} β
β β Wait until: status = 2 (Succeded) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. Fetch Document Information β
β POST /documents/fetch-document-data β
β β Returns: job_id β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. Poll Job Status β
β GET /jobs/{job_id} β
β β Wait until: status = 2 (Succeded) β
β β Extract: document_id β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 6. Compare Face to Document β
β POST /faces/compare-to-document β
β β Returns: job_id β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 7. Poll Job Status β
β GET /jobs/{job_id} β
β β Wait until: status = 2 (Succeded) β
β β Returns: similarity score (>50% = match) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 8. Close Session β
β POST /session/close β
β β status: SUCCESS or FAILED β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
You can also import and use the KYCClient class in your own code:
from kyc_demo import KYCClient, KYCAPIError
# Initialize client
client = KYCClient("https://api.2face.example.com")
try:
# Create session
session_id = client.create_session("SIGNUP")
# Validate document
job_id = client.validate_document_type("/path/to/cedula.jpg")
result = client.poll_job_status(job_id)
# Fetch document data
job_id = client.fetch_document_data("/path/to/cedula.jpg")
result = client.poll_job_status(job_id)
# Compare face
job_id = client.compare_face_to_document("/path/to/selfie.jpg", "DOC123")
result = client.poll_job_status(job_id)
# Close session
client.close_session("SUCCESS")
except KYCAPIError as e:
print(f"Error: {e}")
if client.session_id:
client.close_session("FAILED")2025-12-01 21:56:00 - INFO - ======================================================================
2025-12-01 21:56:00 - INFO - Starting KYC Flow
2025-12-01 21:56:00 - INFO - ======================================================================
2025-12-01 21:56:00 - INFO - [Step 1/6] Creating session...
2025-12-01 21:56:01 - INFO - β Session created successfully: abc123xyz
2025-12-01 21:56:01 - INFO - [Step 2/6] Validating document type...
2025-12-01 21:56:02 - INFO - β Document validation job created: job_456
2025-12-01 21:56:02 - INFO - [Step 3/6] Polling document validation job...
2025-12-01 21:56:02 - INFO - Poll #1 (0.5s): Status = PROCESSING
2025-12-01 21:56:04 - INFO - Poll #2 (2.5s): Status = COMPLETED
2025-12-01 21:56:04 - INFO - β Job completed successfully
... [additional steps] ...
2025-12-01 21:56:15 - INFO - ======================================================================
2025-12-01 21:56:15 - INFO - KYC Flow Completed Successfully!
2025-12-01 21:56:15 - INFO - ======================================================================
2025-12-01 21:56:15 - INFO - π Document Validation Result:
2025-12-01 21:56:15 - INFO - {'status': 'COMPLETED', 'isValid': True}
2025-12-01 21:56:15 - INFO - π Document Information:
2025-12-01 21:56:15 - INFO - {'documentId': '00112345678', 'firstName': 'Juan', ...}
2025-12-01 21:56:15 - INFO - π€ Face Comparison Result:
2025-12-01 21:56:15 - INFO - Similarity: 95.3
2025-12-01 21:56:15 - INFO - Match: True
2025-12-01 21:56:15 - INFO - β
KYC Demo completed successfully!
- Verify
TWOFACE_API_URLis correct - Check network connectivity
- Ensure API endpoint is accessible
- Verify image paths are absolute paths
- Check file permissions
- Ensure files exist at specified locations
- Increase
MAX_JOB_WAITin environment variables - Check if API is experiencing high load
- Verify images are not corrupted
- Ensure CEDULA image is clear and well-lit
- Check that document is fully visible in image
- Verify correct document type is specified
For detailed API documentation, refer to the 2FACE API Postman collection.
POST /session- Create sessionPOST /session/close- Close sessionPOST /documents/validate-document-type- Validate document typePOST /documents/fetch-document-data- Extract document informationPOST /faces/compare-to-document- Compare face to documentGET /jobs/{jobId}- Get job status
Per the official 2FACE documentation, the API provides two authentication methods:
- Preferred method for unattended production applications
- API keys created via company applications admin panel
- Passed as HTTP header:
Authorization: <api_key>(NOT a bearer token) - Used for endpoints that don't require a session
- Required for session-based KYC flow endpoints
- Created via
POST /sessionendpoint - Passed as HTTP header:
X-Tagshelf-Session: <token> - Used INSTEAD OF the API key (not in addition to)
How This Script Handles Authentication:
- Uses API key (
Authorizationheader) for:- Session creation (
POST /session) - Job polling (
GET /jobs/{jobId})
- Session creation (
- Uses session token (
X-Tagshelf-Sessionheader) for KYC flow endpoints:- Document validation, data extraction, face comparison
- Only one authentication method is used per request
Security Note: Don't expose your API key in client applications. API keys are meant for backend servers.
This is a demonstration script. Feel free to extend it for your specific use case.
This demo script is provided as-is for educational and integration purposes.
Senior Software Developer - 2025