Organization Verification (KYB)

Know Your Business (KYB) verification process for organizations

Organization Verification (KYB)

Complete Know Your Business (KYB) verification process for business organizations, including document verification, personnel checks, and beneficial owner identification.


Verification Levels

LevelDescriptionApproval RequiredTypical Use Case
TENANT_VERIFIEDBasic business verificationTENANT_ADMINStandard businesses, low-risk sectors
POWER_TENANT_VERIFIEDEnhanced due diligencePOWER_TENANT (Super Admin)High-risk businesses, large transactions, PEPs

Complete KYB Verification Flow

Step 1: Initiate Verification

Check what verification is required for the organization.

Endpoint: GET /api/v2.1/customer/organization/{organizationId}/verification/requirements

cURL
bash
curl -X GET "https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification/requirements" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "X-Forwarded-From: e2e-test" \
  -H "User-Agent: YourApp/1.0" \
  -H "platform: web" \
  -H "deviceId: 356938035643809"
JavaScript
javascript
const response = await fetch(
  'https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification/requirements',
  {
    headers: {
      'Accept': 'application/json, text/plain, */*',
      'Authorization': `Bearer ${accessToken}`,
      'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
      'X-Forwarded-From': 'e2e-test',
      'User-Agent': 'YourApp/1.0',
      'platform': 'web',
      'deviceId': '356938035643809'
    }
  }
);

const { data } = await response.json();
console.log('Required documents:', data.requiredDocuments);
console.log('Verification level:', data.verificationLevel);
Python
python
import requests

response = requests.get(
    'https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification/requirements',
    headers={
        'Accept': 'application/json, text/plain, */*',
        'Authorization': f'Bearer {access_token}',
        'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
        'X-Forwarded-From': 'e2e-test',
        'User-Agent': 'YourApp/1.0',
        'platform': 'web',
        'deviceId': '356938035643809'
    }
)

data = response.json()['data']
print(f"Required documents: {data['requiredDocuments']}")
print(f"Verification level: {data['verificationLevel']}")

Response:

json
{
  "success": true,
  "data": {
    "organizationId": "org_12345",
    "verificationLevel": "TENANT_VERIFIED",
    "requiredDocuments": [
      "CERTIFICATE_OF_INCORPORATION",
      "ARTICLES_OF_ASSOCIATION",
      "SHAREHOLDER_REGISTER",
      "DIRECTOR_ID",
      "BENEFICIAL_OWNER_DECLARATION",
      "BANK_STATEMENT"
    ],
    "requiredPersonnelVerification": {
      "directors": {
        "minimum": 1,
        "requireIdVerification": true,
        "requirePepCheck": true
      },
      "beneficialOwners": {
        "minimum": 1,
        "ownershipThreshold": 25.0,
        "requireIdVerification": true,
        "requirePepCheck": true
      }
    },
    "estimatedReviewTime": "2-5 business days"
  }
}

Step 2: Submit Verification Documents

Upload required documents to the verification process.

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

cURL
bash
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/verifications/ver_12345/documents" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "X-Forwarded-From: e2e-test" \
  -H "User-Agent: YourApp/1.0" \
  -H "platform: web" \
  -H "deviceId: 356938035643809" \
  -d '{
    "docId": "550e8400-e29b-41d4-a716-446655440000",
    "documentType": "CERTIFICATE_OF_INCORPORATION",
    "fileName": "incorporation_cert.pdf",
    "fileContent": "JVBERi0xLjQKJeLjz9MKNyAwIG9iaiA8PAovVHlwZSAvQ2F0YWxvZy...",
    "customerId": "org_12345",
    "description": "Company registration certificate"
  }'
JavaScript
javascript
const { v4: uuidv4 } = require('uuid');
const fs = require('fs');

// Read file and convert to base64
const fileBuffer = fs.readFileSync('/path/to/incorporation_cert.pdf');
const base64Content = fileBuffer.toString('base64');

const response = await fetch(
  'https://sandbox.finhub.cloud/api/v2.1/verifications/ver_12345/documents',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${accessToken}`,
      'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
      'X-Forwarded-From': 'e2e-test',
      'User-Agent': 'YourApp/1.0',
      'platform': 'web',
      'deviceId': '356938035643809'
    },
    body: JSON.stringify({
      docId: uuidv4(),
      documentType: 'CERTIFICATE_OF_INCORPORATION',
      fileName: 'incorporation_cert.pdf',
      fileContent: base64Content,
      customerId: organizationId,
      description: 'Company registration certificate'
    })
  }
);

const { data } = await response.json();
console.log('Document uploaded:', data.documentId);
Python
python
import requests
import base64
from uuid import uuid4

# Read and encode file
with open('/path/to/incorporation_cert.pdf', 'rb') as f:
    base64_content = base64.b64encode(f.read()).decode('utf-8')

response = requests.post(
    'https://sandbox.finhub.cloud/api/v2.1/verifications/ver_12345/documents',
    headers={
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {access_token}',
        'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
        'X-Forwarded-From': 'e2e-test',
        'User-Agent': 'YourApp/1.0',
        'platform': 'web',
        'deviceId': '356938035643809'
    },
    json={
        'docId': str(uuid4()),
        'documentType': 'CERTIFICATE_OF_INCORPORATION',
        'fileName': 'incorporation_cert.pdf',
        'fileContent': base64_content,
        'customerId': 'org_12345',
        'description': 'Company registration certificate'
    }
)

data = response.json()['data']
print(f"Document uploaded: {data['documentId']}")

Request Body:

FieldTypeRequiredDescription
docIdstring (UUID)YesUnique document identifier (generate using UUID v4)
documentTypestringYesDocument type from the table below
fileNamestringYesOriginal file name with extension (.pdf, .jpg, .png)
fileContentstringYesBase64-encoded file content
customerIdstringYesOrganization ID from registration
descriptionstringNoDocument purpose or description

Response:

json
{
  "success": true,
  "data": {
    "documentId": "doc_67890",
    "verificationId": "ver_12345",
    "status": "UPLOADED",
    "uploadedAt": "2026-01-13T10:30:00Z"
  }
}

Required Documents:

Document TypeValue for documentTypeRequired ForDescription
Certificate of IncorporationCERTIFICATE_OF_INCORPORATIONAllProof of company registration
Articles of AssociationARTICLES_OF_ASSOCIATIONAllCompany bylaws/constitution
Proof of Registered AddressPROOF_OF_REGISTERED_ADDRESSAllRegistered office address proof
Beneficial Owners DeclarationBENEFICIAL_OWNERS_DECLARATIONAllUBO form (25%+ ownership)
Bank StatementBANK_STATEMENTAllLast 3 months business statements
Director IDsDIRECTOR_IDAllPassport/ID for each director
Financial StatementsFINANCIAL_STATEMENTSLarge businessesAudited accounts (revenue > €1M)
Business LicenseBUSINESS_LICENSERegulated sectorsIndustry-specific licenses

Step 3: Personnel Verification Check

Ensure all required personnel are added and verified:

Endpoint: GET /api/v2.1/customer/organization/{organizationId}/verification/personnel-status

cURL
bash
curl -X GET "https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification/personnel-status" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "X-Forwarded-From: e2e-test" \
  -H "User-Agent: YourApp/1.0" \
  -H "platform: web" \
  -H "deviceId: 356938035643809"

Response:

json
{
  "success": true,
  "data": {
    "directors": {
      "total": 2,
      "verified": 2,
      "pending": 0,
      "status": "COMPLETE"
    },
    "beneficialOwners": {
      "total": 2,
      "verified": 2,
      "totalOwnership": 100.0,
      "status": "COMPLETE"
    },
    "employees": {
      "total": 5,
      "withAdminRole": 1,
      "status": "COMPLETE"
    },
    "overallStatus": "READY_FOR_VERIFICATION"
  }
}

Step 4: Submit Verification Request

Once all documents and personnel are in place, submit for verification.

Endpoint: POST /api/v2.1/customer/organization/{organizationId}/verification

Request Body:

json
{
  "verificationType": "KYB",
  "verificationLevel": "TENANT_VERIFIED",
  "priority": "NORMAL",
  "verificationData": {
    "businessPurpose": "Import/export of electronic goods",
    "expectedAnnualRevenue": "€500,000 - €1,000,000",
    "expectedTransactionVolume": "50-100 transactions/month",
    "sourceOfFunds": "Business revenue and investor capital",
    "primaryJurisdictions": ["DE", "FR", "NL"]
  }
}
cURL
bash
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "X-Forwarded-From: e2e-test" \
  -H "User-Agent: YourApp/1.0" \
  -H "platform: web" \
  -H "deviceId: 356938035643809" \
  -d '{
    "verificationType": "KYB",
    "verificationLevel": "TENANT_VERIFIED",
    "priority": "NORMAL",
    "verificationData": {
      "businessPurpose": "Import/export of electronic goods",
      "expectedAnnualRevenue": "€500,000 - €1,000,000"
    }
  }'
JavaScript
javascript
const response = await fetch(
  'https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${accessToken}`,
      'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
      'X-Forwarded-From': 'e2e-test',
      'User-Agent': 'YourApp/1.0',
      'platform': 'web',
      'deviceId': '356938035643809'
    },
    body: JSON.stringify({
      verificationType: 'KYB',
      verificationLevel: 'TENANT_VERIFIED',
      priority: 'NORMAL',
      verificationData: {
        businessPurpose: 'Import/export of electronic goods',
        expectedAnnualRevenue: '€500,000 - €1,000,000'
      }
    })
  }
);

const { data } = await response.json();
console.log('Verification ID:', data.verificationId);
console.log('Status:', data.status);
Python
python
import requests

response = requests.post(
    'https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification',
    headers={
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {access_token}',
        'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
        'X-Forwarded-From': 'e2e-test',
        'User-Agent': 'YourApp/1.0',
        'platform': 'web',
        'deviceId': '356938035643809'
    },
    json={
        'verificationType': 'KYB',
        'verificationLevel': 'TENANT_VERIFIED',
        'priority': 'NORMAL',
        'verificationData': {
            'businessPurpose': 'Import/export of electronic goods',
            'expectedAnnualRevenue': '€500,000 - €1,000,000'
        }
    }
)

data = response.json()['data']
print(f"Verification ID: {data['verificationId']}")
print(f"Status: {data['status']}")

Response (200 OK):

json
{
  "success": true,
  "data": {
    "verificationId": "ver_org_67890",
    "organizationId": "org_12345",
    "status": "PENDING_REVIEW",
    "type": "KYB",
    "level": "TENANT_VERIFIED",
    "submittedAt": "2024-01-15T10:30:00Z",
    "estimatedCompletionTime": "2-5 business days",
    "requiredDocuments": [
      {
        "documentType": "CERTIFICATE_OF_INCORPORATION",
        "status": "SUBMITTED",
        "submittedAt": "2024-01-15T09:00:00Z"
      },
      {
        "documentType": "ARTICLES_OF_ASSOCIATION",
        "status": "SUBMITTED",
        "submittedAt": "2024-01-15T09:15:00Z"
      }
    ],
    "personnelChecks": {
      "directors": "COMPLETE",
      "beneficialOwners": "COMPLETE",
      "pepScreening": "IN_PROGRESS"
    },
    "nextSteps": [
      "Wait for compliance review",
      "PEP and sanctions screening in progress",
      "You will be notified via email when verification is complete"
    ]
  }
}

Step 5: Check Verification Status

Poll for verification status updates.

Endpoint: GET /api/v2.1/customer/organization/{organizationId}/verification/status

cURL
bash
curl -X GET "https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification/status" \
  -H "Accept: application/json, text/plain, */*" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
  -H "X-Forwarded-From: e2e-test" \
  -H "platform: web" \
  -H "deviceId: 356938035643809"
JavaScript
javascript
const response = await fetch(
  'https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification/status',
  {
    headers: {
      'Accept': 'application/json, text/plain, */*',
      'Authorization': `Bearer ${accessToken}`,
      'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
      'X-Forwarded-From': 'e2e-test',
      'platform': 'web',
      'deviceId': '356938035643809'
    }
  }
);

const { data } = await response.json();
console.log('Status:', data.status);
if (data.status === 'APPROVED') {
  console.log('✅ Verification approved! Ready for activation.');
}
Python
python
import requests

response = requests.get(
    'https://sandbox.finhub.cloud/api/v2.1/customer/organization/org_12345/verification/status',
    headers={
        'Accept': 'application/json, text/plain, */*',
        'Authorization': f'Bearer {access_token}',
        'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
        'X-Forwarded-From': 'e2e-test',
        'platform': 'web',
        'deviceId': '356938035643809'
    }
)

data = response.json()['data']
print(f"Status: {data['status']}")
if data['status'] == 'APPROVED':
    print("✅ Verification approved! Ready for activation.")

Response (Approved):

json
{
  "success": true,
  "data": {
    "verificationId": "ver_org_67890",
    "organizationId": "org_12345",
    "status": "APPROVED",
    "type": "KYB",
    "level": "TENANT_VERIFIED",
    "submittedAt": "2024-01-15T10:30:00Z",
    "reviewedAt": "2024-01-17T14:20:00Z",
    "approvedAt": "2024-01-17T14:20:00Z",
    "reviewedBy": "compliance_officer_01",
    "approvalRequired": "TENANT_ADMIN",
    "verificationChecks": {
      "documentsVerified": true,
      "directorsVerified": true,
      "beneficialOwnersVerified": true,
      "pepScreening": "CLEAR",
      "sanctionsScreening": "CLEAR",
      "adverseMediaScreening": "CLEAR"
    },
    "reviewNotes": "All documents verified. Business purpose and structure validated. No adverse findings.",
    "nextSteps": [
      "Proceed to consent acceptance",
      "Then activate organization"
    ]
  }
}

Verification Status Flow

stateDiagram-v2
    [*] --> NOT_STARTED: Organization registered
    NOT_STARTED --> PREPARING: Add documents & personnel
    PREPARING --> PENDING_REVIEW: Submit verification
    PENDING_REVIEW --> UNDER_REVIEW: Compliance starts review
    UNDER_REVIEW --> APPROVED: All checks pass
    UNDER_REVIEW --> ADDITIONAL_INFO_REQUIRED: Need more info
    UNDER_REVIEW --> REJECTED: Failed checks
    ADDITIONAL_INFO_REQUIRED --> UNDER_REVIEW: Info provided
    REJECTED --> PREPARING: Fix issues and resubmit
    APPROVED --> [*]: Ready for activation

Status Descriptions

StatusDescriptionNext Action
NOT_STARTEDDocuments/personnel not yet submittedUpload documents, add personnel
PREPARINGDocuments being uploadedComplete all uploads, then submit
PENDING_REVIEWSubmitted, queued for reviewWait for compliance officer
UNDER_REVIEWBeing reviewed by complianceWait for decision (2-5 days)
ADDITIONAL_INFO_REQUIREDMore information neededProvide requested information
APPROVEDVerification successfulProceed to consent & activation
REJECTEDVerification failedReview reasons, fix issues, resubmit

Step 6: Verification Approval (Admin)

For organizations requiring TENANT_ADMIN or POWER_TENANT approval.

Endpoint: POST /api/v2.1/customer/organization/{organizationId}/verification/approve

Required Role: COMPLIANCE_OFFICER or ADMIN_USER

Request:

json
{
  "verificationId": "ver_org_67890",
  "approved": true,
  "approvalNotes": "All KYB checks completed successfully. Documents verified. PEP and sanctions screening clear.",
  "conditions": []
}

Response:

json
{
  "success": true,
  "data": {
    "verificationId": "ver_org_67890",
    "status": "APPROVED",
    "approvedAt": "2024-01-17T14:20:00Z",
    "approvedBy": "compliance_officer_01",
    "nextSteps": [
      "Organization is now verified",
      "Proceed to consent acceptance",
      "Then activate organization"
    ]
  }
}

UBO (Ultimate Beneficial Owner) Requirements

Organizations must declare all UBOs (individuals owning ≥25% of the company).

UBO Verification Checklist

  • All shareholders with ≥25% ownership declared
  • Each UBO has submitted ID verification
  • PEP screening completed for all UBOs
  • Sanctions screening completed for all UBOs
  • Source of wealth documented for UBOs
  • Control structure diagram uploaded (if complex)

Complex Ownership Structures

For organizations with multi-tier ownership (e.g., Company A owns Company B):

  1. Upload ownership structure diagram
  2. Declare all natural persons with ≥25% indirect ownership
  3. Provide incorporation documents for parent companies
  4. Complete enhanced due diligence for all layers

Response Codes

CodeDescription
200Verification status retrieved successfully
201Verification submitted successfully
400Missing required documents or personnel
403Insufficient permissions
404Organization not found
422Verification prerequisites not met
500Internal server error

Common Verification Errors

Error: Missing Required Documents

Problem: Not all required documents uploaded

Solution: Check verification requirements and upload all documents:

bash
GET /api/v2.1/customer/organization/{orgId}/verification/requirements

Error: Ownership Validation Failed

Problem: Shareholder ownership doesn’t total 100%

Solution: Ensure all shareholders are declared and ownership percentages sum to exactly 100%.

Error: Missing Admin User

Problem: No employee with ADMIN_USER role

Solution: Add at least one employee with ADMIN_USER role before submitting verification.

Error: Director Not Verified

Problem: One or more directors missing ID verification

Solution: Ensure all directors have submitted valid identification documents.


API Schema Reference

For the complete OpenAPI schema specification, see the API Schema Mapping documentation (Organization Verification operation - to be added).



Changelog

VersionDateChanges
v1.02026-01-13Initial organization verification documentation

Failed to load openapi.yaml: No number after minus sign in JSON at position 1 (line 1 column 2)

Type to search…

↑↓ navigate open esc close