Automate KYC Verification with Company Belgium API
Discover how to automate your KYC verification processes by integrating the Company Belgium API. Code examples, use cases and complete integration guide for domiciliation centers.
In brief
Belgian domiciliation centres can cut KYC verification time by 80 % by integrating the Company Belgium REST API, which provides direct access to official BCE/KBO data. In 2 seconds the API returns a company's status, address, legal form, VAT number and beneficial owners — versus 30 minutes of manual checking. Every response is timestamped and archivable for the AML/KYC audits required by the law of 18 September 2017.
Introduction: Automation at the Service of Compliance
Domiciliation centers in Belgium face a multiplication of KYC obligations (Know Your Customer) as part of anti-money laundering efforts. Manual verification of each client quickly becomes time-consuming and error-prone.
Company Belgium offers a modern technological solution: a powerful REST API that enables you to automate all your KYC verification processes by accessing official CBE/BCE data directly.
In this article, we guide you step-by-step through integrating the Company Belgium API and reducing the time spent on KYC verifications by 80%.
Why Automate KYC Verification?
⏱️ Significant Time Savings
A manual company verification takes an average of 30 minutes:
- Searching the CBE/BCE website: 10 min
- UBO register verification: 8 min
- VAT validation: 5 min
- Establishment consultation: 7 min
With the Company Belgium API, this verification takes 2 seconds.
> 💡 Impact calculation: For a center processing 100 new clients/month, that's 50 hours saved each month, equivalent to 1.25 FTE!
✅ Guaranteed Reliability and Compliance
- Official data: direct access to the CBE/BCE database (daily updates)
- Timestamping: each verification is timestamped for audits
- Complete traceability: history of all requests
- GDPR compliance: secure storage and compliant retention period
🚀 Focus on Your Core Business
Free your teams from repetitive administrative tasks so they can focus on:
- Advisory support for clients
- In-depth risk analysis
- Weak signal detection
- Business development
Technical Architecture of the Integration
Main Endpoints for KYC
The Company Belgium API exposes several essential endpoints:
#### 1. Company Verification
1
GET /api/companies/{enterpriseNumber}
Returns all official information about a company:
- Status (active/inactive)
- Legal form
- Registered office address
- VAT number
- Creation date
- Directors
#### 2. UBO Lookup
1
GET /api/companies/{enterpriseNumber}/ubo
Accesses the register of ultimate beneficial owners (if publicly available).
#### 3. Establishment Verification
1
GET /api/companies/{enterpriseNumber}/establishments
Lists all operational establishments of the company.
#### 4. Peppol Verification
1
GET /api/peppol/check?vatNumber={vatNumber}
Checks if the company is registered on the Peppol network for electronic invoicing.
Secure Authentication
The API uses a dual-key system to ensure security:
1 2 3 4
const headers = {
class="code-string">'X-API-Key': class="code-string">'pk_live_your_public_key', class="code-comment">// Identifies your application
class="code-string">'X-API-Secret': class="code-string">'sk_live_your_secret_key', class="code-comment">// Authenticates the request
};
> ⚠️ Security: Never expose the secret key on the client side! Use it only server-side.
Step-by-Step Integration Guide
Step 1: Get Your API Keys
Step 2: SDK Installation (optional)
For Node.js/TypeScript:
1 2 3
npm install @company-belgium/sdk
# or
pnpm add @company-belgium/sdk
For Python:
1
pip install company-belgium
Step 3: Initial Configuration
Node.js / TypeScript
1 2 3 4 5 6 7
import { CompanyBelgiumClient } from class="code-string">'@company-belgium/sdk';
const client = new CompanyBelgiumClient({
publicKey: process.env.CB_PUBLIC_KEY,
secretKey: process.env.CB_SECRET_KEY,
environment: class="code-string">'production', class="code-comment">// or class="code-string">'sandbox' for testing
});
Python
1 2 3 4 5 6 7
from company_belgium import Client
client = Client(
public_key=os.getenv(class="code-string">'CB_PUBLIC_KEY'),
secret_key=os.getenv(class="code-string">'CB_SECRET_KEY'),
environment=class="code-string">'production'
)
Step 4: First KYC Verification
Complete TypeScript Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
async function verifyNewClient(enterpriseNumber: string) {
try {
class="code-comment">// 1. Basic verification
const company = await client.companies.get(enterpriseNumber);
class="code-comment">// 2. Compliance checks
const checks = {
isActive: company.status === class="code-string">'AC',
hasValidVAT: company.vatNumber !== null,
hasAddress: company.addresses.length > 0,
isNotBankrupt: company.status !== class="code-string">'ST',
createdRecently: isWithinLastYear(company.startDate),
};
class="code-comment">// 3. UBO register verification (if needed)
let uboVerified = false;
if (checks.isActive) {
const ubo = await client.companies.getUBO(enterpriseNumber);
uboVerified = ubo !== null && ubo.beneficiaries.length > 0;
}
class="code-comment">// 4. Peppol verification (bonus)
const peppolRegistered = await client.peppol.check(company.vatNumber);
class="code-comment">// 5. Generate KYC report
const kycReport = {
enterpriseNumber,
companyName: company.denomination,
verificationDate: new Date().toISOString(),
checks,
uboVerified,
peppolRegistered,
riskLevel: calculateRiskLevel(checks),
status: allChecksPassed(checks) ? class="code-string">'APPROVED' : class="code-string">'REVIEW_REQUIRED',
};
class="code-comment">// 6. Save for audit
await saveKYCReport(kycReport);
return kycReport;
} catch (error) {
console.error(class="code-string">'KYC verification failed:', error);
throw new KYCVerificationError(error.message);
}
}
class="code-comment">// Helper function
function calculateRiskLevel(checks: Checks): class="code-string">'LOW' | class="code-string">'MEDIUM' | class="code-string">'HIGH' {
const passedChecks = Object.values(checks).filter(Boolean).length;
const totalChecks = Object.values(checks).length;
const ratio = passedChecks / totalChecks;
if (ratio >= 0.9) return class="code-string">'LOW';
if (ratio >= 0.7) return class="code-string">'MEDIUM';
return class="code-string">'HIGH';
}
Advanced Use Cases
Case 1: Automated Onboarding
Create a complete client onboarding workflow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
async function automaticOnboarding(clientData: ClientData) {
class="code-comment">// Step 1: Validate enterprise number
if (!isValidCBENumber(clientData.enterpriseNumber)) {
return { status: class="code-string">'REJECTED', reason: class="code-string">'Invalid CBE number format' };
}
class="code-comment">// Step 2: KYC verification via API
const kycReport = await verifyNewClient(clientData.enterpriseNumber);
class="code-comment">// Step 3: Automatic decision
if (kycReport.status === class="code-string">'APPROVED' && kycReport.riskLevel === class="code-string">'LOW') {
class="code-comment">// Auto-approval: create client file
await createClientFile(clientData, kycReport);
await sendWelcomeEmail(clientData.email);
return { status: class="code-string">'APPROVED', clientId: newClientId };
}
class="code-comment">// Step 4: Manual review for complex cases
if (kycReport.riskLevel === class="code-string">'HIGH') {
await notifyComplianceOfficer(kycReport);
return { status: class="code-string">'PENDING_REVIEW', reason: class="code-string">'High risk - manual review required' };
}
class="code-comment">// Step 5: Request additional documents
await requestAdditionalDocuments(clientData.email, kycReport.missingData);
return { status: class="code-string">'PENDING_DOCUMENTS' };
}
Case 2: Continuous Monitoring
Implement automatic monitoring of your clients:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
class="code-comment">// Daily cron job
async function dailyClientMonitoring() {
const activeClients = await getActiveClients();
for (const client of activeClients) {
class="code-comment">// Check changes since last verification
const changes = await client.companies.getChanges(
client.enterpriseNumber,
{ since: client.lastVerificationDate }
);
if (changes.length > 0) {
const significantChanges = changes.filter(change =>
[class="code-string">'status', class="code-string">'address', class="code-string">'administrators', class="code-string">'juridicalForm'].includes(change.field)
);
if (significantChanges.length > 0) {
await notifyComplianceTeam({ client, changes: significantChanges, urgency: class="code-string">'MEDIUM' });
await flagForKYCReview(client.id);
}
await updateLastVerificationDate(client.id);
}
}
}
Case 3: Batch Verification
Verify multiple companies in parallel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
async function batchVerification(enterpriseNumbers: string[]) {
const results = await Promise.allSettled(
enterpriseNumbers.map(num => verifyNewClient(num))
);
return {
total: enterpriseNumbers.length,
successful: results.filter(r => r.status === class="code-string">'fulfilled').length,
failed: results.filter(r => r.status === class="code-string">'rejected').length,
details: results.map((r, i) => ({
enterpriseNumber: enterpriseNumbers[i],
status: r.status,
data: r.status === class="code-string">'fulfilled' ? r.value : null,
error: r.status === class="code-string">'rejected' ? r.reason : null,
})),
};
}
Compliance and Audit Trail
Preservation of Verification Evidence
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
interface KYCAuditLog {
id: string;
timestamp: Date;
enterpriseNumber: string;
apiResponse: any;
verifiedBy: string;
verificationResult: class="code-string">'APPROVED' | class="code-string">'REJECTED' | class="code-string">'REVIEW';
riskLevel: class="code-string">'LOW' | class="code-string">'MEDIUM' | class="code-string">'HIGH';
}
async function saveAuditLog(verification: KYCAuditLog) {
await db.kycAuditLogs.insert({
...verification,
createdAt: new Date(),
retentionUntil: addYears(new Date(), 10), class="code-comment">// 10-year retention
});
await s3.putObject({
Bucket: class="code-string">'kyc-audit-logs',
Key: class="code-string">`${verification.id}.json`,
Body: JSON.stringify(verification),
ServerSideEncryption: class="code-string">'AES256',
});
}
Costs and Limits
Company Belgium Pricing Plans
| Plan | Requests/month | Price | Ideal for |
|---|---|---|---|
| Free | 100 | €0 | Testing and small volumes |
| Starter | 1,000 | €29/month | Starting centers |
| Professional | 10,000 | €149/month | Established centers |
| Enterprise | Unlimited | Upon request | Large volumes |
> 💡 ROI calculation: If your team bills at €50/h, saving 30 min per verification = €25 savings. From 6 verifications/month, the Starter plan pays for itself!
Rate Limits
- Free: 10 req/min
- Starter: 60 req/min
- Professional: 300 req/min
- Enterprise: Custom
Support and Resources
Official Documentation
Technical Support
- Email: support@companybelgium.be
- Live chat: 9am-6pm (business days)
- Community forum: forum.companybelgium.be
- Status page: status.companybelgium.be
Conclusion
Automating KYC verification via the Company Belgium API radically transforms your compliance process:
✅ 80% time saved on verifications
✅ 100% reliability with official CBE/BCE data
✅ Guaranteed compliance with complete audit trail
✅ Scalability: from 10 to 10,000 verifications/month
✅ Immediate ROI from the first weeks
Start Today
> 🚀 Launch offer: First month free on the Professional plan with code AUTOKYC2026
Questions? Our team is available to support you in your integration.
👉 Contact us or Book a demo
---
Related articles:
Frequently asked questions
How do you automate KYC verification of a Belgian company with the BCE/KBO API?
Via the Company Belgium API, successively call GET /api/companies/{number} for status, legal form, address and VAT number, then GET /api/companies/{number}/ubo to access the UBO register if publicly available. Each response is timestamped. You can then automatically calculate a risk level and trigger immediate approval, manual review or a request for additional documents based on the result.
Is KYC verification via the BCE API compliant with the Belgian anti-money laundering law of 18 September 2017?
The Company Belgium API accesses official BCE/KBO data, which constitutes a recognised reference source for legal entity identity verification. For full compliance with the law of 18 September 2017, you must keep a complete audit trail of each verification with timestamp, result and source, for a minimum of 10 years. The API provides the timestamp and traceability; retention is the responsibility of your document management system.
How long does automated KYC verification take versus manual for a Belgian domiciliation centre?
Manual verification takes an average of 30 minutes: 10 minutes searching the BCE/KBO website, 8 minutes for the UBO register, 5 minutes for VAT validation and 7 minutes for establishments. With the Company Belgium API, the same verification takes about 2 seconds. For a centre handling 100 new clients per month, automation frees up approximately 50 hours of work per month.
How do you handle inactive or bankrupt companies in an automated KYC process in Belgium?
The API returns the status field for each company: AC means active, ST means ceased, FA means bankruptcy. Your KYC code must handle these cases specifically. For a company with ST status, retain historical data for AML compliance (10-year retention obligation). For FA status, trigger an immediate alert to the compliance team. The BCE/KBO retains data even for ceased companies, ensuring full traceability.
Comments
Related articles

Belgian Crossroads Bank for Enterprises (BCE/KBO) API: complete English developer documentation
English developer documentation for the Belgian Crossroads Bank for Enterprises API. Overview of the BCE/KBO registry, legal context, access options, quick start with cURL examples, and integration patterns for international developers.

Rate limits, quotas and caching to scale a BCE/KBO application: reference architecture
Your app queries the BCE/KBO API at volume — how to avoid 429s, control costs and guarantee latency? Reference architecture with multi-layer cache, request queue, observability and webhooks. Concrete patterns and target numbers.

BCE/KBO API endpoints reference: complete list of REST routes (companies, addresses, NACE, UBO, establishments, Peppol)
Comprehensive technical reference of the Company Belgium REST API endpoints: search, company record, addresses, NACE activities, establishments, directors, UBO, Peppol verification. With response schemas, parameters and error codes.
