URL: /baas/api/reference/customer-apis/organization/verification
---
title: 'Organization Verification (KYB)'
description: 'Know Your Business (KYB) verification process for organizations'
api: 'POST https://sandbox.finhub.cloud/api/v2.1/customer/organization/{organizationId}/verification'
---
# Organization Verification (KYB)
Complete Know Your Business (KYB) verification process for business organizations, including document verification, personnel checks, and beneficial owner identification.
**Base URL:** `https://sandbox.finhub.cloud`
For complete details on authentication and headers, refer to the [Standard HTTP Headers](../../schemas/standard-headers) reference documentation.
---
## 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 |
**High-Risk Organizations** require POWER_TENANT_VERIFIED level:
- Money service businesses
- Cryptocurrency exchanges
- Gambling/gaming businesses
- Organizations with PEP directors or beneficial owners
- Organizations from high-risk jurisdictions
---
## 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`
```bash cURL
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`
Use the verification ID returned from Step 1. Documents are uploaded as JSON with base64-encoded content.
```bash cURL
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:**
| 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:**
```json
{
"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 |
**File Requirements:**
- Formats: PDF, JPG, PNG
- Maximum size: 10MB per file
- Base64 encoding required for JSON upload
- Use UTF-8 encoding for file names
---
### Step 3: Personnel Verification Check
Ensure all required personnel are added and verified:
**Endpoint:** `GET /api/v2.1/customer/organization/{organizationId}/verification/personnel-status`
```bash cURL
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"]
}
}
```
```bash cURL
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`
```bash cURL
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
```mermaid
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:**
```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
| 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:
```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).
---
## 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 |