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 |