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
| Level | Description | Approval Required | Typical Use Case |
|---|---|---|---|
| TENANT_VERIFIED | Basic business verification | TENANT_ADMIN | Standard businesses, low-risk sectors |
| POWER_TENANT_VERIFIED | Enhanced due diligence | POWER_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 -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"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);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:
{
"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 -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"
}'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);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:
| Field | Type | Required | Description |
|---|---|---|---|
docId | string (UUID) | Yes | Unique document identifier (generate using UUID v4) |
documentType | string | Yes | Document type from the table below |
fileName | string | Yes | Original file name with extension (.pdf, .jpg, .png) |
fileContent | string | Yes | Base64-encoded file content |
customerId | string | Yes | Organization ID from registration |
description | string | No | Document purpose or description |
Response:
{
"success": true,
"data": {
"documentId": "doc_67890",
"verificationId": "ver_12345",
"status": "UPLOADED",
"uploadedAt": "2026-01-13T10:30:00Z"
}
}Required Documents:
| Document Type | Value for documentType | Required For | Description |
|---|---|---|---|
| Certificate of Incorporation | CERTIFICATE_OF_INCORPORATION | All | Proof of company registration |
| Articles of Association | ARTICLES_OF_ASSOCIATION | All | Company bylaws/constitution |
| Proof of Registered Address | PROOF_OF_REGISTERED_ADDRESS | All | Registered office address proof |
| Beneficial Owners Declaration | BENEFICIAL_OWNERS_DECLARATION | All | UBO form (25%+ ownership) |
| Bank Statement | BANK_STATEMENT | All | Last 3 months business statements |
| Director IDs | DIRECTOR_ID | All | Passport/ID for each director |
| Financial Statements | FINANCIAL_STATEMENTS | Large businesses | Audited accounts (revenue > €1M) |
| Business License | BUSINESS_LICENSE | Regulated sectors | Industry-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 -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:
{
"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:
{
"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 -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"
}
}'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);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):
{
"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 -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"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.');
}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):
{
"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
| Status | Description | Next Action |
|---|---|---|
| NOT_STARTED | Documents/personnel not yet submitted | Upload documents, add personnel |
| PREPARING | Documents being uploaded | Complete all uploads, then submit |
| PENDING_REVIEW | Submitted, queued for review | Wait for compliance officer |
| UNDER_REVIEW | Being reviewed by compliance | Wait for decision (2-5 days) |
| ADDITIONAL_INFO_REQUIRED | More information needed | Provide requested information |
| APPROVED | Verification successful | Proceed to consent & activation |
| REJECTED | Verification failed | Review 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:
{
"verificationId": "ver_org_67890",
"approved": true,
"approvalNotes": "All KYB checks completed successfully. Documents verified. PEP and sanctions screening clear.",
"conditions": []
}Response:
{
"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):
- Upload ownership structure diagram
- Declare all natural persons with ≥25% indirect ownership
- Provide incorporation documents for parent companies
- Complete enhanced due diligence for all layers
Response Codes
| Code | Description |
|---|---|
200 | Verification status retrieved successfully |
201 | Verification submitted successfully |
400 | Missing required documents or personnel |
403 | Insufficient permissions |
404 | Organization not found |
422 | Verification prerequisites not met |
500 | Internal server error |
Common Verification Errors
Error: Missing Required Documents
Problem: Not all required documents uploaded
Solution: Check verification requirements and upload all documents:
GET /api/v2.1/customer/organization/{orgId}/verification/requirementsError: 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).
Related Endpoints
Complete HTTP headers reference
Upload verification documents
Add directors, employees, shareholders
Accept organization consents
Activate verified organization
Individual KYC verification
Changelog
| Version | Date | Changes |
|---|---|---|
| v1.0 | 2026-01-13 | Initial organization verification documentation |
Failed to load openapi.yaml: No number after minus sign in JSON at position 1 (line 1 column 2)