KYC version submission
Create, edit, and submit a versioned KYC profile for review through the DALP Platform API, SDK, and CLI.
KYC data on DALP is versioned. A user's identity submission lives in a KYC profile version that moves through a fixed lifecycle: you create a draft, edit it, attach documents, and submit it for review. Submission locks the version and hands it to a reviewer, who approves it, rejects it, or requests changes.
Each step is a single Platform API call against the user or version ID: read the profile, list versions, create a draft, read or update a draft, and submit it. The reviewer decisions that follow submission live in KYC reviewer version actions. The operator walkthrough in the Console lives in Provide KYC data.
Version lifecycle
A version holds one status at a time, and each status allows a fixed set of operations. The happy path runs in order: create a draft, edit it, attach documents, then submit.
| Status | What it means | What you can do |
|---|---|---|
draft | The version is being prepared. | Edit fields, attach or remove documents, and submit. |
under_review | The version is in the review workflow. | Read the submission. Editing is locked until review ends. |
approved | A reviewer accepted the version. | Read the approved data. Create a new draft to make changes. |
rejected | A reviewer declined the version. | Read the rejection reason and create a corrected draft. |
A user keeps at most one open draft. Each profile read and version read returns
canEdit, canSubmit, and canReview flags so your integration can drive the
interface from the platform's view of the current state instead of inferring it.
Read the profile
Read the profile to find the user's approved version, latest version, and whether an update is pending. Start here when you build a KYC screen for a user.
const profile = await client.user.kyc.profile.read({
params: { userId: "usr_01hzt7n4investor0001" },
});Direct HTTP integrations call GET /api/v2/kyc-profiles/{userId}.
{
"data": {
"id": "kyc_01hzt7n4profile00001",
"userId": "usr_01hzt7n4investor0001",
"hasPendingUpdate": false,
"approvedVersion": null,
"latestVersion": {
"id": "kycv_01hzt7n4draftversion",
"versionNumber": 1,
"isDraft": true
},
"openActionRequestsCount": 0
}
}List versions
List a user's versions to show their submission history. The list paginates and filters by status, and reports which version is approved and which is current.
const versions = await client.user.kyc.versions.list({
params: { userId: "usr_01hzt7n4investor0001" },
query: { status: { inArray: "under_review,approved" }, limit: 10 },
});Direct HTTP integrations call GET /api/v2/kyc-profiles/{userId}/versions. The
response sorts by versionNumber ascending by default and supports sorting on
versionNumber, status, submittedAt, and reviewedAt.
Create a draft
Create a draft to start a new submission. A draft clones its starting values from
the user's approved version by default, or from the latest version. When a user
has no version yet, supply the starting values through initialData.
const draft = await client.user.kyc.versions.create({
params: { userId: "usr_01hzt7n4investor0001" },
body: {
cloneFrom: "approved",
initialData: {
firstName: "Maria",
lastName: "Santos",
country: "PT",
},
},
});Direct HTTP integrations call POST /api/v2/kyc-profiles/{userId}/versions. The
initialData object carries the identity fields the user supplies. A date of birth,
when provided, must place the user at age 18 or older. The new draft returns with
status set to draft and the next versionNumber.
{
"data": {
"id": "kycv_01hzt7n4newdraft0001",
"versionNumber": 2,
"status": "draft",
"userId": "usr_01hzt7n4investor0001",
"createdAt": "2026-05-24T09:58:11.204Z",
"createdBy": "usr_01hzt7n4investor0001"
}
}After the draft exists, attach supporting files with the
KYC document uploads API.
Documents can be added or removed only while the version stays in draft.
Update a draft
Update a draft to correct identity fields before submission. Only a draft version
accepts edits. Once a version leaves draft, create a new draft to make further
changes.
const updated = await client.user.kyc.version.update({
params: { versionId: "kycv_01hzt7n4newdraft0001" },
body: {
residencyStatus: "resident",
},
});Direct HTTP integrations call PATCH /api/v2/kyc-profile-versions/{versionId}.
Read a version
Read a single version to show its full state and workflow metadata, including the
canEdit, canSubmit, and canReview flags and the attached documentsCount.
const version = await client.user.kyc.version.read({
params: { versionId: "kycv_01hzt7n4newdraft0001" },
});Direct HTTP integrations call GET /api/v2/kyc-profile-versions/{versionId}.
Submit for review
Submit a draft to send it into the review workflow. Submission moves the version to
under_review, records who submitted it and when, and locks the version against
further edits. Documents are optional at the platform level, though your
organization may require specific documents before a reviewer approves the profile.
const submitted = await client.user.kyc.version.submit({
params: { versionId: "kycv_01hzt7n4newdraft0001" },
});Direct HTTP integrations call POST /api/v2/kyc-profile-versions/{versionId}/submissions.
{
"data": {
"id": "kycv_01hzt7n4newdraft0001",
"status": "under_review",
"submittedBy": "usr_01hzt7n4investor0001"
}
}After submission, a reviewer acts on the version. See KYC reviewer version actions for the approve, reject, and request-update decisions and their outcomes.
State transitions
| Step | From | To | Side effect |
|---|---|---|---|
| Create | none | draft | A new draft version is created with the next version number. |
| Update | draft | draft | Identity fields on the draft are changed. |
| Submit | draft | under_review | The version is locked and the profile enters review. |
CLI equivalents
The DALP CLI exposes the same submitter steps for operator scripts. Reach for it when a back-office job is easier to run outside the SDK:
| Task | CLI command |
|---|---|
| Read profile | kyc profile |
| List versions | kyc versions |
| Create draft | kyc version-create |
| Read version | kyc version-read |
| Update draft | kyc version-update |
| Submit | kyc version-submit |
Validation and error handling
Treat these as terminal request errors unless the response says otherwise. Confirm the version status before retrying, and store the request ID from the API response when you escalate a repeated platform error.
| Error | What DALP observed | Caller response |
|---|---|---|
DALP-0391 | Submit targeted a version that is not in draft. | No change is made. Only a draft version can be submitted. |
DALP-0392 | Update targeted a version that is not in draft. | No change is made. Create a new draft to make further changes. |
DALP-0413 | Create requested a clone but the user has no version to clone from. | Provide initialData for a user who is submitting for the first time. |
DALP-0416 | Profile read or create found no KYC profile for the user. | Confirm the user ID, or create the first draft to start the profile. |
DALP-0418 | Create referenced a source version that does not exist. | Confirm cloneFromVersionId, or provide initialData instead. |
DALP-0421 | Version read targeted an ID that does not match a KYC version. | No change is made. Confirm the version ID. |
Related
Identity recovery API
Preview, start, and monitor identity recovery workflows for users who lost access to a wallet.
KYC document upload and download API flow
Upload, confirm, list, download, and delete KYC documents through the DALP API, SDK, and CLI, with auth-gated download URLs that re-check access on every request.