Onboarding case ( onboarding_case )

A onboarding_case represents a business onboarding case. It drives an orchestration process that collects data, runs compliance checks, and reaches an approval or rejection decision. It also provides a URL to a User Journey completed by the subject.

Role

The onboarding case is the central object of KYC and KYB flows. It carries two distinct dimensions: the case lifecycle of the case — is it still active? — and the final decision . This separation distinguishes a case closed with rejection from a case canceled before any decision.

At creation, an orchestration process starts automatically. This process is responsible for collecting supporting documents, calling identity-verification providers, and concluding by attaching company and contact objects created during the process.

Identifier and structure

Every case has a stable identifier prefixed with obc_. The The url field contains the User Journey URL returned directly in the creation response — no additional call is required to retrieve the link to send to the subject.

JSON
"onboarding_case":{22 items
"object":"onboarding_case"
"id":"obc_3f8a1d9c2b4e7f6a"
"subject_type":"company"
"status":"open"
"decision_status":"pending"
"company_id":null
"contact_id":null
"process_definition_id":"prd_8a2b3c4d5e6f7a8b"
"process_instance_id":"pci_1b2c3d4e5f6a7b8c"
"process_status":"running"
"url":"https://onboarding.example.com/o/obc_3f8a…"
"initial_data":{1 item
"company":{...}3 items
}
"dedupe_key":"source_reference:crm-prospect-00512"
"locale":"fr"
"return_url":"https://example.com/onboarding/return"
"source_reference":"CRM-PROSPECT-00512"
"metadata":{}0 items
"checks":[]0 items
"opened_at":"2026-06-17T09:00:00.000Z"
"closed_at":null
"created_at":"2026-06-17T09:00:00.000Z"
"updated_at":"2026-06-17T09:00:00.000Z"
}
{
"object": "onboarding_case",
"id": "obc_3f8a1d9c2b4e7f6a",
"subject_type": "company",
"status": "open",
"decision_status": "pending",
"company_id": null,
"contact_id": null,
"process_definition_id": "prd_8a2b3c4d5e6f7a8b",
"process_instance_id": "pci_1b2c3d4e5f6a7b8c",
"process_status": "running",
"url": "https://onboarding.example.com/o/obc_3f8a…",
"initial_data": {
  "company": {
    "legal_name": "Dupont & Fils SARL",
    "registration_number": "841234567",
    "registration_country": "FR"
  }
},
"dedupe_key": "source_reference:crm-prospect-00512",
"locale": "fr",
"return_url": "https://example.com/onboarding/return",
"source_reference": "CRM-PROSPECT-00512",
"metadata": {},
"checks": [],
"opened_at": "2026-06-17T09:00:00.000Z",
"closed_at": null,
"created_at": "2026-06-17T09:00:00.000Z",
"updated_at": "2026-06-17T09:00:00.000Z"
}

Subject type

The field subject_type determines the nature of the subject being onboarded and resulting closure constraints.

subject_typeSujetRequired for approval
companyCompany (legal entity)company_id must be populated
individualParticulier (personne physique)company_id et contact_id must be populated

The onboarding decision remains carried by the case through decision_status. It is not projected onto the company: multiple cases may coexist or be replayed, and policy authorizing a later operation belongs to the process or merchant.

Fields

FieldTypeDescription
idstringCase identifier (prefix `obc_`).
objectstringAlways "onboarding_case".
merchant_idstringMerchant owning the case.
subject_typeenumSubject type: `company` or `individual`.
statusenumLifecycle: `open`, `completed`, `cancelled`.
decision_statusenumFinal decision: `pending`, `approved`, `rejected`.
company_idstringCompany attached to the case (`cmp_…`). May be null until resolution in the process.
contact_idstringPrimary attached contact (`ctc_…`). Required for approved `individual` cases.
process_definition_idstringOnboarding process definition started (`prd_…`).
process_instance_idstringProcess instance currently driving the case (`pci_…`). May change during corrective resume.
process_statusenumExecution state derived from the associated instance: `running`, `waiting`, `stopping`, `completed`, `failed`, `retry_exhausted`, `superseded`, `stopped`, or null.
urlstringURL of the hosted onboarding experience. Returned in the creation response.
initial_dataobjectPrefill data injected into the process. See dedicated section.
dedupe_keystringDeduplication key. Automatically generated when absent. See dedicated section.
localestringUser Journey language (for example `fr`, `en`).
return_urlstringRedirect URL after experience completion.
source_referencestringReference in your system (CRM, internal case…).
metadataobjectFlat map of `string | number | boolean` scalars, following the API metadata convention.
checksarrayCompliance checks attached to the case. Included only on GET /:id.
opened_atdatetimeCase opening date.
closed_atdatetimeClosure date (final status). `null` while still open.
created_atdatetimeCreation date.
updated_atdatetimeLast update date.

Lifecycle and decision

The field status describes the case lifecycle. The decision_status field expresses the final decision. Only certain combinations are valid.

Initial stateopen
completed
cancelled

Combinaisons valides

statusdecision_statusValideNote
openpendingyesInitial state. No decision made.
completedapprovedyesFavorable decision. Company (and contact for `individual`) required.
completedrejectedyesUnfavorable decision.
completedpendingnoA `completed` case must carry a decision.
cancelledpendingyesCancellation without decision. `decision_status` cannot be non-pending.
cancelledapproved/rejectednoA canceled case cannot carry a decision.
Closure constraints

A case in a final status (completed or cancelled) can no longer be modified. When using the finalize_onboarding_casenode, the status parameter directly takes the decision value ( "approved" or "rejected"), not the case status — the node applies status: completed.

Associated process

A case created with an onboarding process exposes the instance currently driving it through process_instance_id. The process_status gives the state of this instance. It is derived from the associated execution and remains distinct from status and decision_status.

ExampleInterpretation
status: open + process_status: runningThe case is open and processing is underway.
status: open + process_status: stoppedExecution was stopped, but the case was not automatically canceled.
status: completed + decision_status: approved + process_status: completedThe case carries a favorable decision and execution is complete.
The decision remains explicit

A instance completed does not automatically approve or reject the case. An instance failed, retry_exhausted or stopped does not automatically move it to cancelled. The finalize_onboarding_case and explicit update nodes remain responsible for the decision and business lifecycle.

When a manual retry, a fork retry_step / skip_step or resumption of a user step creates a new instance to continue the same onboarding, process_instance_id switches to this new instance. It becomes the canonical execution of the case and process_status reflects its state. The old instance remains available for traceability.

See Errors and idempotency for resume and associated-instance transfer rules.

Initial data

The field initial_data allows pre-filling subject data before the process starts. This data is injected into the process as variables of type draft :

Key in initial_dataProcess variableAccepted fields
initial_data.companycompany_draftlegal_name, trade_name, legal_form, registration_number, registration_country, tax_identifier, registered_address, incorporation_date, share_capital, currency, is_buyer, is_supplier, source_reference, metadata
initial_data.contactcontact_draftfull_name, first_name, last_name, email, phone, job_title, preferred_locale, source_reference, metadata

These draft variables are available as soon as the process starts and may be passed to nodes create_company or create_contact to create the actual objects without asking again for already-known data.

Creation with prefilled initial data

HTTP
POST /v1/onboarding-cases
{4 items
"subject_type":"company"
"locale":"fr"
"source_reference":"CRM-PROSPECT-00512"
"initial_data":{1 item
"company":{...}4 items
}
}
{
"subject_type": "company",
"locale": "fr",
"source_reference": "CRM-PROSPECT-00512",
"initial_data": {
  "company": {
    "legal_name": "Dupont & Fils SARL",
    "registration_number": "841234567",
    "registration_country": "FR",
    "is_buyer": true
  }
}
}

Deduplication

The platform prevents opening several active cases for the same subject. Detection relies on a deduplication key (dedupe_key).

When dedupe_key is not supplied, it is automatically generated according to this priority:

  1. source_reference:<normalized value> — when source_reference is present
  2. person_company:<email>:<country>:<number> — when email and company number are present in initial_data
  3. company_registration:<country>:<number> — when only company number is available
  4. person_email:<email> — when only email is available

If an active case (status: open) already exists with the same key, creation returns an error 409 :

HTTP
409 Conflict
{1 item
"error":{1 item
"message":"An active onboarding case already exists for this dedupe key"
}
}
{
"error": {
  "message": "An active onboarding case already exists for this dedupe key"
}
}

To bypass deduplication in specific cases, for example intentional re-onboarding, pass a dedupe_key random unique value on every creation.

Compliance checks

Each case carries an array checks of compliance checks performed during the process. These checks are available on GET /v1/onboarding-cases/:id (not included in the list).

Every check records a verification result with its provider, scope, verified subject, and timestamp. Possible results are:

ResultMeaning
pendingVerification awaiting result
passedVerification successful
failedVerification failed
manual_reviewAmbiguous result requiring manual review
errorTechnical error during verification

The node create_compliance_check lets the process record a verification trace. It accepts as subject (subject) a company, contact, or contact_role. The check_type field may take free-form values (for example kyc, kyb, sanctions, pep).

In processes

The case is automatically injected as input to the onboarding process under the variable onboarding_case (type platform.onboarding_case). Five nodes can operate it:

NodeRoleKey inputs / outputs
finalize_onboarding_caseResolves subjects, attaches them, and applies the final decision — recommended patternAccepts: onboarding_case, status (approved | rejected), company?, contact? · Produces: onboarding_case, company, contact
update_onboarding_case_statusUpdates status and/or decision_statusAccepts: onboarding_case, status (open | completed | cancelled), decision_status? · Produces: onboarding_case
update_onboarding_case_subjectAttaches a company and/or contact to the case without closing itAccepts: onboarding_case, company?, contact?, source_reference, dedupe_key · Produces: onboarding_case
create_compliance_checkRecords a compliance check on a subject, with optional attachment to the caseAccepts: onboarding_case?, scope, subject, check_type, provider?, result, raw_response?, valid_until? · Produces: compliance_check
has_already_onboardedChecks whether the company already has an approved and closed onboardingAccepts: company, contact? · Route yes (produces onboarding_case, completed_at) / no
finalize_onboarding_case vs update_onboarding_case_status

In the finalize_onboarding_case node, status takes "approved" or "rejected" (the decision), not "completed". The node itself applies status: completed and resolves the subjects in one operation. Use update_onboarding_case_status only when attachment logic has already been handled separately.

Events

EventTrigger
onboarding_case.company.createdCase created with `subject_type = company`.
onboarding_case.individual.createdCase created with `subject_type = individual`.
onboarding_case.completedCase closed with `decision_status = approved`.
onboarding_case.rejectedCase closed with `decision_status = rejected`.

The creation event is differentiated by subject_type, allowing distinct onboarding processes by subject nature without extra trigger filtering. Transitioning to cancelled does not emit a dedicated event.

L'endpoint GET /v1/onboarding-cases/search lets you retrieve the latest completed and approved case for a given company and optionally contact without traversing the paginated list:

HTTP
GET /v1/onboarding-cases/search?company_id=cmp_3a8f
"onboarding_case_search_result":{3 items
"object":"onboarding_case_search_result"
"onboarding_case":{2 items
"id":"obc_3f8a"
"status":"completed"
}
"completed_at":"2026-01-15T14:30:00.000Z"
}
{
"object": "onboarding_case_search_result",
"onboarding_case": {
  "id": "obc_3f8a",
  "status": "completed"
},
"completed_at": "2026-01-15T14:30:00.000Z"
}