Skip to main content

KYB steps and configuration

A KYB flow is an anchor step that collects business information, plus optional satellite steps that collect documents, beneficial owners, and directors. All of them write into one KYB case, so the reviewer sees a single case.

This page is the reference for the step types, what each one configures, and the endpoints the applicant's session posts to. For the dashboard walkthrough, see the KYB overview; for the review workflow, see Reviewing KYB cases.

Changes in this release
  • Per-document flags are gone from the step configuration. certificateOfIncorporation, articlesOfAssociation, organizationalStructureChart, proofOfAttorney, and customDocuments are still accepted when you save a flow, and are folded into customCountryDocuments["**"], but they are never returned. Configure documents through customCountryDocuments, described below.
  • The anchor gains orchestrator, plannerMode, and agentResearch.
  • The flow no longer has a webhookUrl. Destinations are organization-level webhook endpoints.
  • discoveryEnabled and discoveryBudgetCredits live on the anchor KYB step, not on KYB_UBOS.

The anchor and its satellites​

Step typeDashboard nameRoleRequires
KYBKnow Your BusinessAnchor. Collects the business information and owns the case. Also where ownership discovery is enabled.Nothing
KYB_DOCUMENTSBusiness Document CollectionCompany document uploads.A KYB step earlier in the flow
KYB_UBOSUBO CollectionBeneficial-owner declaration.A KYB step earlier in the flow
KYB_DIRECTORSDirector CollectionDirector declaration.A KYB step earlier in the flow

Each satellite carries a kybStepId pointing back at its anchor, the same way a Liveness step points at its Document Verification step. Two rules are enforced when you save a flow:

  • A flow has at most one KYB anchor.
  • A satellite's kybStepId must resolve to a KYB step ordered before it.

A satellite without a resolvable anchor is not a valid flow.

Splitting the step buys three things:

  • The applicant can be routed part by part. Documents can be collected before owners, or a part can be skipped entirely for a particular flow.
  • UBOs and directors can use different KYC flows. Each satellite carries its own kycFlowId, so directors can be invited into a lighter flow than beneficial owners.
  • Owners or directors can be collected without KYC at all. See requireKyc below.

A KYB step with no satellites​

An anchor with no satellite steps collects the business information only: the applicant supplies it and the case goes on to its checks. A part is collected only when its satellite is in the flow, so to collect documents, owners, or directors, add the matching step.

Flows created before the split, whose single KYB step still declares documents or directors, are legacy monolithic steps. They keep working through the legacy submission endpoint, and the per-part endpoints reject them with a message naming the endpoint to use instead.

Configuration​

KYB (anchor)​

FieldTypeDefaultMeaning
agenticModeenumDISABLEDKYB agent mode: DISABLED, SUGGEST, AUTO_PILOT. See KYB Agent Mode.
amlAgenticModeenumDISABLEDAML agent mode for the screening matches this case raises.
orchestratorenumLINEARThe Case planner: LINEAR (Fixed order), JDM (Organization's rules, see KYB orchestration rules), or LLM (AI proposals). Fixed for each case when it opens.
plannerModeenumSUGGESTFor LLM: DISABLED, SUGGEST (a reviewer accepts each proposal), or AUTO_PILOT (proposals apply on their own, except ones that need a choice). See Proposed changes.
agentResearchobjectoff{ enabled, spendLimit, maxSearches }: lets the KYB agent consult extra sources during its review, within a credit limit and a number of web searches per review. Values above the platform ceiling are refused when you save the flow.
discoveryEnabledbooleanfalseStart ownership discovery when business information is submitted.
discoveryBudgetCreditsintegernonePer-verification cap on discovery spend, in credits. Omit for the platform default. Only read when discoveryEnabled is on.
allowIndividualSubjectbooleanfalseOffer the applicant a business-or-individual choice at the start of the step.
tinCheckEnabledbooleanfalseAsk a business registered in the US for its EIN and match it with the company name on IRS records on submission. See Checking a US business's EIN.
labelsobject{}Per-locale button labels.

An anchor on a legacy monolithic flow also carries kycFlowId, maxUbos, maxDirectors, maxFileUploads, collectDirectors, autoSendUboKycEmail, and the document configuration described below. On a split flow those live on the satellites instead.

KYB_DOCUMENTS​

FieldTypeDefaultMeaning
kybStepIdUUIDnoneThe anchor this satellite belongs to. Required.
maxFileUploadsinteger10How many additional documents the applicant may attach, on top of the upfront ones.
customCountryDocumentsobject{}Your changes to the document catalog, keyed by ISO 3166-1 alpha-2 country code, or "**" for every country.
labelsobject{}Per-locale button labels.

Zyphe keeps a document catalog per country, plus a general list used for countries without their own entry. Each entry in customCountryDocuments overrides or adds a document:

FieldMeaning
keyThe document's catalog key, or your own key for a custom document.
labelThe name shown to the applicant and the reviewer.
requiredWhether the applicant must upload it before submitting.
onDemandNot asked upfront. A reviewer, or your backend through the SDK, requests it later from the case.
enabledTurn a catalog document off for your flows.

A country with its own list uses only that list. Catalog documents that share a group are alternatives: any one of them satisfies the group. The effective list served to the client, documentsPerCountry, is computed from the catalog and your changes, which win per country; it is read-only.

KYB_UBOS​

FieldTypeDefaultMeaning
kybStepIdUUIDnoneThe anchor this satellite belongs to. Required.
maxUbosinteger10Maximum number of beneficial owners the applicant may declare.
requireKycbooleantrueWhether each declared owner must complete a KYC flow. See below.
kycFlowIdUUIDnoneThe flow owners are invited into. Only meaningful when requireKyc is on; may be omitted otherwise.
autoSendUboKycEmailbooleantrueSend the KYC invitation automatically on submission. When off, a reviewer sends the first invitation from the case page.
labelsobject{}Per-locale button labels.

KYB_DIRECTORS​

FieldTypeDefaultMeaning
kybStepIdUUIDnoneThe anchor this satellite belongs to. Required.
maxDirectorsinteger10Maximum number of directors the applicant may declare.
requireKycbooleantrueWhether each declared director must complete a KYC flow.
kycFlowIdUUIDnoneThe flow directors are invited into. Independent of the UBO satellite's, so directors can use a different KYC flow.
labelsobject{}Per-locale button labels.

The existence of the KYB_DIRECTORS step is what makes a flow collect directors. The anchor's collectDirectors boolean is the legacy monolithic equivalent.

Collecting people without KYC​

requireKyc is on the UBO and director satellites, and defaults to true, which is what every flow built before it existed does.

requireKyc: true. The widget demands an email address for each person, because an email is what a KYC invitation is addressed to. Zyphe sends and schedules those invitations against kycFlowId, and the person must complete that flow before the case is ready for review.

requireKyc: false. The widget collects the person by name alone and asks for no email. kycFlowId becomes meaningless and can be omitted. The person is still screened for PEP and sanctions by name; there is simply no identity verification behind the name.

The two satellites are independent: you can require KYC of beneficial owners while screening directors by name only, or the reverse.

Two rules follow from it:

  • Saving a step with requireKyc: true and no kycFlowId is rejected at validation time. Set one, or turn requireKyc off.
  • With requireKyc: true, a final submission whose declared people carry no email is rejected. This also applies to the legacy monolithic endpoint, so a widget that used to send name-only owners against a KYC-requiring step must now send emails, or the step must set requireKyc: false.
Readiness keys off the person, not the config

Whether a person is covered is decided per person, from whether that person has an email on file: a person with an email needs a completed KYC, a name-only person needs a clean name screening. Changing requireKyc therefore does not retroactively re-gate people already declared, and owners found by ownership discovery, who arrive without an email, are always screened by name. Name-only screening is a fallback: unless your compliance policy admits it, approving such a case needs a recorded exception.

Which population must be screened​

A KYB case records a screening strategy: which population of natural persons must be identified and screened before it can be approved.

ValueMeaning
uboBeneficial owners. The default, and correct for the overwhelming majority of private companies.
directorsDirectors instead of owners. For a business where no natural person crosses the ownership threshold (a listed or widely-held company, a state-owned body), control rather than ownership is the screenable population.
uboAndDirectorsBoth.

The strategy selects which population is required, never whether one is: every value demands at least one screened natural person, so no sequence of changes produces a case that is approvable with nobody identified. A person who holds both roles is screened once.

Screening is complete when every required subject has a current screening and every match is resolved. Until then the case is not ready for review, whoever wants to decide it, and the KYB agent escalates rather than approves a case whose screening coverage is incomplete.

Agents change the strategy through the set_kyb_screening_strategy MCP tool, which accepts only a strategy the people already on file satisfy, requires a reason, and writes a KYB_SCREENING_STRATEGY_CHANGED entry to the audit trail carrying the previous and new strategy, the reason, and the UBO and director counts at that moment. Ask Zyphe support to set it for a flow if you are not driving KYB through an agent.

Alongside it, the case records a due-diligence level: simplified, standard (the default), or enhanced. enhanced adds a financial-documents requirement; otherwise the checks are the same at every level. The level can be changed on the case page, and an approver can record it on the decision (dueDiligenceLevel, also available through decideKybCase). simplified is never a fallback: it is a positive finding about the subject, so an unclassified case is standard, not reduced-checks.

Submitting each part​

The applicant's session posts one part at a time. All four endpoints are verification-request scoped and authenticated with the session token the hosted widget already holds; they are not part of the API-key /sdk surface. Add ?sandbox=true to target the sandbox.

MethodPathBodyStep the VR must be on
POST/flow/{flow_id}/vr/{verification_request_id}/kyb/submit-business-infobusinessInformation, submitKYB
POST/flow/{flow_id}/vr/{verification_request_id}/kyb/submit-documentsdocumentUploads, submitKYB_DOCUMENTS
POST/flow/{flow_id}/vr/{verification_request_id}/kyb/submit-ubosuboDefinitions, submitKYB_UBOS
POST/flow/{flow_id}/vr/{verification_request_id}/kyb/submit-directorsdirectorDefinitions, submitKYB_DIRECTORS

Each returns 202 with verificationRequestId and kybResultId (the case ID). submit-documents additionally returns documentUploads carrying presigned PUT URLs: upload the files to those URLs immediately after the response returns.

The case stays OPEN until every part present in the flow has been submitted; only then does it move to PROCESSING. Reading any satellite's verification request returns the shared result, so a client does not have to hold the anchor's ID to show progress.

The two-phase submit flag​

Each payload carries a submit boolean, defaulting to true:

  • submit: false saves progress. The part stays open and the applicant can come back to it.
  • submit: true marks the part submitted. Once every part of the flow is submitted, the case moves to PROCESSING and its checks start.

Use submit: false for autosave and multi-screen parts; send submit: true on the last screen of the part.

A final submit runs the part's real validation, which a draft save skips:

PartWhat a final submit enforces
Business infoCompany screening is queued; the document part is reopened if resolving the company's country made more documents required; ownership discovery is started when enabled.
DocumentsEvery required document for the resolved country must be present. documentUploads: null on a final submit means "finalize what was already saved"; it never clears them.
UBOs, directorsCaps from maxUbos / maxDirectors. When requireKyc is on, every declared person must carry an email address, otherwise the call is rejected. Any outstanding declaration request for that part is fulfilled.
Non-registered businesses

businessInformation on submit-business-info is nullable. Send null for a business that is not registered: the sole-proprietor path that collects a single owner directly.

The legacy monolithic endpoint​

POST /flow/{flow_id}/vr/{verification_request_id}/kyb/process-kyb-document is unchanged and remains the submission path for a monolithic KYB step. It enforces the same validation and upload caps as the split endpoints. Posting a per-part submission to a monolithic flow returns a 400 naming this endpoint.

Checking a US business's EIN​

With tinCheckEnabled on the anchor, a business registered in the US is asked for its EIN (Employer Identification Number), and its business information is accepted only once the EIN and the company name match IRS records. The match is a TIN check, and needs the TIN Check product. Businesses outside the US, and non-registered businesses, are not asked.

The widget sends the EIN as ein, next to businessInformation, on submit-business-info (and on the legacy process-kyb-document). It is not part of the business information and is never stored: the check keeps its last four digits only. The hyphen applicants type (12-3456789) is accepted.

A final submission (submit: true) is refused with 422 when the EIN does not let it through. The answers are kept as a draft, so the applicant corrects the EIN or the company name and submits again:

Error tagCodeWhen
tin_check_ein_required12809No EIN was sent.
tin_check_mismatch12810The EIN and the company name do not match IRS records, or the IRS has not issued it.
tin_check_attempts_exhausted12811Three checks of this submission did not match. No further check is run.

An unavailable lookup answers 503 with tin_check_unavailable. Once a check has matched, a retried submission with the same company name reuses it and needs no EIN.

Each check that returns an answer is charged to your organization as a TIN check, match or not. In sandbox, checks are free and answered from sample data: 12-3456789 (any EIN outside the 000000 prefix) matches, and 00-0000000 does not.

The checks appear on the KYB result page in the dashboard, and with your organization's other checks under Compliance → TIN Check. Over the API, list a KYB result's checks with GET /sdk/organizations/{organization_id}/tin-checks?flowResultId=….

Prefilling from official registers​

Two applicant-facing endpoints let the widget prefill the business-information form from official business registers before the applicant confirms it:

MethodPathPurpose
GET.../kyb/company-search?country=&query=Search by company name or registration number. Returns candidates.
POST.../kyb/company-prefillFetch a chosen candidate's details as prefill values.
GET.../kyb/director-candidatesRe-read any director suggestions from the persisted snapshot.

company-search returns available: false with an empty candidate list when no source serves that country. That is not an error: the widget hides the search box. The covered jurisdictions are listed in Country coverage. company-prefill returns authoritative: false when the values came from a non-authoritative search hit; the authoritative record is fetched after submission and the cross-check compares the applicant's submission against it.

Director candidates are commonly empty, since officer data is not always available for a country. Treat an empty list as normal and collect directors from the applicant.

These endpoints are rate limited per verification request: 30 searches and 10 prefills per minute.

Step outputs in Flow Builder​

Each satellite writes its own step output, which Flow Builder conditions can branch on:

StepOutput fields
KYBstatus, moderationStatus, pepAndSanctionsStatus, businessName, registrationNumber, country, amlPep, amlSanctions, amlRiskScorePercent
KYB_DOCUMENTSuploadedCount, requiredSatisfied
KYB_UBOSuboCount, allUbosVerified
KYB_DIRECTORSdirectorCount, allDirectorsVerified