# KYC version submission

Source: https://docs.settlemint.com/docs/api-reference/compliance/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](/docs/api-reference/compliance/kyc-reviewer-version-actions).
The operator walkthrough in the Console lives in
[Provide KYC data](/docs/operators/user-management/provide-kyc-data).

## Version lifecycle [#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]

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.

```ts fixture=dalp-client group=kyc-version-submission
const profile = await client.user.kyc.profile.read({
  params: { userId: "usr_01hzt7n4investor0001" },
});
```

Direct HTTP integrations call `GET /api/v2/kyc-profiles/{userId}`.

```json
{
  "data": {
    "id": "kyc_01hzt7n4profile00001",
    "userId": "usr_01hzt7n4investor0001",
    "hasPendingUpdate": false,
    "approvedVersion": null,
    "latestVersion": {
      "id": "kycv_01hzt7n4draftversion",
      "versionNumber": 1,
      "isDraft": true
    },
    "openActionRequestsCount": 0
  }
}
```

## List versions [#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.

```ts group=kyc-version-submission
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]

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`.

```ts group=kyc-version-submission
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`.

```json
{
  "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](/docs/api-reference/compliance/kyc-document-uploads) API.
Documents can be added or removed only while the version stays in `draft`.

## Update a 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.

```ts group=kyc-version-submission
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-version]

Read a single version to show its full state and workflow metadata, including the
`canEdit`, `canSubmit`, and `canReview` flags and the attached `documentsCount`.

```ts group=kyc-version-submission
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-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.

```ts group=kyc-version-submission
const submitted = await client.user.kyc.version.submit({
  params: { versionId: "kycv_01hzt7n4newdraft0001" },
});
```

Direct HTTP integrations call `POST /api/v2/kyc-profile-versions/{versionId}/submissions`.

```json
{
  "data": {
    "id": "kycv_01hzt7n4newdraft0001",
    "status": "under_review",
    "submittedBy": "usr_01hzt7n4investor0001"
  }
}
```

After submission, a reviewer acts on the version. See
[KYC reviewer version actions](/docs/api-reference/compliance/kyc-reviewer-version-actions)
for the approve, reject, and request-update decisions and their outcomes.

## State transitions [#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 [#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 [#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 [#related]

* [KYC reviewer version actions](/docs/api-reference/compliance/kyc-reviewer-version-actions)
* [KYC document uploads](/docs/api-reference/compliance/kyc-document-uploads)
* [Provide KYC data](/docs/operators/user-management/provide-kyc-data)
* [Platform API error reference](/docs/api-reference/errors/platform-api-error-reference)
