KYB · Business verification
Corporate onboarding with entity information, connected related parties, documents and forms.
Corporate customer onboarding. Use eventType: "KYB_EVENT".
Flow Overview
- Corporate Particular
- CRP Collector
- Required Documents (main + CRPs)
- Non-Required Documents
- Required Forms (main + CRPs)
- [Screen Check]
- Decision
KYB Node Routing Table
| nodeType | API | Description |
|---|---|---|
flow_action_corporate_particular |
workflow.kyb.particular.data |
Submit corporate entity info |
flow_action_corporate_crp_collector |
workflow.kyb.crp.ind.particular / workflow.kyb.crp.corp.particular / workflow.kyb.crp.submit | Submit directors, shareholders, UBOs |
flow_action_corporate_required_document |
workflow.kyb.corp.required.doc + .submit
|
Upload documents for main entity + CRPs |
flow_action_corporate_nonrequired_document |
workflow.kyb.corp.non.required.doc +
.submit
|
Optional documents (can skip) |
flow_action_corporate_required_forms |
workflow.kyb.corp.required.form + .submit
|
Submit forms for main entity + CRPs |
Corporate Particular
Endpoint:
workflow.kyb.particular.data
POST
{
"executionId": "exec-abc123def456",
"callbackKey": "kyb:corporate_particular:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001",
"corporateData": "{\"name\":\"Acme Corp Pte Ltd\",\"industry\":\"INFORMATION TECHNOLOGY\",\"entityType\":\"PRIVATE LIMITED COMPANY\",\"countryOfIncorporation\":\"SG\",\"countryOfOperations\":\"SG\",\"email\":\"corp@acme.com\"}"
}
corporateData is a JSON-encoded string,
same pattern as personData in KYC.
CRP Collector
After corporate particular, collect Connected Related Parties (directors, shareholders, UBOs).
CRP Metadata
The nextStep.metadata specifies required roles:
{
"totalRequiredRoles": 2,
"requiredRoles": [
{ "roleId": "DIRECTOR", "allowIndividual": true, "allowCorporate": false },
{ "roleId": "SHAREHOLDER", "allowIndividual": true, "allowCorporate": true }
]
}
| Field | Description |
|---|---|
requiredRoles |
Roles that must be filled |
allowIndividual |
Can this role be a person? |
allowCorporate |
Can this role be a company? |
Submit Individual CRP
Endpoint:
workflow.kyb.crp.ind.particular
POST
{
"executionId": "exec-abc123def456",
"callbackKey": "kyb:crp_collector:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001",
"personData": "{\"name\":\"Jane Director\",\"nationality\":\"SG\",\"date_of_birth\":\"1985-03-20\",\"sex\":\"FEMALE\",\"roles\":[{\"roleId\":\"DIRECTOR\",\"roleName\":\"Director\"}]}"
}
Store the returned crpPid — needed for liveness,
documents, and forms for this CRP.
Submit Individual CRP Liveness
Endpoint:
workflow.kyb.crp.ind.liveness
POST
Same pattern as KYC liveness, with an additional
crpPid field:
{
"provider": "SELF",
"status": "PASS",
"scores": "{\"qualityScore\":1.0,\"brightnessScore\":100,\"brightnessStatus\":\"normal\"}",
"images": "{\"faceFull\":\"s3://workflow-kyc/.../jane_photo.jpg\"}",
"executionId": "exec-abc123def456",
"callbackKey": "kyb:crp_collector:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001",
"crpPid": "acc45a86-f2e9-48c2-8fcd-2bf6563357a1"
}
Submit Corporate CRP
Endpoint:
workflow.kyb.crp.corp.particular
POST
{
"executionId": "exec-abc123def456",
"callbackKey": "kyb:crp_collector:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001",
"corporateData": "{\"name\":\"CRP Holdings Pte Ltd\",\"entityType\":\"ASSOCIATION\",\"countryOfIncorporation\":\"SG\",\"roles\":[{\"roleId\":\"SHAREHOLDER\",\"roleName\":\"Shareholder\"}]}"
}
Finalize CRP Submission
Endpoint:
workflow.kyb.crp.submit
POST
{
"executionId": "exec-abc123def456",
"callbackKey": "kyb:crp_collector:exec-abc123def456:..."
}
crp.submit to advance the
workflow. Submitting individual CRPs alone does not trigger the
transition.
KYB Required Documents
Endpoint:
workflow.kyb.corp.required.doc
POST
Upload documents for the main entity (crpPid: "") and each
CRP (crpPid: "acc45..."). Same doc field
schema as KYC. Submit via
workflow.kyb.corp.required.doc.submit.
Main entity document:
{
"doc": "{\"front\":{\"url\":\"s3://workflow-kyc/.../cert.png\",\"filename\":\"cert.png\",\"content_type\":\"image/png\",\"size\":85618}}",
"isRequired": true,
"docType": "CERTIFICATE_OF_INCORPORATION",
"extraData": "{\"issueDate\":\"2001-05-10\",\"expiryDate\":\"2030-10-10\"}",
"crpPid": "",
"executionId": "exec-abc123def456",
"callbackKey": "kyb:corporate_document:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
CRP individual document (double-sided):
{
"doc": "{\"front\":{\"url\":\"s3://...front.png\",\"filename\":\"front.png\",\"content_type\":\"image/png\",\"size\":849092},\"back\":{\"url\":\"s3://...back.png\",\"filename\":\"back.png\",\"content_type\":\"image/png\",\"size\":950146}}",
"isRequired": true,
"docType": "NATIONAL_ID",
"extraData": "{\"documentNumber\":\"12034\"}",
"crpPid": "acc45a86-f2e9-48c2-8fcd-2bf6563357a1",
"executionId": "exec-abc123def456",
"callbackKey": "kyb:corporate_document:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
KYB Non-Required Documents
Same schema as required documents. Use
workflow.kyb.corp.non.required.doc to upload. Call
workflow.kyb.corp.non.required.doc.submit to advance (even
if skipping).
KYB Required Forms
Endpoint:
workflow.kyb.corp.required.form
POST
| Metadata Key | Who Fills It |
|---|---|
mainForm |
Main corporate entity |
crpIndividualForm |
Each individual CRP |
crpCorporateForm |
Each corporate CRP |
crpBothForm |
Each shareholder CRP |
Main entity form:
{
"formId": "CorporateForm",
"formData": "{\"field_firm_size_level\":\"small_5_19\",\"field_has_branch\":\"no\"}",
"crpPid": "",
"executionId": "exec-abc123def456",
"callbackKey": "kyb:corporate_form:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
CRP individual form:
{
"formId": "IndividualCRPForm",
"formData": "{\"field_0_0\":\"test\",\"field_0_1\":\"Singapore\"}",
"crpPid": "acc45a86-f2e9-48c2-8fcd-2bf6563357a1",
"executionId": "exec-abc123def456",
"callbackKey": "kyb:corporate_form:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
Submit all forms (main + each CRP), then call
workflow.kyb.corp.required.form.submit.
Follow the nextStep metadata returned by the workflow when deciding which related-party roles, liveness checks, documents and forms are required. Preserve crpPid for every related party and use an empty crpPid only for the main entity examples shown above.