Documentation Index Fetch the complete documentation index at: https://docs.gu1.ai/llms.txt
Use this file to discover all available pages before exploring further.
Complete KYB Verification Workflow
gu1’s KYB workflow automates the entire business verification process from initial data collection to ongoing monitoring. This guide walks through each step with technical implementation details.
Workflow Overview
Step 1: Initial Data Collection
What to Collect
Gather basic business information from your application form:
Company Name : Legal name and trade name
Registration Number : Government-issued business registration
Tax ID : EIN (US), CNPJ (Brazil), RFC (Mexico), etc.
Incorporation Date : When the business was formed
Country : Jurisdiction of incorporation
Business Address : Registered office location
Industry : Type of business activity
Expected Transaction Volume : Monthly/annual estimates
const businessApplication = {
legalName: "Tech Solutions Sociedade Anônima" ,
tradeName: "Tech Solutions" ,
registrationNumber: "12.345.678/0001-90" ,
taxId: "12.345.678/0001-90" ,
incorporationDate: "2020-06-15" ,
country: "BR" ,
address: {
street: "Av. Paulista, 1000" ,
city: "São Paulo" ,
state: "SP" ,
postalCode: "01310-100"
},
industry: "Software Development" ,
website: "https://techsolutions.com.br" ,
expectedMonthlyVolume: 250000 ,
businessDescription: "B2B SaaS platform for enterprise clients"
};
Step 2: Create Business Entity
Use the Entities API to create a company entity in gu1:
curl -X POST http://api.gu1.ai/entities \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "company",
"externalId": "business_12345",
"name": "Tech Solutions Sociedade Anônima",
"taxId": "12.345.678/0001-90",
"countryCode": "BR",
"entityData": {
"company": {
"legalName": "Tech Solutions Sociedade Anônima",
"tradeName": "Tech Solutions",
"incorporationDate": "2020-06-15",
"industry": "Software Development",
"employeeCount": 50,
"revenue": 5000000
}
},
"attributes": {
"registrationNumber": "12.345.678/0001-90",
"website": "https://techsolutions.com.br",
"registeredAddress": "Av. Paulista, 1000, São Paulo",
"expectedMonthlyVolume": 250000,
"applicationDate": "2024-10-03T10:00:00Z"
}
}'
Response:
{
"success" : true ,
"entity" : {
"id" : "660e9511-f39c-52e5-b827-557766551111" ,
"externalId" : "business_12345" ,
"type" : "company" ,
"name" : "Tech Solutions Sociedade Anônima" ,
"riskScore" : 0 ,
"status" : "under_review" ,
"createdAt" : "2024-10-03T10:00:00Z"
}
}
Step 3: Document Upload & Verification
Upload required business documents for verification:
Required Documents
Articles of Incorporation - Founding document
Business License - Government-issued operating permit
Tax Certificate - Proof of tax registration
Proof of Address - Utility bill or bank statement
Beneficial Ownership Declaration - UBO information
Upload Documents
async function uploadBusinessDocuments ( entityId , documents ) {
const documentUploads = [];
for ( const doc of documents ) {
const formData = new FormData ();
formData . append ( 'file' , doc . file );
formData . append ( 'documentType' , doc . type );
formData . append ( 'entityId' , entityId );
const response = await fetch ( 'http://api.gu1.ai/documents' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_KEY } `
},
body: formData
});
documentUploads . push ( await response . json ());
}
return documentUploads ;
}
// Usage
const documents = [
{ file: articlesOfIncorporation , type: 'articles_of_incorporation' },
{ file: businessLicense , type: 'business_license' },
{ file: taxCertificate , type: 'tax_certificate' },
{ file: proofOfAddress , type: 'proof_of_address' }
];
const uploadedDocs = await uploadBusinessDocuments ( entityId , documents );
Step 4: AI Analysis & Risk Assessment
Request AI-powered analysis of the business entity:
async function requestAIAnalysis ( entityId ) {
const response = await fetch (
`http://api.gu1.ai/entities/ ${ entityId } /ai-analysis` ,
{
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
analysisType: 'kyb_verification' ,
includeDocuments: true ,
checkSanctions: true ,
checkAdverseMedia: true
})
}
);
return await response . json ();
}
AI Analysis Response:
{
"analysisId" : "analysis_abc123" ,
"entityId" : "660e9511-f39c-52e5-b827-557766551111" ,
"riskScore" : 35 ,
"riskLevel" : "medium" ,
"findings" : {
"documentVerification" : {
"status" : "verified" ,
"confidence" : 0.95 ,
"articlesOfIncorporation" : "valid" ,
"businessLicense" : "valid" ,
"taxCertificate" : "valid"
},
"businessLegitimacy" : {
"status" : "verified" ,
"registrationVerified" : true ,
"taxIdValid" : true ,
"addressConfirmed" : true
},
"sanctionsScreening" : {
"status" : "clear" ,
"listsChecked" : [ "OFAC" , "UN" , "EU" , "UK" ],
"matches" : []
},
"adverseMedia" : {
"status" : "minor_flags" ,
"findings" : [
{
"source" : "news_article" ,
"date" : "2023-05-15" ,
"summary" : "Small tax dispute resolved" ,
"severity" : "low"
}
]
},
"riskFactors" : [
{
"factor" : "new_business" ,
"impact" : 20 ,
"description" : "Company incorporated less than 5 years ago"
},
{
"factor" : "high_growth_industry" ,
"impact" : 15 ,
"description" : "Software industry has elevated fraud risk"
},
{
"factor" : "clean_compliance_history" ,
"impact" : -10 ,
"description" : "No regulatory violations found"
}
]
},
"recommendation" : "approve_with_monitoring" ,
"nextSteps" : [
"Verify beneficial ownership" ,
"Set transaction monitoring thresholds" ,
"Schedule 6-month review"
]
}
Step 5: Risk-Based Decision
Based on the risk score, route to appropriate workflow:
async function processKYBDecision ( analysisResult ) {
const { riskScore , riskLevel , recommendation } = analysisResult ;
if ( riskScore < 30 ) {
// Low Risk - Auto-approve
return await autoApprove ( analysisResult . entityId );
} else if ( riskScore < 70 ) {
// Medium Risk - Enhanced Due Diligence
return await enhancedDueDiligence ( analysisResult . entityId );
} else {
// High Risk - Manual Review Required
return await flagForManualReview ( analysisResult . entityId , analysisResult . findings );
}
}
async function autoApprove ( entityId ) {
// Update entity status to approved
await fetch ( `http://api.gu1.ai/entities/ ${ entityId } ` , {
method: 'PATCH' ,
headers: {
'Authorization' : `Bearer ${ API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
attributes: {
kybStatus: 'approved' ,
approvedAt: new Date (). toISOString (),
approvedBy: 'automated_system' ,
reviewNotes: 'Low risk - auto-approved'
}
})
});
// Send approval notification
await sendApprovalEmail ( entityId );
// Enable monitoring
await enableOngoingMonitoring ( entityId );
return { status: 'approved' , action: 'auto_approved' };
}
async function enhancedDueDiligence ( entityId ) {
// Request additional information
await requestAdditionalDocs ( entityId , [
'financial_statements' ,
'ownership_structure' ,
'source_of_funds'
]);
// Update status
await updateEntityStatus ( entityId , 'enhanced_due_diligence' );
return { status: 'pending' , action: 'edd_required' };
}
async function flagForManualReview ( entityId , findings ) {
// Create review task
await createReviewTask ({
entityId ,
priority: 'high' ,
assignTo: 'compliance_team' ,
findings ,
dueDate: new Date ( Date . now () + 24 * 60 * 60 * 1000 ) // 24 hours
});
return { status: 'manual_review' , action: 'flagged_for_review' };
}
Step 6: Beneficial Ownership Verification
Identify and verify Ultimate Beneficial Owners (UBOs):
async function verifyBeneficialOwners ( entityId , owners ) {
const verifiedOwners = [];
for ( const owner of owners ) {
// Create person entity for each UBO
const uboEntity = await fetch ( 'http://api.gu1.ai/entities' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
type: 'person' ,
externalId: `ubo_ ${ owner . id } ` ,
name: ` ${ owner . firstName } ${ owner . lastName } ` ,
countryCode: owner . nationality ,
entityData: {
person: {
firstName: owner . firstName ,
lastName: owner . lastName ,
dateOfBirth: owner . dateOfBirth ,
nationality: owner . nationality
}
},
attributes: {
ownershipPercentage: owner . ownership ,
isPEP: owner . isPEP ,
relationshipToCompany: 'beneficial_owner'
}
})
});
const ubo = await uboEntity . json ();
// Run KYC checks on UBO
const kycResult = await runKYCCheck ( ubo . entity . id );
// Create relationship between company and UBO
await createRelationship ({
fromEntityId: entityId ,
toEntityId: ubo . entity . id ,
relationshipType: 'beneficial_owner' ,
ownershipPercentage: owner . ownership
});
verifiedOwners . push ({
... ubo . entity ,
kycStatus: kycResult . status ,
riskScore: kycResult . riskScore
});
}
return verifiedOwners ;
}
Step 7: Setup Ongoing Monitoring
Enable continuous monitoring for approved businesses:
async function setupOngoingMonitoring ( entityId ) {
// Configure monitoring rules
await fetch ( 'http://api.gu1.ai/rules' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
name: `KYB Monitoring - ${ entityId } ` ,
entityId: entityId ,
rules: [
{
type: 'sanctions_screening' ,
frequency: 'daily' ,
action: 'alert_compliance_team'
},
{
type: 'adverse_media' ,
frequency: 'weekly' ,
action: 'create_review_task'
},
{
type: 'ownership_changes' ,
frequency: 'realtime' ,
action: 'trigger_reverification'
},
{
type: 'transaction_anomalies' ,
threshold: 'high' ,
action: 'flag_for_review'
}
]
})
});
// Setup webhook notifications
await configureWebhook ({
entityId ,
events: [
'sanctions_match' ,
'adverse_media_found' ,
'ownership_change' ,
'transaction_anomaly'
],
url: 'https://your-app.com/webhooks/kyb-alerts'
});
}
Step 8: Status Updates & Notifications
Keep the business informed throughout the process:
async function sendStatusUpdate ( entityId , status , details ) {
// Get entity details
const entity = await getEntity ( entityId );
// Send email notification
await sendEmail ({
to: entity . attributes . contactEmail ,
subject: `KYB Verification Update - ${ status } ` ,
template: 'kyb_status_update' ,
data: {
companyName: entity . name ,
status: status ,
details: details ,
nextSteps: getNextSteps ( status ),
dashboardUrl: `https://app.gu1.ai/onboarding/ ${ entityId } `
}
});
// Send webhook to your system
await sendWebhook ({
event: 'kyb_status_changed' ,
entityId: entityId ,
status: status ,
timestamp: new Date (). toISOString (),
details: details
});
}
// Status update examples
await sendStatusUpdate ( entityId , 'documents_received' , {
message: 'We have received your documents and are processing them.'
});
await sendStatusUpdate ( entityId , 'approved' , {
message: 'Your business has been verified and approved!' ,
approvalDate: new Date (). toISOString ()
});
await sendStatusUpdate ( entityId , 'additional_info_required' , {
message: 'We need additional information to complete your verification.' ,
requiredDocuments: [ 'financial_statements' , 'ownership_structure' ]
});
Complete Workflow Implementation
Here’s a complete function that orchestrates the entire KYB workflow:
async function executeKYBWorkflow ( applicationData ) {
try {
// Step 1 & 2: Create entity
console . log ( 'Creating business entity...' );
const entity = await createBusinessEntity ( applicationData );
// Step 3: Upload documents
console . log ( 'Uploading verification documents...' );
await uploadBusinessDocuments ( entity . id , applicationData . documents );
// Step 4: Request AI analysis
console . log ( 'Running AI analysis...' );
const analysis = await requestAIAnalysis ( entity . id );
// Step 5: Make risk-based decision
console . log ( 'Processing KYB decision...' );
const decision = await processKYBDecision ( analysis );
if ( decision . status === 'approved' ) {
// Step 6: Verify UBOs (for approved entities)
console . log ( 'Verifying beneficial owners...' );
await verifyBeneficialOwners ( entity . id , applicationData . beneficialOwners );
// Step 7: Setup monitoring
console . log ( 'Setting up ongoing monitoring...' );
await setupOngoingMonitoring ( entity . id );
}
// Step 8: Send status update
console . log ( 'Sending status notification...' );
await sendStatusUpdate ( entity . id , decision . status , analysis . findings );
return {
success: true ,
entityId: entity . id ,
status: decision . status ,
riskScore: analysis . riskScore ,
decision: decision
};
} catch ( error ) {
console . error ( 'KYB workflow error:' , error );
return {
success: false ,
error: error . message
};
}
}
Timeline Estimates
Risk Level Automated Processing With Manual Review Traditional Process Low Risk 2-5 minutes 30 minutes 2-3 days Medium Risk 15-30 minutes 2-4 hours 3-5 days High Risk 30-60 minutes 1-2 days 5-10 days
Next Steps
Data Requirements See detailed data fields needed for KYB
Complete Example Full working code implementation
API Reference Entity creation API documentation
Webhooks Setup real-time notifications