Verification Management API

KYC/KYB verification workflows, document uploads, and approvals

Verification Management API

Complete verification workflows for KYC (Know Your Customer) and KYB (Know Your Business) compliance.


Verification Workflow

  1. Create Verification

    Initiate verification request with type and level

  2. Upload Documents

    Submit required verification documents

  3. Review Process

    Admin reviews submissions and documents

  4. Approve/Reject

    Admin makes final decision

  5. Update Customer Status

    System updates customer verification level


Create Verification Request

Initiate a new verification process for a customer.

Endpoint

POST /api/v2.1/verifications

Headers

X-Tenant-ID string header required

Tenant identifier

Authorization string header required

Bearer token for authentication

Content-Type string header required

Must be application/json

Request Body

customerId string body

Customer UUID identifier to verify (included when verifying a specific customer)

Example: 5887c98c-b5b1-4234-b819-a4987f54aa77

requestedByTenantId string body required

Tenant ID requesting the verification

Example: d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f

type string body required

Verification type

Valid Values:

  • IDENTITY_VERIFICATION - Basic identity check
  • DOCUMENT_VERIFICATION - Document authenticity verification
  • ENHANCED_DUE_DILIGENCE - Enhanced KYC/KYB checks
  • SANCTIONS_CHECK - Sanctions and PEP screening
  • CUSTOMER_DUE_DILIGENCE - Standard CDD process
  • BUSINESS_VERIFICATION - Organization/business verification
requestedLevel string body required

Target verification level

Valid Values:

  • TENANT_VERIFIED - Tenant-level verification
  • FINHUB_VERIFIED - Platform-level verification
requestedByUserId string body required

User ID initiating the verification

Example: admin-user

additionalData object body

Optional metadata for the verification

additionalData properties
description string body

Description of the verification request

priority string body

Priority level: NORMAL, HIGH, or URGENT

Headers

X-Tenant-ID string header required

Tenant identifier

Authorization string header required

Bearer token for authentication

Content-Type string header required

Must be application/json

X-Forwarded-From string header required

Source identifier for request origin tracking

User-Agent string header required

Client application identifier — required by the global request filter

platform string header required

Client platform identifier (e.g., web). Also accepted as sec-ch-ua-platform

deviceId string header required

Unique device identifier for session tracking. Also accepted as X-Device-Id or device-id

X-User-ID string header

User ID initiating the verification (used in B2B flows)

X-User-Roles string header

Comma-separated list of user roles (used in B2B flows)

Code Examples

cURL
bash
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/verifications" \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Forwarded-From: e2e-test" \
  -H "User-Agent: YourApp/1.0" \
  -H "platform: web" \
  -H "deviceId: 356938035643809" \
  -d '{
    "customerId": "5887c98c-b5b1-4234-b819-a4987f54aa77",
    "requestedByTenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
    "type": "IDENTITY_VERIFICATION",
    "requestedLevel": "TENANT_VERIFIED",
    "requestedByUserId": "admin-user",
    "additionalData": {
      "description": "New customer onboarding",
      "priority": "NORMAL"
    }
  }'
cURL
bash
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/verifications" \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Forwarded-From: e2e-test" \
  -H "User-Agent: YourApp/1.0" \
  -H "platform: web" \
  -H "deviceId: 356938035643809" \
  -d '{
    "customerId": "2f6ddd86-9ef1-45b6-a16d-058b3ccf29e4",
    "requestedByTenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
    "type": "BUSINESS_VERIFICATION",
    "requestedLevel": "TENANT_VERIFIED",
    "requestedByUserId": "admin-user",
    "additionalData": {
      "description": "KYB compliance check",
      "priority": "HIGH"
    }
  }'
JavaScript
javascript
const createVerification = async (customerId, type) => {
  const response = await fetch(
    'https://sandbox.finhub.cloud/api/v2.1/verifications',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
        'Authorization': `Bearer ${token}`,
        'X-Forwarded-From': 'e2e-test',
        'User-Agent': 'YourApp/1.0',
        'platform': 'web',
        'deviceId': '356938035643809'
      },
      body: JSON.stringify({
        customerId,
        requestedByTenantId: 'd1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f',
        type,
        requestedLevel: 'TENANT_VERIFIED',
        requestedByUserId: 'admin-user',
        additionalData: {
          description: `${type} check`,
          priority: 'NORMAL'
        }
      })
    }
  );

  return response.json();
};
Python
python
def create_verification(customer_id, verification_type):
    url = 'https://sandbox.finhub.cloud/api/v2.1/verifications'
    
    payload = {
        'customerId': customer_id,
        'requestedByTenantId': 'd1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f',
        'type': verification_type,
        'requestedLevel': 'TENANT_VERIFIED',
        'requestedByUserId': 'admin-user',
        'additionalData': {
            'description': f'{verification_type} compliance check',
            'priority': 'NORMAL'
        }
    }
    
    response = requests.post(
        url,
        headers={
            'Content-Type': 'application/json',
            'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
            'Authorization': f'Bearer {token}',
                'X-Forwarded-From': 'e2e-test',
            'User-Agent': 'YourApp/1.0',
            'platform': 'web',
            'deviceId': '356938035643809'
        },
        json=payload
    )
    
    return response.json()

Response

Response example
201
json
{
  "success": true,
  "code": 200,
  "timestamp": "2026-01-12T19:22:00.469602400Z",
  "message": "Verification process started",
  "data": {
    "id": "42cf474d-0914-47f1-895f-54147443d203",
    "customerId": "5887c98c-b5b1-4234-b819-a4987f54aa77",
    "type": "IDENTITY_VERIFICATION",
    "status": "IN_PROGRESS",
    "performedBy": "TENANT",
    "performedById": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
    "verificationLevel": "TENANT_VERIFIED",
    "appliesToSubtenants": false,
    "requiredDocuments": [
      "GOVERNMENT_ID"
    ],
    "startedAt": "2026-01-12T19:22:00.436424200Z",
    "initiatedBy": "admin-user",
    "additionalData": {
      "description": "New customer onboarding",
      "priority": "NORMAL"
    },
    "verified": false
  }
}

Upload Verification Document

Upload a document for an active verification process.

Endpoint

POST /api/v2.1/verifications/{verificationId}/documents

Path Parameters

verificationId string path required

Verification UUID from the create verification response

Example: 42cf474d-0914-47f1-895f-54147443d203

Request Body

documentType string body required

Type of document being uploaded

Valid Document Types:

  • PASSPORT - Passport document
  • NATIONAL_ID - National ID card
  • DRIVERS_LICENSE - Driver’s license
  • PROOF_OF_ADDRESS - Address verification
  • BANK_STATEMENT - Bank statement
  • SOURCE_OF_FUNDS - Source of funds declaration
  • BENEFICIAL_OWNERSHIP - Beneficial ownership declaration
  • PEP_DECLARATION - PEP status declaration
  • PROOF_OF_FUNDS - Proof of funds
  • INVOICE - Invoice or business document
  • CERTIFICATE_OF_INCORPORATION - Company registration
  • SHAREHOLDER_REGISTER - Shareholder registry
  • DIRECTOR_ID - Director identification
fileName string body required

Original filename with extension

Example: passport.pdf

fileContent string body required

Base64-encoded file content

Supported Formats: PDF, JPEG, PNG Max Size: 10MB

mimeType string body required

MIME type of the file

Examples: application/pdf, image/jpeg, image/png

description string body

Optional description or notes about the document

customerId string body

Customer ID (for payment verification documents)

accountId string body

Account ID (for payment verification documents)

transactionAmount number body

Transaction amount (for payment verification)

currency string body

Currency code (for payment verification)

purpose string body

Purpose of the document upload

Code Example

cURL
bash
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/verifications/42cf474d-0914-47f1-895f-54147443d203/documents" \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Forwarded-From: e2e-test" \
  -H "User-Agent: YourApp/1.0" \
  -H "platform: web" \
  -H "deviceId: 356938035643809" \
  -d '{
    "documentType": "PASSPORT",
    "fileName": "passport.pdf",
    "fileContent": "JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwo+PgplbmRvYmoKeHJlZgowIDAKdHJhaWxlcgo8PAovUm9vdCAxIDAgUgo+PgolJUVPRgo=",
    "mimeType": "application/pdf",
    "description": "Customer passport for identity verification"
  }'
JavaScript
javascript
const uploadDocument = async (verificationId, file) => {
  // Convert file to base64
  const base64Content = await fileToBase64(file);
  
  const response = await fetch(
    `https://sandbox.finhub.cloud/api/v2.1/verifications/${verificationId}/documents`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
        'Authorization': `Bearer ${token}`,
        'X-Forwarded-From': 'e2e-test',
        'User-Agent': 'YourApp/1.0',
        'platform': 'web',
        'deviceId': '356938035643809'
      },
      body: JSON.stringify({
        documentType: 'PASSPORT',
        fileName: file.name,
        fileContent: base64Content,
        mimeType: file.type,
        description: 'Customer passport for identity verification'
      })
    }
  );

  return response.json();
};

// Helper function
const fileToBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result.split(',')[1]);
    reader.onerror = error => reject(error);
  });
};

Response

Response example
201
json
{
  "code": 200,
  "message": "Verification document uploaded successfully",
  "data": "Document uploaded for verification 42cf474d-0914-47f1-895f-54147443d203: {\"id\":\"d7379b5e-f983-4a27-b074-9a5a58cdc9da\",\"tenantId\":\"d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f\",\"customerId\":\"5887c98c-b5b1-4234-b819-a4987f54aa77\",\"fileName\":\"628dd82a-a698-4d8c-bcb2-a97e78d33397_passport.pdf\",\"fileType\":\"PASSPORT\",\"status\":\"UPLOADED\",\"contentType\":\"application/pdf\",\"contentUrl\":\".\\\\data\\\\documents\\\\d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f\\\\2026\\\\01\\\\12\\\\5887c98c-b5b1-4234-b819-a4987f54aa77\\\\628dd82a-a698-4d8c-bcb2-a97e78d33397_passport.pdf\",\"uploadDate\":1768245720542,\"uploadedBy\":\"system\",\"description\":\"Customer passport for identity verification\",\"verified\":false}"
}

Approve Verification

Approve a verification request after review.

Endpoint

POST /api/v2.1/verifications/{verificationId}/approve

Path Parameters

verificationId string path required

Verification UUID to approve

Request Body

notes string body

Admin notes about the approval decision (used in implementation)

approvedBy string body required

User ID or name of the approver

Example: E2E_TEST_ADMIN or admin user ID

adminNotes string body

Alternative field for admin notes (legacy support)

approvalReason string body

Reason for approval

Code Example

cURL
bash
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/verifications/42cf474d-0914-47f1-895f-54147443d203/approve" \
  -H "Accept: application/json, text/plain, */*" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Forwarded-From: e2e-test" \
  -H "platform: web" \
  -H "deviceId: 356938035643809" \
  -d '{
    "adminNotes": "All documents verified and authentic",
    "approvedBy": "admin_user_123",
    "approvalReason": "All verification criteria met"
  }'
JavaScript
javascript
const approveVerification = async (verificationId) => {
  const response = await fetch(
    `https://sandbox.finhub.cloud/api/v2.1/verifications/${verificationId}/approve`,
    {
      method: 'POST',
      headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json',
        'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
        'Authorization': `Bearer ${token}`,
        'X-Forwarded-From': 'e2e-test',
        'platform': 'web',
        'deviceId': '356938035643809'
      },
      body: JSON.stringify({
        adminNotes: 'All documents verified and authentic',
        approvedBy: 'admin_user_123',
        approvalReason: 'All verification criteria met'
      })
    }
  );

  return response.json();
};

Response

Response example
200
json
{
  "code": 200,
  "message": "Verification approved successfully",
  "data": {
    "level": "TENANT_VERIFIED",
    "approvedBy": "admin-user",
    "approvedAt": "2026-01-12T19:22:00.658560500Z",
    "verificationId": "42cf474d-0914-47f1-895f-54147443d203",
    "status": "APPROVED"
  }
}

Get Verification Status

Retrieve the current status of a verification request.

Endpoint

GET /api/v2.1/verifications/{verificationId}

Path Parameters

verificationId string path required

Verification UUID

Response

Response example
200
json
{
  "code": 200,
  "message": "Verification status retrieved successfully",
  "data": {
    "submittedDocuments": 0,
    "completedAt": "2026-01-12T19:22:04.780839500Z",
    "level": "FINHUB_VERIFIED",
    "startedAt": "2026-01-12T19:22:02.894983800Z",
    "type": "SANCTIONS_CHECK",
    "verificationId": "90fb384c-6404-453d-9001-d15c4e0966e5",
    "status": "APPROVED"
  }
}

Verification Types Reference

TypePurposeRequired DocumentsTypical Use Case
IDENTITY_VERIFICATIONBasic identity checkGovernment IDIndividual onboarding
DOCUMENT_VERIFICATIONDocument authenticityProof of address, IDAddress verification
ENHANCED_DUE_DILIGENCEEnhanced KYCSource of funds, beneficial ownership, PEPHigh-risk customers
SANCTIONS_CHECKPEP & sanctions screeningPEP declaration, proof of addressCompliance requirements
CUSTOMER_DUE_DILIGENCEStandard CDDBasic identificationStandard KYC
BUSINESS_VERIFICATIONKYB for organizationsIncorporation docs, shareholder registerOrganization onboarding

Document Type Requirements

Individual Customers

IDENTITY_VERIFICATION:

  • PASSPORT or NATIONAL_ID or DRIVERS_LICENSE

ENHANCED_DUE_DILIGENCE:

  • SOURCE_OF_FUNDS
  • BENEFICIAL_OWNERSHIP (if applicable)
  • PEP_DECLARATION
  • PROOF_OF_ADDRESS

SANCTIONS_CHECK:

  • PROOF_OF_ADDRESS
  • SOURCE_OF_FUNDS
  • BENEFICIAL_OWNERSHIP
  • PEP_DECLARATION

Organization Customers

BUSINESS_VERIFICATION:

  • CERTIFICATE_OF_INCORPORATION
  • PROOF_OF_ADDRESS
  • DIRECTOR_ID
  • SHAREHOLDER_REGISTER

Verification Levels

LevelDescriptionVerification By
TENANT_VERIFIEDVerified by tenantTenant admin
FINHUB_VERIFIEDVerified by platformFinHub compliance team

Common Workflows

Individual KYC Workflow

1. Create IDENTITY_VERIFICATION
   ↓
2. Upload PASSPORT document
   ↓
3. Admin reviews and approves
   ↓
4. Create DOCUMENT_VERIFICATION
   ↓
5. Upload PROOF_OF_ADDRESS
   ↓
6. Admin approves
   ↓
7. (Optional) Create ENHANCED_DUE_DILIGENCE for high-risk
   ↓
8. Customer status updated to VERIFIED

Organization KYB Workflow

1. Create BUSINESS_VERIFICATION
   ↓
2. Upload required documents:
   - CERTIFICATE_OF_INCORPORATION
   - DIRECTOR_ID
   - SHAREHOLDER_REGISTER
   - PROOF_OF_ADDRESS
   ↓
3. Admin reviews all documents
   ↓
4. Admin approves verification
   ↓
5. Organization status updated to VERIFIED

Best Practices

Document Quality Guidelines

  • Resolution: Minimum 300 DPI for scanned documents
  • Format: PDF preferred, JPEG/PNG acceptable
  • Size: Maximum 10MB per file
  • Clarity: All text must be clearly readable
  • Completeness: Full document visible, no cropping


Changelog

VersionDateChanges
v2.12026-01-13Initial release

Type to search…

↑↓ navigate open esc close