Description
Overview
The KYB (Know Your Business) module provides functionality for managing business verification flows, including:
- Dynamic questionnaire flows
- Answer management
- Section-based verification process
- Status tracking
- Customizable validation rules
- Multi-step verification workflows
- Custom function support for dynamic content generation
- Restricted country validation
- Shareholder and signatory management
- Advanced condition evaluation with case-insensitive operators
Flow Start Step Behavior
- Each flow has a configured start step (
start_step) in KYB flow configuration. - When a client starts navigation without explicitly passing
question_name, backend flow navigation starts from that configuredstart_step. - In editor workflows, changing the start node in UI updates local draft state first and is only persisted after an explicit save action.
DATA_DIR flow seeds (bootstrap)
On API startup, YAML files under $DATA_DIR/kyb/*.yaml are imported into kyb.flows_config / kyb.items (same format as Configurator flow import). There is no incremental *.diff.yaml — one file = one full flow.
| Topic | Document |
|---|---|
File layout, KYB_FORCE_SEED, checklist | seed_authoring.md |
| Environment variables (all seed types) | docs/data-dir-seeds-env.md |
| Module doc index | README.md |
| Sample | .samples/data/kyb/kyb_corebanq.yaml |
Loader: common/kybseed. HTTP equivalent: PUT /v1/kyb/config/{flow_name}.
Flow Step Configuration
Flow steps (questions) are defined in YAML flow files or in kyb.items rows (Configurator / import API). Each step can control navigation UI, warnings, and form behavior.
Back navigation (back)
Controls whether the web client shows a Back button on the current step. The backend exposes this on the navigate/submit response as flow.back (boolean). The client hides the Back control when flow.back is false.
| Property | Type | Default | Description |
|---|---|---|---|
back | boolean | true | On the step root: disable Back when false. |
options.back | boolean | true (when options is present) | Same effect when set under options. |
The server reads back from the step root first, then falls back to options.back. If neither is set, navigate defaults to flow.back: true.
Important: message (warning/info text) is display-only. It does not disable Back. To hide Back, set back: false or options.back: false.
For steps stored in kyb.items (DB / import), prefer options.back — the DB loader maps the options JSON column into the runtime question; step-level back at the root is used in YAML files and is not a separate DB column.
Example — confirm step with warning and no Back:
- name: confirm_company_details
back: false
q:
en: Confirm details
de: Details bestätigen
message:
severity: warning
text:
en: There is no way back after you continue, check your input carefully
de: Es gibt keinen Weg zurück nachdem Sie fortfahren, überprüfen Sie Ihre Eingaben
section:
name: company_profile
status: PENDING
schema:
type: object
properties:
ZefixName:
type: string
readOnly: true
# afterSubmit, next, formData, ...Equivalent using options (typical for DB-backed flows):
- name: confirm_company_address
q:
en: Confirm address
options:
back: false
section:
name: company_profile
status: PENDINGNavigate response (excerpt):
{
"flow": {
"current_step": "confirm_company_details",
"back": false
},
"question": {
"name": "confirm_company_details",
"q": "Confirm details",
"message": {
"severity": "warning",
"text": "There is no way back after you continue, check your input carefully"
}
}
}Step options
| Property | Type | Default | Description |
|---|---|---|---|
options.back | boolean | true | See Back navigation. |
options.saveFormData | boolean | true | When false, submitted answers for this step are not persisted to kyb.answers. |
options.show_in_progress_rail | boolean | true (when omitted) | When false, the step is omitted from flow.progress_catalog left-rail milestones (see Progress catalog). |
options.presentation | string | — | Client screen to render instead of the default RJSF form. See Client presentation. |
options.wizard_step | string | — | Initial sub-step when presentation is signatories_wizard. See Client presentation. |
Store these keys under options in flow YAML or in the kyb.items.options JSON column (Configurator / import). They are configuration metadata for integrators and web clients; the server uses show_in_progress_rail when building progress_catalog. Other presentation keys are passed through in flow config and are intended for client routing (and future flow.ui on navigate responses).
Client presentation (options.presentation)
Use options.presentation (and optional options.wizard_step) on a flow item when the web client must render a dedicated screen instead of a JSON Schema form — for example the authorized persons / signatory invite flow (invite list, select signatories by signing rights, enter invitation emails).
This is the DB-driven equivalent of hard-coding section names in the client: configure the item in Configurator or YAML, import to kyb.items, and point next at that step when the user should enter that experience.
presentation values
| Value | Client behavior |
|---|---|
| (omitted) | Default: RJSF form when the step has a renderable schema; otherwise section overview (empty schema / SECTION_LIST). |
signatories_wizard | Multi-step signatory onboarding UI (not RJSF): document preview, invite/add signatories, select who must sign (single vs joint via signatory signature_type and weight rules), collect emails, optional email update. Data comes from signatory and upload APIs, not from kyb.answers for list steps. |
Other presentation values (application_submitted, leave_kyb, and computed flow.ui on navigate) may be added later; prefer customers.status (REVIEW, ACTIVE) for post-submit “application under review” and dashboard routing where that already applies.
wizard_step (with presentation: signatories_wizard)
wizard_step | Typical screen |
|---|---|
invite | Invite / list signatories, document signing preview (default when omitted). |
select_authorised | Select signatories who must sign; show single vs joint signing from each row’s signature_type. |
enter_emails | One email field per selected signatory; submit via POST .../signatories/invite. |
update_email | Update a single signatory’s invitation email. |
Clients may advance sub-steps locally after the first navigate (same pattern as web-app kybAuthorisedPersonsStore); wizard_step sets the entry screen when landing on the step.
Example — signatory email collection step
Use a dedicated item (not an empty-schema milestone such as section3_complete). Chain it with next after section unlock milestones if needed.
- name: signatory_invite_emails
q:
en: Authorized persons
de: Zeichnungsberechtigte
section:
name: authorized_persons
status: PENDING
options:
saveFormData: false
show_in_progress_rail: true
presentation: signatories_wizard
wizard_step: enter_emails
customFunction:
name: CustomSignatoryList
params:
buttons: []
next: SECTION_LIST| Field | Role |
|---|---|
saveFormData: false | Signatory list / emails are not stored as a kyb.answers row; visit-only for progress rail when applicable. |
show_in_progress_rail: true | Show this step as a milestone under authorized_persons in progress_catalog. |
presentation | Switch client from RJSF to the signatories wizard shell. |
wizard_step: enter_emails | Open directly on the email-entry screen (skip invite/select if the product allows). |
customFunction: CustomSignatoryList | Optional; aligns with list-based signatory steps in existing flows. Often combined with invite / select_authorised steps using the same presentation and different wizard_step values. |
Do not use an empty schema alone to request this UI — empty schema means section overview, not signatory emails. Milestone nodes such as section3_complete should keep update blocks to unlock sections and use next to reach a presentation-configured item when the signatory flow should start.
Navigate / submit (client contract)
Integrators should read options.presentation and options.wizard_step from the active step config (today: flow item loaded from DB; planned: echoed on question or flow.ui in navigate responses). Example target shape:
{
"flow": {
"current_step": "signatory_invite_emails",
"progress_catalog": { "sections": [], "visit_only": ["signatory_invite_emails"] }
},
"question": {
"name": "signatory_invite_emails",
"q": "Authorized persons",
"section": { "name": "authorized_persons", "status": "PENDING" },
"options": {
"saveFormData": false,
"show_in_progress_rail": true,
"presentation": "signatories_wizard",
"wizard_step": "enter_emails"
}
}
}Progress catalog
Navigate and submit responses include flow.progress_catalog: ordered left-rail milestones per section, rail_parent for button-only sub-flows, and visit_only for steps with options.saveFormData: false.
Steps are ordered by kyb.items.sort_order. A step is hidden from the rail when:
options.show_in_progress_railisfalse, ortypeis notquestion(e.g.info,section_list), or- the step is a button sub-flow child listed in
rail_parent.
Step message
Optional banner shown above the Continue button (client renders by severity: info, warning, error).
message:
severity: warning
text:
en: There is no way back after you continue, check your input carefully
de: Es gibt keinen Weg zurück nachdem Sie fortfahren, überprüfen Sie Ihre EingabenLocalized text follows the same locale-key pattern as q (en, de, fr, it, …).
Flow YAML reference (kyb_audax_CAP_CY.yaml)
Field catalog extracted from .runtime/data/kyb/kyb_audax_CAP_CY.yaml (Audax CAP/CY variant). Other brand flows reuse the same shape; step names and form fields differ per product.
| Document metric | Value |
|---|---|
| Flow name | kyb_flow |
| Version | 2.1.2800 |
| Start step | page404 |
| Questions (steps) | 299 |
Flow-level Sections | 5 |
| Named steps in catalog | 292 |
Top-level keys
| Key | Type | Purpose |
|---|---|---|
flow | object | Flow identity, version, start step, last-modified timestamp |
Sections | array | Sidebar sections (icon, title, initial status) |
Questions | array | All steps / nodes in the flow |
metadata | object | Editor layout (positions map: step name → { x, y }) |
flow object
| Field | Type | Observed values | Description |
|---|---|---|---|
name | string | kyb_flow | Flow name passed to navigate/submit APIs |
start | string | page404 | First step when navigation omits question_name |
version | string | 2.1.2800 | Flow config version (string, not semver-enforced) |
modified | string (RFC3339) | e.g. 2026-05-01T08:20:49.449Z | Last export/edit time from the configurator |
Sections entries (flow sidebar)
Each entry defines a section shown in the KYB progress UI.
| Field | Type | Observed values | Description |
|---|---|---|---|
name | string | company_profile, nature_of_business, shareholders, authorized_persons, review_documents | Section id (also used in step section.name) |
title | locale map | en, de, fr, it | Localized section label |
icon | string | business, work_outline, group, person_outline, description | Material icon id for the sidebar |
status | string | PENDING, NOT_STARTED | Initial section status in this file |
show | boolean | true, false | Whether the section appears in the sidebar (review_documents uses false) |
Additional section names appear only on steps (account_setup, founders, shareholders_ubo) via section.name / update, not in the top-level Sections list.
metadata.positions
Map of step name → { x, y } (floats). Used by the flow editor (React Flow); ignored at runtime by navigate/submit.
Question (step) — root fields
Keys observed on Questions[] items in this file (camelCase where noted).
| Field | Type | Used in CAP_CY | Description |
|---|---|---|---|
name | string | required | Unique step id; referenced in next, templates {{step.field}} |
q | locale map | required | Step title (en, de, fr, it; occasional uk) |
description | locale map | optional | Subtitle under the title |
section | object | usual | Active sidebar section + status for this step |
schema | JSON Schema–like object | usual | Form fields (properties, required, type, …) |
uiSchema | object | usual | RJSF widgets, order, rules (ui:widget, ui:order, …) |
formData | object | usual | Default/prefill values; may contain {{template}} expressions |
next | string or array | usual | Unconditional next step or conditional rules |
afterSubmit | object | frequent | Post-continue HTTP actions (actions[]) |
beforeSubmit | object | 40 steps | Pre-submit HTTP actions (same action shape) |
update | object | occasional | Patch other sections’ status / show on enter |
message | object | occasional | Banner (severity + localized text) |
options | object | occasional | back, saveFormData, show_in_progress_rail, presentation, wizard_step |
back | boolean | rare | Same as options.back (prefer options for DB import) |
customFunction | object | frequent | Server-driven UI (name + params) |
customAPI | — | not in CAP_CY | Supported by runtime; unused in this file |
Legacy / invalid keys also appear in exports and should be avoided: decription, root-level de/en/fr/it, formdata (typo for formData).
section (on a step)
| Field | Type | Observed values |
|---|---|---|
name | string | company_profile, nature_of_business, shareholders, shareholders_ubo, authorized_persons, account_setup, founders, review_documents |
status | string | PENDING, COMPLETE |
show | boolean | true (optional) |
title | locale map | rare override |
options
| Field | Type | Observed in CAP_CY |
|---|---|---|
back | boolean | false only (when set) |
saveFormData | boolean | false (when set) |
show_in_progress_rail | boolean | false when step should not appear in progress_catalog |
presentation | string | signatories_wizard (authorized-persons flows; product-specific) |
wizard_step | string | invite, select_authorised, enter_emails, update_email |
message
| Field | Type | Observed values |
|---|---|---|
severity | string | info, warning, error, normal |
text | locale map | en, de, fr, it |
update
Patches section state when the user lands on the step. Keys are section names; values are partial section objects.
| Nested field | Observed values |
|---|---|
status | PENDING, COMPLETE |
show | true |
Section names used in update: company_profile, nature_of_business, shareholders, shareholders_ubo, authorized_persons, account_setup, founders, review_documents.
next
| Shape | Description |
|---|---|
| string | Single unconditional next step name |
| array of rules | Each item: when (expression), then (step), optional else on last branch |
Rule keys: when, then, else.
Operators used in when (see Condition Evaluation): ==, !=, >, =, Form field names (schema.properties` keys) — 259 unique in CAP_CY
DrcorIncorporationDate, DrcorLegalForm, DrcorName, DrcorRegNumber, DrcorStatus, OperCity, OperCountry, OperHouseNumber, OperStreet, OperZip, OsQuery, RegCity, RegDistrict, RegHouseNumber, RegStreet, RegZip, TIC, TaxResidency, ZefixForm, ZefixName, ZefixSeat, ZefixUID, ZefixUIDFormatted, accountType, acknowledge, acknowledgeFormA, acknowledgeFormK, acknowledgeRisk, additional_documents, address, amlPolicy, amount, amountCurrency, annualRevenue, articles_of_association, articles_of_association_draft, assets, auditedFinancials, auditor, auditorAppointed, auditorName, authorizedRepresentative, bankReference, benefit, boIsContractingParty, branchRegistrationNumber, businessDescription, bylaws, canClaimDistribution, canRevoke, canton, capitalContribution, capitalCurrency, capitalPurpose, certificateOfDirectors, certificateOfGoodStanding, certificateOfIncorporation, certificateOfRegisteredOffice, certificateOfShareholders, city, companyName, confirm, confirmAML, confirmDataProcessing, confirmDataRetention10y, confirmFADP, confirmFormASigned, confirmNoSanctions, confirmTerms, confirmTruthful, confirmation, confirmed, contractors, contributionType, controlDocument, controlType, counterpartie1, counterpartie2, counterpartie3, countries, country, countryOfIncorporation, countryOfResidence, currency, customer1, customer2, customer3, customerCountries, customerTypes, cysecLicenseNumber, dateOf, dateOfBirth, declarationTruthful, defined_beneficiaries, depositary, details, doc_type, email, employeeCount, employees, entityCountry, entityLegalForm, entityName, entityType, entityUID, establishment_type, evidenceDocument, existing_signatories, fleetSize, foundationPurposes, foundation_discretionary, foundation_revocable, founderType, founderTypes, foundersReport, fundManager, fundType, goodsDescription, groupName, hasAppointmentRight, hasControllingPersons, hasIndirectShareholders, hasIntendedAcquisition, hasNotary, hasRevocationRight, hasRightToRevoke, hasVAT, houseNumber, idDocumentsDirectorsUBO, id_documents, if, inCountries, income_sources, incorporationCountry, industries, isCareOf, isCyprusResident, isFromHighRiskJurisdiction, isListed, isNaturalPerson, isOperational, isOperationalEntity, isPEP, isTTSRegistered, isTrustee, is_operational, is_third_person, legalForm, madeBy, members, memorandumArticles, monthlyIn, monthlyOut, municipality, name, nameConfirmed, nameSuffix, nationality, noControllingPerson, noCounterparties, noCriminalProceedings, noCustomers, noWebsite, nominalValuePerShare, nominate_representatives, not_operational_yet, notaryCanton, notaryName, notaryOffice, numberOfShares, operationalEntity, otherBeneficiaries, outCountries, outgoingPaymentsCounterparties, ownershipPercentage, ownership_structure, paidInAmount, parentCompanyName, parentCountry, parentRegistrationNumber, partnerType, partnershipName, partnershipType, partyName, partyType, passportNumber, paymentFrequencyReceive, paymentFrequencySend, paymentMethods, paymentsOut, phone, plannedName, position, postalAddress, power_of_attorney, productDescription, profitShare, proofOfAddress, proof_of_address, providers, purpose, qualification, receiveAmount, register_extracts, registeredOffice, registrationDate, registrationNumber, relationship, representative, requiresSecoLicense, returnTo, revenueRange, revenueSources, revokers_exist, riskCategory, role, salesChannels, sameAsRegistered, same_physical_address, sanctionsScreening, scenario, secretaryType, sendAmount, sendCountries, settlorType, shareType, share_register, shareholderType, shares, sharesSubscribed, shippingActivityType, signatureType, sourceCategory, sourceCountry, sourceDescription, sourceOfWealth, source_of_funds_evidence_pack, status, statutes, street, subtitle1, subtitle2, swissResidencePermit, taxCompliant, taxResidency, taxResidencyCertificate, thirdPartyOwner, totalAUM, totalShareCapital, trustDeedDate, trustName, trustType, type, types, uboDeclaration, uboRegisterExtract, uboType, websiteUrl, zipCode
uiSchema
| Key | Purpose |
|---|---|
ui:order | Array of property names — field display order |
ui:widget | Widget id (see table) |
ui:options | Widget options (see below) |
ui:required | Mark field required in UI |
ui:readonly, ui:hidden, ui:label, ui:title, ui:help, ui:placeholder | Presentation |
ui:enumNames | Labels for enum values |
ui:field | Custom field component |
ui:rules | Conditional show/hide/enable rules |
ui:widget values in CAP_CY:
ArrayField, CantonSelectSingle, CountrySelectMulti, CountrySelectMultiple, CountrySelectSingle, FileUpload, ItemSelectMultiple, OpenSanctionsSelectSingle, TextInputWithRecordExistenceCheck, YesNoSwitch, ZefixSelectSingle, checkboxes, date, email, file, hidden, phone, radio, select, text, textarea, updown
ui:options keys:
accept, condition, conditional, dataset, error_message, expandable, format, inline, inputLabel, label, max, min, placeholder, queryFilter, record_field, record_type, rows, schema, searchQuery, step, width
searchQuery.tag is used for country datasets (e.g. operating).
Template placeholders
String values may embed expressions resolved at runtime:
{{actorID}}
{{principalID}}
{{enter_company_name.ZefixUID}}
{{confirm_company_details.customer_id}}Used in formData, afterSubmit/beforeSubmit url/body, and conditional readOnly expressions in schema.
Locale keys
Observed on q, description, message.text, schema.properties.*.title, and button labels:
en, de, fr, it (primary); occasional uk, name, status on malformed exports — use the four primary locales only.
Condition Evaluation
The KYB module supports powerful condition evaluation for determining flow navigation. All text comparison operators are case-insensitive by default.
Available Operators
Equality Operators
==- Case-insensitive equality comparison!=- Case-insensitive inequality comparison
Text Pattern Operators
contains- Checks if text contains a substring (case-insensitive)starts_with- Checks if text starts with a prefix (case-insensitive)ends_with- Checks if text ends with a suffix (case-insensitive)
Regex Operator
=~- Regular expression pattern matching
Numeric Operators
>- Greater than=- Greater than or equal to- **` 1000000
then: high_value_processing
- when: employee_count >= 50 then: large_company_processing
- when: risk_score 500000 then: large_swiss_corporate
- when: address.country == "ch" or address.country == "de" then: european_processing
- when: risk_score > 7 or company.name contains "high risk" then: enhanced_monitoring
- else: standard_processing
#### Array Operations
```yaml
next:
- when: "switzerland" in selected_countries
then: swiss_compliance
- when: "high_risk" in risk_tags
then: enhanced_due_diligence
- else: standard_processingTag Operations
next:
# Check if any selected countries have high-risk tag
- when: send_countries.sendCountries has_country_tag "high-risk"
then: restricted_countries_warning
# Check if any customer countries have sanctions tag
- when: customer_countries.customerCountries has_country_tag "sanctions"
then: enhanced_compliance_check
- else: standard_processingAdvanced Regex Patterns
Address Validation
next:
# P.O. Box or Postfach detection
- when: address.line1 =~ "^(?i)(p\\.?o\\.?\\s+box|postfach)"
then: po_box_processing
# Street address validation
- when: address.line1 =~ "^(?i)[0-9]+\\s+[a-z]+\\s+(street|strasse|gasse)"
then: street_address_processing
- else: address_validation_requiredCompany Type Detection
next:
# Swiss company types
- when: company.name =~ "^(?i).*\\s+(ag|gmbh)\\s*$"
then: swiss_corporate
# International company types
- when: company.name =~ "^(?i).*\\s+(ltd|inc|corp|llc)\\s*$"
then: international_corporate
# German company types
- when: company.name =~ "^(?i).*\\s+(gmbh|ug|ohg)\\s*$"
then: german_corporate
- else: individual_or_otherContact Information Validation
next:
# Phone number validation
- when: contact.phone =~ "^(?i)(\\+?[0-9]{1,3}[\\s-]?)?[0-9]{3,4}[\\s-]?[0-9]{3,4}[\\s-]?[0-9]{3,4}$"
then: valid_phone
# Website URL validation
- when: website.url =~ "^(?i)(https?://)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([/\\w \\.-]*)*/?$"
then: valid_website
- else: invalid_contact_infoCondition Structure
Conditions can be structured in multiple ways:
Simple String Next Step
next: "next_question_name"Single Condition
next:
when: field_name == "value"
then: "next_question_name"Multiple Conditions with Else
next:
- when: condition1 == "value1"
then: "step1"
- when: condition2 == "value2"
then: "step2"
- else: "default_step"Complex Nested Conditions
next:
- when: company.type == "ag" and revenue.amount > 1000000
then: "large_swiss_corporate_processing"
- when: address.country == "ch" or address.country == "de"
then: "european_processing"
- when: risk_score > 7
then: "enhanced_monitoring"
- else: "standard_processing"Endpoints
Navigate Flow
POST /v1/kyb/navigate
Start or continue a KYB verification flow.
Request Body:
{
"flow_name": "business_verification",
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"question_name": "company_details"
}Success Response (201):
{
"flow": {
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_name": "business_verification",
"current_step": "company_details",
"previous_step": "",
"back": true,
"status": "PENDING",
"sections": [
{
"name": "company_information",
"title": "Company Information",
"icon": "building",
"status": "PENDING",
"show": true
}
]
},
"question": {
"name": "company_details",
"section": {
"name": "company_information",
"title": "Company Information",
"icon": "building",
"status": "PENDING",
"show": true
},
"q": "Please provide your company details",
"description": "Enter the basic information about your company",
"schema": {
"type": "object",
"properties": {
"company_name": {
"type": "string",
"title": "Company Name"
}
}
}
}
}Repin Actor Flow (Admin)
POST /v1/kyb/admin/flows/repin
Administratively repin an actor's kyb.flows row to a different flows_config snapshot and/or move the current_step. Used to recover actors stuck on inactive snapshots after a flow version rotation, or to forcibly move an actor to a specific step. Requires the Administrator role.
Request Body:
{
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_name": "kyb_flow",
"flow_id": "86e827ea-ddc9-4b44-9294-f9d660bc4d9d",
"current_step": "A_UBO_entities_list"
}flow_id and current_step are both optional, but at least one must be provided. When flow_id is supplied, the target snapshot must belong to the same flow_name. When current_step is supplied, an active item with that name must exist in the effective snapshot. Both checks run inside the same DB transaction as the update.
Success Response (200):
{
"id": "1d1f4ba4-2f5e-4f9e-9df8-8b3a3fa1234f",
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_name": "kyb_flow",
"flow_id": "86e827ea-ddc9-4b44-9294-f9d660bc4d9d",
"current_step": "A_UBO_entities_list",
"previous_step": "section3_complete"
}Errors: 400 invalid actor_id / flow_id / step or missing both targets · 403 non-admin · 404 no active flow row for actor + flow_name.
Submit Answer
POST /v1/kyb/submit-answer
Submit an answer for a KYB flow question.
Request Body:
{
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_name": "business_verification",
"question_name": "company_details",
"record_index": 0,
"answer": {
"company_name": "Example Corp GmbH",
"registration_number": "CHE-123.456.789"
},
"metadata": {
"source": "user_input",
"version": "1.0"
}
}Success Response (200):
{
"flow": {
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_name": "business_verification",
"current_step": "address_details",
"previous_step": "company_details",
"status": "PENDING"
},
"question": {
"name": "address_details",
"section": {
"name": "company_information",
"title": "Company Information",
"icon": "building"
},
"q": "Please provide your company address"
}
}Get All KYB Answers
GET /v1/kyb/customer/{customer_id}
Retrieve all KYB answers for a specific customer.
Path Parameters:
- customer_id: Customer UUID
Success Response (200):
[
{
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_name": "business_verification",
"question_name": "company_details",
"previous_step": "",
"answer": {
"company_name": "Example Corp GmbH",
"registration_number": "CHE-123.456.789"
},
"created_at": "2024-03-21T10:00:00Z"
}
]Get KYB Answer
GET /v1/kyb/{kyb_id}
Retrieve a specific KYB answer.
Path Parameters:
- kyb_id: KYB answer UUID
Success Response (200):
{
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_name": "business_verification",
"question_name": "company_details",
"previous_step": "",
"answer": {
"company_name": "Example Corp GmbH",
"registration_number": "CHE-123.456.789"
},
"created_at": "2024-03-21T10:00:00Z"
}Update KYB Answer
PUT /v1/kyb/{kyb_id}
Update a specific KYB answer.
Path Parameters:
- kyb_id: KYB answer UUID
Request Body:
{
"answer": {
"company_name": "Updated Corp GmbH",
"registration_number": "CHE-123.456.789"
}
}Success Response (200):
{
"message": "Answer updated successfully"
}Delete KYB Answer
DELETE /v1/kyb/{kyb_id}
Delete a specific KYB answer.
Path Parameters:
- kyb_id: KYB answer UUID
Success Response (200):
{
"message": "Answer deleted successfully"
}Custom Functions
The KYB module supports custom functions that can be used in question configurations to generate dynamic content, validate data, and provide enhanced user experiences.
Available Custom Functions
CheckRestrictedCountries
Validates selected countries against a restricted/high-risk list and returns a disabled CountrySelectMultiple widget with restricted countries.
Usage in YAML:
customFunction:
name: "CheckRestrictedCountries"
params:
question_name: "selected_countries"Response:
- Returns a CountrySelectMultiple widget with restricted countries marked as disabled
- Automatically filters countries tagged as "high-risk"
- Provides both country codes and names for restricted countries
GetCustomList
Generates dynamic lists of shareholders with progress tracking and management capabilities.
Usage in YAML:
customFunction:
name: "GetCustomList"
params:
group: "shareholders"
buttons:
- name: "add_shareholder"
label:
en: "Add Shareholder"
icon: "plus"
next: "add_shareholder_form"Features:
- Displays shareholder information with stake percentages
- Shows progress bar with total shares held
- Provides delete buttons for individual shareholders
- Supports custom action buttons
- Tracks total shares and remaining shares
CustomSignatoryList
Generates dynamic lists of signatories with management capabilities.
Usage in YAML:
customFunction:
name: "CustomSignatoryList"
params:
buttons:
- name: "add_signatory"
label:
en: "Add Signatory"
icon: "user-plus"
next: "add_signatory_form"Features:
- Displays signatory information with signature types
- Provides delete buttons for individual signatories
- Supports custom action buttons
- Shows secondary text with signature type descriptions
Custom Function Configuration
Custom functions can be configured in question YAML files with the following structure:
name: "example_question"
q: "Please select countries"
customFunction:
name: "CheckRestrictedCountries"
params:
question_name: "selected_countries"
schema:
type: "object"
properties:
selected_countries:
type: "array"
items:
type: "string"
uiSchema:
selected_countries:
ui:widget: "CountrySelectMultiple"Widget Types
CountrySelectMultiple
A specialized widget for country selection that supports:
- Multiple country selection
- Disabled state for restricted countries
- Automatic filtering of high-risk countries
- Visual indicators for restricted countries
Shareholder Widget
A custom widget for displaying shareholder information:
- Shows shareholder name and stake percentage
- Displays chip with stake information
- Includes delete functionality
- Supports secondary text for additional information
Button Widget
A customizable button widget that supports:
- Custom labels with internationalization
- Icon support
- Color customization
- Action handling
Error Responses
All endpoints may return the following errors:
- 400: Invalid input data
- 401: Unauthorized
- 403: Insufficient permissions
- 404: Resource not found
- 500: Internal server error