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.

Session-Based Verification

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.

POST /api/v1/verification/sessions/
Idempotency

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.

GET /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.

GET /api/v1/verification/sessions/{session_id}/results/
Results Availability

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"
}

Revoke Verification Session

Cancel and revoke a verification session. The verification link will no longer work after revocation.

DELETE /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.

GET /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.

POST /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.

GET /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.

Webhook Security

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 allowed
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-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
}