Response shape
On success the body is the data object. There is no envelope — the HTTP status tells you it succeeded.Success — 201 from create
429, 503 and the Api-Version rejection.
409
All field, questionnaire and custom-field errors arrive together, one entry each,
and nothing is created. Duplicate email (
ERRCUS_1600), duplicate phone
(ERRCUS_1601), restricted country (ERRCUS_1605) and a reused share token are
checked afterwards, one at a time, and only once the fields are valid — on create
and on update:
400 — two problems
errors[].field
The offending input, as a single machine-mappable token — email, company.phone,
beneficiaries[0].dob, customFields.whatsappNumber, userType, status,
Api-Version, userId, idDocType, document, subjectType, subjectId,
uboRef, beneficiaries[0].types. A questionnaire item uses the full path —
questionnaire.sections.profileDetails.items.occupation.value.
A missing block names the block (company, company.address, beneficiaries),
and a cross-beneficiary rule (share total, no UBO) names beneficiaries. Only
errors with no single input (a malformed questionnaire structure, a restricted
country) carry field: null.
Message wording
Most messages are field-prefixed and lower-cased to match the field token:Status codes
Conflicts
A duplicate email on a normal create is a
400, ERRCUS_1600. The 409
variant, ERRCUS_1602, is only the concurrent-retry race.Verification lifecycle
status can also take these five values — the only ones beyond the eight above:
Treat unknown values as in progress. The
list filter
?status= accepts only the
original eight.
For an individual, the customer is submitted for review automatically once
every required document step is uploaded — the photo ID, the selfie and the
proof of address (a UTILITY_BILL). Until then each upload answers SUBMITTED with
a missing list. For a business, Endl submits the business after its first
company document, once every owner’s documents are complete — so upload both
company groups before the owners’ last document. A business keeps its current
status (normally INITIATED) until then, and never returns SUBMITTED.
Locks on completion
The lock is not the same for the two customer types.
The questionnaire is not in either list because it is never editable: it is set on
create. On update a non-empty
questionnaire object is 400 ERRCUS_1303, an empty
or non-object one is 400 ERRCUS_1301, and null is ignored — before or after
completion.
Onboarding error codes
Every onboarding error carries its ownERRCUS_* code in errors[].code. The HTTP
status, message and field are the same as they would otherwise be — for
beneficiaries the code is per field and the index stays in field, so
ERRCUS_1206 comes with field: "beneficiaries[2].email".
Individual customer
Business company
Business beneficiaries
Questionnaire and custom fields
Question keys come from the verification level, so these codes are per reason, andfield names the exact question — for example
questionnaire.sections.profileDetails.items.occupation.value.
Documents
The document
country uses ERRCUS_1012 (sent but blank) and ERRCUS_1013 (invalid). Omitted entirely, it is 400 ERRCORE_1001 (country is required).
Request level
Onboarding business rules
Verification-provider errors
Errors from the verification step that you can act on keep their ownERRCOMP_*
code, message and HTTP status, rather than collapsing into a generic 500:
409
500 ERRCORE_1000. The 500 message is free text
and may include internal detail; don’t parse it. A verification-service failure
returns Service temporarily unavailable, please try again (503 ERRCORE_1008 on a
timeout).
Codes that are not onboarding-specific
These keep theirERRCORE_*, ERRREF_* or ERRCOMP_* code: