KYB Verification (Know Your Business)
KYB verification enables you to verify business identities as part of your compliance onboarding flow. A KYB application collects business information, beneficial owners (UBOs), directors, and supporting documents, then runs registry checks and screening before a compliance officer makes a final decision.
KYB Application Lifecycle
┌───────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐
│ DRAFT │────▶│ SUBMITTED │────▶│ IN_REVIEW │────▶│ APPROVED │
└───────┘ └───────────┘ └─────┬─────┘ └──────────┘
│
▼
┌──────────┐
│ REJECTED │
└──────────┘
Statuses:
| Status | Description |
|---|---|
draft | Application created, still being populated |
submitted | Submitted for review (registry verified, UBOs collected) |
in_review | Under compliance officer review or screening |
approved | Verification passed |
rejected | Verification failed |
expired | Application expired before completion |
requires_info | Additional information requested |
Create a KYB Application
Start a new KYB verification by providing core business details.
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/kyb/verifications \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"legal_name": "Acme Holdings Ltd",
"trading_name": "Acme",
"registration_number": "RC-123456",
"country": "NG",
"business_type": "limited_liability",
"industry_sector": "Financial Services",
"tax_id": "TIN-9876543",
"incorporation_date": "2018-03-15T00:00:00Z"
}'
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
"Content-Type": "application/json",
},
body: JSON.stringify({
legal_name: "Acme Holdings Ltd",
trading_name: "Acme",
registration_number: "RC-123456",
country: "NG",
business_type: "limited_liability",
industry_sector: "Financial Services",
tax_id: "TIN-9876543",
incorporation_date: "2018-03-15T00:00:00Z",
}),
}
);
const application = await response.json();
console.log(`Application ID: ${application.id}, Status: ${application.status}`);
response = requests.post(
f"{BASE_URL}/kyb/verifications",
headers=HEADERS,
json={
"legal_name": "Acme Holdings Ltd",
"trading_name": "Acme",
"registration_number": "RC-123456",
"country": "NG",
"business_type": "limited_liability",
"industry_sector": "Financial Services",
"tax_id": "TIN-9876543",
"incorporation_date": "2018-03-15T00:00:00Z",
},
)
application = response.json()
print(f"Application ID: {application['id']}, Status: {application['status']}")
payload := map[string]interface{}{
"legal_name": "Acme Holdings Ltd",
"trading_name": "Acme",
"registration_number": "RC-123456",
"country": "NG",
"business_type": "limited_liability",
"industry_sector": "Financial Services",
"tax_id": "TIN-9876543",
"incorporation_date": "2018-03-15T00:00:00Z",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", baseURL+"/kyb/verifications", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
Request body fields:
| Field | Type | Required | Description |
|---|---|---|---|
legal_name | string | Yes | Registered legal name of the business |
trading_name | string | No | Trade name / DBA |
registration_number | string | Yes | Company registration number |
country | string | Yes | ISO 3166-1 alpha-2 country code |
business_type | string | Yes | One of: sole_proprietorship, partnership, limited_liability, corporation, cooperative, ngo, trust, other |
industry_sector | string | Yes | Industry or sector classification |
tax_id | string | No | Tax identification number |
incorporation_date | string | Yes | Incorporation date in RFC 3339 format |
Response:
{
"id": "kyb_abc123",
"status": "draft",
"business_entity": {
"legal_name": "Acme Holdings Ltd",
"trading_name": "Acme",
"registration_number": "RC-123456",
"country": "NG",
"business_type": "limited_liability",
"industry_sector": "Financial Services",
"tax_id": "TIN-9876543",
"incorporation_date": "2018-03-15T00:00:00Z"
},
"ubos": [],
"directors": [],
"documents": [],
"created_at": "2025-06-01T12:00:00Z",
"updated_at": "2025-06-01T12:00:00Z"
}
Update Business Information
Update or add additional details such as addresses after creating the application.
- cURL
- Node.js
- Python
- Go
curl -X PATCH https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"trading_name": "Acme International",
"registered_address": {
"street1": "42 Marina Road",
"city": "Lagos",
"state": "Lagos",
"postal_code": "101001",
"country": "NG"
},
"operating_address": {
"street1": "10 Broad Street",
"city": "Lagos",
"state": "Lagos",
"postal_code": "101002",
"country": "NG"
}
}'
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123",
{
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
"Content-Type": "application/json",
},
body: JSON.stringify({
trading_name: "Acme International",
registered_address: {
street1: "42 Marina Road",
city: "Lagos",
state: "Lagos",
postal_code: "101001",
country: "NG",
},
}),
}
);
response = requests.patch(
f"{BASE_URL}/kyb/verifications/kyb_abc123",
headers=HEADERS,
json={
"trading_name": "Acme International",
"registered_address": {
"street1": "42 Marina Road",
"city": "Lagos",
"state": "Lagos",
"postal_code": "101001",
"country": "NG",
},
},
)
payload := map[string]interface{}{
"trading_name": "Acme International",
"registered_address": map[string]string{
"street1": "42 Marina Road",
"city": "Lagos",
"state": "Lagos",
"postal_code": "101001",
"country": "NG",
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("PATCH", baseURL+"/kyb/verifications/kyb_abc123", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
Address fields:
| Field | Type | Required | Description |
|---|---|---|---|
street1 | string | Yes | Primary street address |
street2 | string | No | Secondary address line |
city | string | Yes | City |
state | string | Yes | State or province |
postal_code | string | Yes | Postal / ZIP code |
country | string | Yes | ISO 3166-1 alpha-2 country code |
Registry Verification
Verify the business against the official corporate registry in its country of incorporation. This checks that the registration number, legal name, and incorporation details match public records.
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/verify-registry \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/verify-registry",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
},
}
);
const result = await response.json();
console.log(`Registry verified: ${result.registry_verification.verified}`);
response = requests.post(
f"{BASE_URL}/kyb/verifications/kyb_abc123/verify-registry",
headers=HEADERS,
)
result = response.json()
print(f"Registry verified: {result['registry_verification']['verified']}")
req, _ := http.NewRequest("POST", baseURL+"/kyb/verifications/kyb_abc123/verify-registry", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
resp, err := http.DefaultClient.Do(req)
Response includes:
{
"registry_verification": {
"verified": true,
"company_name": "Acme Holdings Ltd",
"status": "active",
"incorporation_date": "2018-03-15",
"registered_address": "42 Marina Road, Lagos, Nigeria"
}
}
Run registry verification early in the process. If the business cannot be found in the registry, it may indicate incorrect details or a fraudulent application.
Manage UBOs (Ultimate Beneficial Owners)
UBOs are individuals who ultimately own or control the business. Regulations typically require identifying anyone with 25% or more ownership, or who exercises significant control.
Add a UBO
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/ubos \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@acme.com",
"phone": "+2341234567890",
"dob": "1985-06-15T00:00:00Z",
"nationality": "NG",
"ownership_percentage": 40,
"role": "owner"
}'
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/ubos",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
"Content-Type": "application/json",
},
body: JSON.stringify({
first_name: "John",
last_name: "Doe",
email: "john.doe@acme.com",
dob: "1985-06-15T00:00:00Z",
nationality: "NG",
ownership_percentage: 40,
role: "owner",
}),
}
);
const ubo = await response.json();
console.log(`UBO ID: ${ubo.id}`);
response = requests.post(
f"{BASE_URL}/kyb/verifications/kyb_abc123/ubos",
headers=HEADERS,
json={
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@acme.com",
"dob": "1985-06-15T00:00:00Z",
"nationality": "NG",
"ownership_percentage": 40,
"role": "owner",
},
)
ubo = response.json()
print(f"UBO ID: {ubo['id']}")
payload := map[string]interface{}{
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@acme.com",
"dob": "1985-06-15T00:00:00Z",
"nationality": "NG",
"ownership_percentage": 40,
"role": "owner",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", baseURL+"/kyb/verifications/kyb_abc123/ubos", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
UBO fields:
| Field | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes | First name |
last_name | string | Yes | Last name |
email | string | Yes | Email address (used for identity verification links) |
phone | string | No | Phone number |
dob | string | Yes | Date of birth in RFC 3339 format |
nationality | string | Yes | ISO 3166-1 alpha-2 country code |
ownership_percentage | number | Yes | Percentage of ownership (0-100) |
role | string | Yes | One of: owner, controlling_person |
Edit a UBO
curl -X PATCH https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/ubos/ubo_456 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"ownership_percentage": 35
}'
Delete a UBO
curl -X DELETE https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/ubos/ubo_456 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
UBO Identity Verification
Each UBO must complete individual identity verification (KYC). Generate a verification link for a UBO and send it to them:
# Get a verification URL for the UBO
curl https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/ubos/ubo_456/verification-url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
Response:
{
"verification_url": "https://verify.korastratum.com/v/abc123def456"
}
The verification URL is single-use and expires after 7 days. Generate a new one if it expires before the UBO completes verification.
Manage Directors
Directors are officers of the company who may or may not also be UBOs.
Add a Director
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/directors \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Smith",
"dob": "1980-01-20T00:00:00Z",
"nationality": "NG",
"role": "director",
"is_also_ubo": false
}'
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/directors",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
"Content-Type": "application/json",
},
body: JSON.stringify({
first_name: "Jane",
last_name: "Smith",
dob: "1980-01-20T00:00:00Z",
nationality: "NG",
role: "director",
is_also_ubo: false,
}),
}
);
const director = await response.json();
console.log(`Director ID: ${director.id}`);
response = requests.post(
f"{BASE_URL}/kyb/verifications/kyb_abc123/directors",
headers=HEADERS,
json={
"first_name": "Jane",
"last_name": "Smith",
"dob": "1980-01-20T00:00:00Z",
"nationality": "NG",
"role": "director",
"is_also_ubo": False,
},
)
director = response.json()
print(f"Director ID: {director['id']}")
payload := map[string]interface{}{
"first_name": "Jane",
"last_name": "Smith",
"dob": "1980-01-20T00:00:00Z",
"nationality": "NG",
"role": "director",
"is_also_ubo": false,
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", baseURL+"/kyb/verifications/kyb_abc123/directors", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
Director fields:
| Field | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes | First name |
last_name | string | Yes | Last name |
dob | string | Yes | Date of birth in RFC 3339 format |
nationality | string | Yes | ISO 3166-1 alpha-2 country code |
role | string | Yes | One of: director, ceo, cfo, secretary |
is_also_ubo | boolean | Yes | Whether this director is also a UBO |
Delete a Director
curl -X DELETE https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/directors/dir_789 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
Upload Documents
Upload supporting documents for the KYB application. Documents are sent as multipart form data.
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/documents \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-F "type=certificate_of_incorporation" \
-F "document_type=certificate_of_incorporation" \
-F "file=@/path/to/certificate.pdf" \
-F "file_name=certificate.pdf"
const formData = new FormData();
formData.append("type", "certificate_of_incorporation");
formData.append("document_type", "certificate_of_incorporation");
formData.append("file", fileBlob, "certificate.pdf");
formData.append("file_name", "certificate.pdf");
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/documents",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
},
body: formData,
}
);
const doc = await response.json();
console.log(`Document ID: ${doc.id}, Status: ${doc.status}`);
with open("/path/to/certificate.pdf", "rb") as f:
response = requests.post(
f"{BASE_URL}/kyb/verifications/kyb_abc123/documents",
headers={"Authorization": f"Bearer {API_KEY}", "X-Tenant-ID": TENANT_ID},
files={"file": ("certificate.pdf", f, "application/pdf")},
data={
"type": "certificate_of_incorporation",
"document_type": "certificate_of_incorporation",
"file_name": "certificate.pdf",
},
)
doc = response.json()
print(f"Document ID: {doc['id']}")
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
writer.WriteField("type", "certificate_of_incorporation")
writer.WriteField("document_type", "certificate_of_incorporation")
writer.WriteField("file_name", "certificate.pdf")
part, _ := writer.CreateFormFile("file", "certificate.pdf")
file, _ := os.Open("/path/to/certificate.pdf")
io.Copy(part, file)
writer.Close()
req, _ := http.NewRequest("POST", baseURL+"/kyb/verifications/kyb_abc123/documents", &buf)
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := http.DefaultClient.Do(req)
Supported document types:
| Type | Description |
|---|---|
certificate_of_incorporation | Certificate of incorporation |
memorandum_of_association | Memorandum of association |
articles_of_association | Articles of association |
board_resolution | Board resolution |
shareholder_register | Shareholder register |
proof_of_address | Proof of business address |
tax_clearance | Tax clearance certificate |
business_license | Business license |
financial_statement | Financial statement |
regulatory_license | Regulatory license |
other | Other supporting document |
Delete a Document
curl -X DELETE https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/documents/doc_101 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
Submit for Review
Once all business information, UBOs, directors, and documents have been added, submit the application for compliance review.
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"attestations": {
"information_accurate": true,
"authorized_representative": true
}
}'
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/submit",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
"Content-Type": "application/json",
},
body: JSON.stringify({
attestations: {
information_accurate: true,
authorized_representative: true,
},
}),
}
);
response = requests.post(
f"{BASE_URL}/kyb/verifications/kyb_abc123/submit",
headers=HEADERS,
json={
"attestations": {
"information_accurate": True,
"authorized_representative": True,
}
},
)
payload := map[string]interface{}{
"attestations": map[string]bool{
"information_accurate": true,
"authorized_representative": true,
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", baseURL+"/kyb/verifications/kyb_abc123/submit", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
Submission is irreversible. Ensure all information is complete and accurate before submitting. The application status will change from draft to submitted.
Review a KYB Application (Admin)
Compliance officers can approve or reject a submitted KYB application.
- cURL
- Node.js
- Python
- Go
curl -X POST https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/review \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"decision": "approved",
"notes": "All documents verified. Registry match confirmed. UBO KYC complete."
}'
const response = await fetch(
"https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123/review",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
"Content-Type": "application/json",
},
body: JSON.stringify({
decision: "approved",
notes: "All documents verified. Registry match confirmed. UBO KYC complete.",
}),
}
);
response = requests.post(
f"{BASE_URL}/kyb/verifications/kyb_abc123/review",
headers=HEADERS,
json={
"decision": "approved",
"notes": "All documents verified. Registry match confirmed. UBO KYC complete.",
},
)
payload := map[string]interface{}{
"decision": "approved",
"notes": "All documents verified. Registry match confirmed. UBO KYC complete.",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", baseURL+"/kyb/verifications/kyb_abc123/review", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
Review decision fields:
| Field | Type | Required | Description |
|---|---|---|---|
decision | string | Yes | One of: approved, rejected, requires_info |
notes | string | No | Reviewer notes explaining the decision |
List KYB Verifications
Retrieve a paginated list of KYB applications, optionally filtered by status.
- cURL
- Node.js
- Python
- Go
# List all applications
curl "https://api.korastratum.com/api/v1/kyb/verifications?limit=20" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
# Filter by status
curl "https://api.korastratum.com/api/v1/kyb/verifications?status=in_review&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
const params = new URLSearchParams({ status: "in_review", limit: "10" });
const response = await fetch(
`https://api.korastratum.com/api/v1/kyb/verifications?${params}`,
{
headers: {
Authorization: "Bearer YOUR_API_KEY",
"X-Tenant-ID": "YOUR_TENANT_ID",
},
}
);
const { data, total_count } = await response.json();
console.log(`Found ${total_count} applications`);
response = requests.get(
f"{BASE_URL}/kyb/verifications",
headers=HEADERS,
params={"status": "in_review", "limit": 10},
)
result = response.json()
print(f"Found {result['total_count']} applications")
req, _ := http.NewRequest("GET", baseURL+"/kyb/verifications?status=in_review&limit=10", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("X-Tenant-ID", tenantID)
resp, err := http.DefaultClient.Do(req)
Query parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: draft, submitted, in_review, approved, rejected |
page | integer | Page number (1-based) |
limit | integer | Items per page (default 20, max 100) |
Get a KYB Verification
Retrieve full details of a single KYB application, including all UBOs, directors, documents, and screening results.
curl https://api.korastratum.com/api/v1/kyb/verifications/kyb_abc123 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
Webhook Events
KYB lifecycle events are delivered via webhook:
| Event | Trigger |
|---|---|
kyb.created | New KYB application created |
kyb.submitted | Application submitted for review |
kyb.approved | Application approved |
kyb.rejected | Application rejected |
kyb.requires_info | Additional information requested |
kyb.ubo.verification_completed | UBO identity verification completed |
kyb.registry.verified | Registry verification completed |
Configure webhooks in the Webhooks guide to receive real-time notifications for KYB events.