Skip to main content

Bulk participant import

Import participant rows in a background batch keyed by an organisation-scoped external reference.

An Identity manager calls POST /api/v2/participants/import-batches with { rows, walletVerification }: up to 500 rows and one wallet step-up for the whole batch. The call answers 202 Accepted with a batchId, a statusUrl and a matching Location header. Read GET /api/v2/participants/import-batches/{batchId} until state is completed. Send Prefer: wait=<seconds> to wait for the batch inside the request. The wait is held between 5 and 99 seconds. When it finishes in time, or every row already fails its row rules, the call answers 200 with the completed batch instead.

A session caller first requests a step-up challenge from POST /api/v2/step-up-challenges with the operation POST /api/v2/participants/import-batches, a target and a payloadDigest. The target is null when the import sends none of the X-Chain-Id, X-Network-Id, X-Executor and X-Custody-Account-Id headers. When it sends any of them, the target is the JSON text of an array holding null and then those four header values in that order, with a missing header as null. The digest is the lowercase hex SHA-256 of the import body's canonical JSON, with object keys sorted, absent fields dropped and the top-level walletVerification left out. The import then carries the challenge id in the X-Step-Up-Challenge header. A challenge works for one request and expires after five minutes. An API key caller sends no challenge and no walletVerification. A missing wallet step-up or challenge answers 400 and a caller without the Identity manager role answers 403, before any row runs. Reading a batch needs the Identity manager role too. When the organisation's approval settings require a second person for the “System administration” group of the Administration family, the import waits for approval and runs once it is approved. Send an Idempotency-Key header to make a retried call safe: the same key from the same caller with the same rows answers the batch it already started, and the same key with different rows answers 409.

Each row carries externalRef, name, email, providerConfigurationId, nationality, residence and kyc (firstName, lastName, dob, residencyStatus, nationalId). nationality and residence are ISO 3166-1 alpha-2 codes. residence becomes the KYC profile country.

Each row that does not fail opens a pending registration request for the participant, or refreshes one still pending, with nationality as the proposed identity registry country. An Identity manager accepts the registration as usual and sees that country prefilled. The import never accepts a registration itself.

A row can carry an optional classification: retail, institutional or proprietary. A batch that uses it also needs the claim issuer role. A caller without that role answers 403 before any row runs. The organisation's identity issues the class as a claim on participantClassRetail, participantClassInstitutional or participantClassProprietary, and only when the participant holds no class yet. A venue reads the class through its own class topic mapping. A row naming a different class from one the participant already holds fails with classification-change-refused and writes no claim, because a class change needs the holder of the participant identity's key. The row's other fields are already saved when it fails. A classified row whose reference is still pending in another batch writes no claim and fails with classification-not-issued. Send it again once that batch has finished.

The import does not take extra wallets. Each participant gets its custody provider's wallet. Register further wallets through the registration routes after the import.

externalRef is unique within the organisation. Sending a reference again updates that participant's name and KYC data instead of creating a second one. The import never changes a login email: a re-sent reference with a different email fails with email-change-refused. A reference that appears twice in one batch fails both rows. A reference whose creation failed is created afresh on its next send.

The batch answers one row per input row, in input order, with status pending, created, updated, unchanged or failed. A failed row carries a code and the field issues that caused it. A created or updated row carries dependency-unavailable when a later step, such as the KYC submission, did not finish. Send it again to finish it.

Code
Meaning
row-invalid
A field broke its rule. issues names the field.
external-ref-duplicate
The reference appears more than once in the batch.
email-in-use
The email belongs to an existing user. The import does not adopt existing members.
email-change-refused
The reference is already imported with another login email. Change it through the user.
participant-create-refused
The user, wallet or identity could not be created.
kyc-fields-rejected
The KYC profile refused a field, or a field the organisation's profile sections require is missing. issues names it. The participant is already created.
kyc-transition-refused
The KYC version could not be submitted for review.
kyc-version-refused
A new KYC version could not be started.
kyc-draft-open
An operator has a KYC draft open for this participant. Finish or discard it, then retry.
classification-not-issued
The class claim could not be written. issues says why. Send the row again to retry it, unless issues says the outcome is unknown. Check the participant's claims first.
classification-change-refused
The participant already holds another class. A change needs the holder of the participant identity's key.
dependency-unavailable
A platform dependency was down. Send the row again later.

A failed row never stops the other rows. KYC data follows the normal provider and review flow: the import submits it for review as the importing operator and never approves it.

Was this page helpful?