Identity Verification API
Programmatically create and manage identity verification sessions for individual entities. Send secure verification links via email, monitor progress in real-time, and retrieve validated identity data.
Create verification sessions, send secure links via email, and receive webhook notifications when verification completes. Extract verified identity data including name, date of birth, document details, and more.
Key Features
- Automated email delivery - Secure verification links sent directly to individuals
- Flexible profiles - Choose from basic, standard, or comprehensive checks
- Custom configurations - Define exact verification checks programmatically
- Real-time webhooks - Instant notifications for all verification events
Verification Session Object
A verification session represents a complete identity verification workflow for an individual entity.
Core Attributes
| Field | Type | Description |
|---|---|---|
session_id |
uuid | Unique identifier for the verification session |
entity_id |
uuid | ID of the individual entity being verified |
entity_name |
string | Name of the individual being verified |
status |
string | Workflow state: pending, accessed, completed, expired, revoked, failed |
outcome |
string | Verification result: pending, clear, consider, attention, issue, error |
failure_reason |
string | Reason for non-clear outcome (e.g., document_fake, face_mismatch) |
verification_url |
string | Secure verification link (token not included for security) |
email_sent |
boolean | Whether verification email was sent |
created_at |
datetime | Session creation timestamp (ISO 8601) |
accessed_at |
datetime | When user first opened verification link |
completed_at |
datetime | When verification completed |
expires_at |
datetime | Link expiration timestamp (default: 48 hours) |
Status Values
| Status | Description |
|---|---|
pending |
Session created, link not yet accessed |
accessed |
User opened verification link |
completed |
All checks completed successfully |
expired |
Verification link expired (default: 48 hours) |
revoked |
Session canceled via API |
failed |
Verification failed (see failure_reason) |
Outcome Values
| Outcome | Description |
|---|---|
pending |
Verification not yet completed |
clear |
All checks passed successfully |
consider |
Manual review recommended |
attention |
Issues detected, review required |
issue |
Verification failed |
error |
Technical error during verification |
Create Verification Session
Create a new identity verification session for an individual entity and optionally send a verification link via email.
/api/v1/verification/sessions/
Session creation supports idempotency via the Idempotency-Key header.
If you retry the same request with the same key, you'll receive the cached response instead of creating a duplicate session.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
entity_id |
uuid | Yes | ID of entity to verify (must be entity_type: individual) |
email |
string | Yes | Email address to send verification link to |
verification_profile |
string | No | Preset profile: basic, standard (default), comprehensive |
verification_checks |
object | No | Custom check configuration (overrides profile if provided) |
expiry_hours |
integer | No | Hours until link expires (default: 48, max: 168) |
send_email |
boolean | No | Automatically send email (default: true) |
webhook_url |
string | No | Session-specific webhook URL for verification events |
Verification Profiles
| Profile | Checks Included | Use Case |
|---|---|---|
basic |
Document check only | Basic ID verification |
standard |
Document + Liveness | Standard KYC |
comprehensive |
Document + Liveness + AML + PEP | High-risk onboarding |
Custom Verification Checks
For advanced use cases, you can override profiles with custom check configurations using the verification_checks parameter.
Each check type can be individually enabled/disabled and configured with specific options.
Available Check Types
| Check Type | Description |
|---|---|
document_check |
Validates document authenticity, detects forgery |
identity_check |
Face match between document photo and selfie |
enhanced_identity_check |
Liveness detection via video (prevents spoofing) |
proof_of_address_check |
Validates utility bills, bank statements |
API Response
Returns the created session with 202 Accepted status.
Success Response (202 Accepted)
{
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"entity_id": "550e8400-e29b-41d4-a716-446655440000",
"entity_name": "John Doe",
"status": "pending",
"verification_url": "https://kycgenie.com/verify/770e8400-e29b-41d4-a716-446655440002",
"email_sent": true,
"expires_at": "2026-02-02T12:00:00Z",
"created_at": "2026-01-31T12:00:00Z"
}
Error Response (400 - Invalid Entity Type)
{
"error": "Identity verification is only available for individuals",
"detail": "Entity type is company, must be individual",
"entity_id": "550e8400-e29b-41d4-a716-446655440000"
}
Error Response (409 - Active Session Exists)
{
"error": "Active verification session already exists",
"detail": "A verification link has already been sent and is still valid",
"existing_session_id": "880e8400-e29b-41d4-a716-446655440003",
"status": "pending",
"expires_at": "2026-02-02T10:00:00Z",
"created_at": "2026-01-31T10:00:00Z"
}
Get Verification Session Status
Retrieve current status, outcome, and check details for a verification session.
/api/v1/verification/sessions/{session_id}/
Request Example
curl https://api.kycgenie.com/api/v1/verification/sessions/770e8400-e29b-41d4-a716-446655440002/ \
-H "Authorization: Bearer YOUR_API_KEY"
import requests
headers = {'Authorization': 'Bearer YOUR_API_KEY'}
response = requests.get(
'https://api.kycgenie.com/api/v1/verification/sessions/770e8400-e29b-41d4-a716-446655440002/',
headers=headers
)
print(response.json())
const response = await fetch(
'https://api.kycgenie.com/api/v1/verification/sessions/770e8400-e29b-41d4-a716-446655440002/',
{
headers: {'Authorization': 'Bearer YOUR_API_KEY'}
}
);
const data = await response.json();
console.log(data);
API Response
Returns session status with 200 OK.
Success Response (200 OK)
{
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"entity_id": "550e8400-e29b-41d4-a716-446655440000",
"entity_name": "John Doe",
"status": "completed",
"outcome": "clear",
"failure_reason": null,
"failure_details": "",
"delivery_method": "email",
"accessed_at": "2026-01-31T12:05:00Z",
"completed_at": "2026-01-31T12:15:00Z",
"expires_at": "2026-02-02T12:00:00Z",
"created_at": "2026-01-31T12:00:00Z",
"checks": [
{
"check_id": "990e8400-e29b-41d4-a716-446655440004",
"check_type": "document_check",
"status": "completed",
"outcome": "clear",
"created_at": "2026-01-31T12:05:00Z",
"completed_at": "2026-01-31T12:10:00Z"
},
{
"check_id": "aa0e8400-e29b-41d4-a716-446655440005",
"check_type": "liveness_check",
"status": "completed",
"outcome": "clear",
"created_at": "2026-01-31T12:10:00Z",
"completed_at": "2026-01-31T12:15:00Z"
}
]
}
Get Detailed Verification Results
Retrieve complete verification results including extracted identity data and raw check data.
Only available when session status is completed.
/api/v1/verification/sessions/{session_id}/results/
Detailed results are only available when status: completed.
Attempting to retrieve results before completion will return a 400 error. On test environments, less data is returned.
API Response
Returns extracted identity data and raw check results with 200 OK.
Success Response (200 OK)
{
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"entity_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"outcome": "clear",
"extracted_data": {
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1985-05-15",
"document_type": "passport",
"document_number": "P12345678",
"document_country": "GB",
"nationality": "GB",
"expiry_date": "2030-05-15",
"gender": "male",
"address": {
"line1": "123 Main Street",
"city": "London",
"postcode": "SW1A 1AA",
"country": "GB"
}
},
"checks": [
{
"check_id": "990e8400-e29b-41d4-a716-446655440004",
"check_type": "document_check",
"status": "completed",
"outcome": "clear",
"created_at": "2026-01-31T12:05:00Z",
"completed_at": "2026-01-31T12:10:00Z",
"result_data": {
"id": "5e8a2b1f-5f3d-4c8a-9b2d-8e7f6a5b4c3d",
"type": "document_check",
"result": "clear",
"breakdown": {
"documentValidation": "clear",
"imageQuality": "clear",
"visualAuthenticity": "clear"
}
}
}
]
}
Error Response (400 - Session Not Completed)
{
"error": "Verification session not completed",
"detail": "Session status is pending. Results are only available when status is completed.",
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"current_status": "pending"
}
Resend Verification Link
Resend verification link via email to the same or different email address. Maximum 3 resends per session.
/api/v1/verification/sessions/{session_id}/resend/
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
email |
string | No | New email address (if omitted, uses original email) |
API Response
Success Response (200 OK)
{
"success": true,
"message": "Verification link resent successfully",
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"email_sent_to": "[email protected]",
"resend_count": 1
}
Error Response (429 - Max Resends Reached)
{
"error": "Too many resend attempts",
"detail": "Maximum of 3 resends per session. Please create a new verification session.",
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"resend_count": 3
}
Revoke Verification Session
Cancel and revoke a verification session. The verification link will no longer work after revocation.
/api/v1/verification/sessions/{session_id}/revoke/
API Response
Success Response (200 OK)
{
"success": true,
"message": "Verification session revoked",
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"status": "revoked"
}
Error Response (400 - Already Completed)
{
"error": "Cannot revoke completed session",
"detail": "Verification has already been completed",
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"status": "completed",
"completed_at": "2026-01-31T12:15:00Z"
}
List Entity Verification Sessions
Retrieve all verification sessions for a specific entity with optional filtering.
/api/v1/entities/{entity_id}/verification-sessions/
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter by status: pending, accessed, completed, expired, revoked, failed |
outcome |
string | Filter by outcome: pending, clear, consider, attention, issue, error |
limit |
integer | Results per page (default: 10) |
offset |
integer | Pagination offset (default: 0) |
API Response
Success Response (200 OK)
{
"count": 5,
"limit": 20,
"offset": 0,
"results": [
{
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"status": "completed",
"outcome": "clear",
"failure_reason": null,
"created_at": "2026-01-31T12:00:00Z",
"accessed_at": "2026-01-31T12:05:00Z",
"completed_at": "2026-01-31T12:15:00Z",
"expires_at": "2026-02-02T12:00:00Z"
},
{
"session_id": "ee0e8400-e29b-41d4-a716-446655440009",
"status": "completed",
"outcome": "clear",
"failure_reason": null,
"created_at": "2026-01-25T09:00:00Z",
"accessed_at": "2026-01-25T09:10:00Z",
"completed_at": "2026-01-25T09:20:00Z",
"expires_at": "2026-01-27T09:00:00Z"
}
]
}
Create Verification Review
Submit a manual review decision for a completed verification session. Allows compliance officers to approve, reject, or flag verifications with full audit trail.
/api/v1/verification/sessions/{session_id}/reviews/create/
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
decision |
string | Yes | Review decision: approved, rejected, flagged, pending |
notes |
string | Yes | Explanation for the decision |
check_ids |
array | No | Specific check IDs if review is check-specific |
API Response
Success Response (201 Created)
{
"review_id": "120e8400-e29b-41d4-a716-446655440012",
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"decision": "approved",
"notes": "Identity verified successfully. All checks clear.",
"reviewed_by": {
"id": "130e8400-e29b-41d4-a716-446655440013",
"name": "Jane Smith",
"email": "[email protected]"
},
"reviewed_at": "2026-01-31T15:00:00Z",
"check_ids": null
}
Error Response (400 - Session Not Completed)
{
"error": "Cannot review verification session",
"detail": "Session status is pending. Reviews can only be submitted for completed sessions.",
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"current_status": "pending"
}
List Verification Reviews
Retrieve all review decisions for a verification session, ordered by most recent first.
/api/v1/verification/sessions/{session_id}/reviews/
API Response
Success Response (200 OK)
{
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"entity_id": "550e8400-e29b-41d4-a716-446655440000",
"session_status": "completed",
"session_outcome": "clear",
"reviews": [
{
"review_id": "120e8400-e29b-41d4-a716-446655440012",
"decision": "approved",
"notes": "Identity verified successfully. All checks clear.",
"reviewed_by": {
"id": "130e8400-e29b-41d4-a716-446655440013",
"name": "Jane Smith",
"email": "[email protected]"
},
"reviewed_at": "2026-01-31T15:00:00Z",
"check_ids": null
}
],
"total_reviews": 1,
"latest_decision": "approved"
}
Webhook Events
The Verification API sends webhook notifications for key events. Configure webhook URLs in your tenant settings
or provide a session-specific webhook_url when creating a session.
All webhooks include an HMAC-SHA256 signature in the X-Webhook-Signature header.
Verify this signature using your webhook secret to ensure authenticity.
Event Types
| Event | Description |
|---|---|
verification.session_created |
Fired immediately after session creation |
verification.session_accessed |
Fired when user first opens verification link |
verification.session_completed |
Fired when all checks complete with clear outcome |
verification.session_failed |
Fired when verification fails |
verification.session_expired |
Fired when verification link expires |
verification.check_completed |
Fired for each individual check completion |
Webhook Payload Example (session_completed)
{
"event": "verification.session_completed",
"timestamp": "2026-01-31T12:15:00Z",
"data": {
"session_id": "770e8400-e29b-41d4-a716-446655440002",
"entity_id": "550e8400-e29b-41d4-a716-446655440000",
"entity_name": "John Doe",
"status": "completed",
"outcome": "clear",
"checks_completed": 2,
"completed_at": "2026-01-31T12:15:00Z",
"extracted_data": {
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1985-05-15",
"document_type": "passport",
"document_number": "P12345678"
}
}
}
Webhook Signature Verification (Python)
import hmac
import hashlib
def verify_webhook_signature(payload_body, signature_header, webhook_secret):
"""Verify webhook HMAC-SHA256 signature"""
expected_signature = hmac.new(
webhook_secret.encode('utf-8'),
payload_body.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature_header, expected_signature)
# In your webhook handler:
signature = request.headers.get('X-Webhook-Signature')
is_valid = verify_webhook_signature(
payload_body=request.body.decode('utf-8'),
signature_header=signature,
webhook_secret=YOUR_WEBHOOK_SECRET
)
if not is_valid:
return 401 # Reject invalid signatures
Rate Limits
Rate limits protect API stability and ensure fair usage across all tenants.
Endpoint Rate Limits
| Endpoint | Rate Limit | Notes |
|---|---|---|
| Create Session | 60 req/min | Per API key |
| Get Status | 300 req/min | Per API key |
| Get Results | 300 req/min | Per API key |
| Resend Link | 20 req/min | Per API key, max 3 per session |
| All Endpoints | 10,000 req/hour | Account-wide limit |
Rate Limit Headers
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Requests remaining in current windowX-RateLimit-Reset: Unix timestamp when limit resets
Rate Limit Exceeded Response (429)
{
"error": "Rate limit exceeded",
"detail": "You have exceeded the rate limit. Please try again later.",
"retry_after": 60
}