For the complete documentation index, see llms.txt. This page is also available as Markdown.

Bulk Client Import

Bulk Client Import lets you submit many customers for KYC/KYB verification in a single batch instead of creating and onboarding each one through separate API calls. You describe all customers in one manifest.json file, upload it together with their documents to a dedicated storage prefix, and start processing. The platform validates the data, creates the customers, submits them for compliance review and reports the outcome for every row.

A batch can contain individuals, companies (with their associated parties: UBOs, directors and authorized signatories), or both.

All Bulk Client Import methods live under /v2/compliance/batch and belong to the BatchService group of the Partner API.


When to use it

  • Migrating an existing customer base to Delos.

  • Onboarding customers in bulk from your CRM or back office.

  • Any case where calling Add Customer + application methods one by one would be slow or hard to track.

For onboarding a single customer, keep using Add Customer and Get Compliance Link.


Key concepts

Term
Meaning

Batch

A container for one import. It has a lifecycle status, row counters and its own storage prefix.

Schema snapshot

The verification requirements (fields, documents, questionnaire, associated-party roles) frozen when the batch is created. The batch is always validated against this snapshot, even if requirements change later.

Manifest

manifest.json in the root of the batch prefix. One item (row) per customer.

Row

One customer in the manifest, identified by your row_key. Each row has its own status and result.

Prefix

A private folder in Delos storage (S3-compatible) where you upload the manifest and documents using temporary credentials.


Batch lifecycle

Status
Meaning
Uploads allowed

OPEN

Created and waiting for files and a manifest.

Yes

CLOSED

Committed. The manifest is accepted and rows are being processed.

No

CHANGE_REQUESTED

Reopened by you for corrections after a commit.

Yes

CANCELLED

Closed permanently. Final state.

No

Transitions

Action
From
To
Other states

Commit

OPEN, CHANGE_REQUESTED

CLOSED

409

Request changes

CLOSED

CHANGE_REQUESTED

No-op from CHANGE_REQUESTED, 409 from OPEN

Cancel

OPEN, CHANGE_REQUESTED

CANCELLED

No-op from CANCELLED, 409 from CLOSED

You can have at most 3 batches that are not closed at the same time. Cancel batches you no longer need to free a slot.


Integration flow

Base URL (Sandbox): https://partner.sandbox.delos.financial

All requests require the Authorization: Bearer <JWT> header. The partner is identified from the token; you never pass a partner ID.

Step 1. Create a batch

Select which customer types this batch will contain.

The response (201) is a Batch object. Save batch_id and schema_version. At this moment the platform freezes the schema snapshot for the selected types.

Step 2. Get the schema and the example manifest

The schema tells you exactly what to provide for each customer:

Schema part
Describes
Filled in the manifest as

fields

Profile fields: required flag, value type, format

fields

documents

Allowed document types and document groups

documents

questionnaire

Questionnaire sections and questions: id, type, options, required flag

questionnaire

associated_parties

Companies only: required roles (UBO, director, etc.)

associated_parties

Use individual_schema for individual rows and company_schema for company rows. Each role in company_schema.associated_parties references a level; the fields and documents for that party are in associated_party_levels under that reference.

Fastest start: download the example manifest. It is generated from your batch's frozen schema and contains one row per selected type, every field with a "<required>" / "<optional>" placeholder, sample documents, questionnaire answers in the correct shape, and one party for each required company role. Replace the placeholders, remove optional parts you do not need, and save it as manifest.json. The same file is also placed in your prefix as example_manifest.json; the platform never reads it as data.

Step 3. Get storage credentials and upload documents

The response contains bucket, prefix, region and temporary credentials (access_key_id, secret_access_key, session_token, expiration). Credentials only work inside your batch prefix and are valid for about 12 hours. Request new ones with the same call when they expire. Credentials are issued only while the batch is OPEN or CHANGE_REQUESTED.

Upload all customer documents into the prefix. The folder structure is up to you; file paths in the manifest must match where you put the files.

Tip: add ?format=credential_process to receive credentials in the AWS credential_process format. The AWS CLI/SDK will then refresh them automatically:

File requirements

  • Formats: PDF, JPEG, PNG. The file content is checked, not the extension.

  • Maximum size: 50 MB per file.

  • Corrupted, password-protected or truncated files are rejected.

Step 4. Compose and upload manifest.json

Upload one manifest.json to the root of the prefix.

Step 5. Commit the batch

Make sure every file and the manifest are fully uploaded first. A successful commit returns 202: the batch becomes CLOSED and processing starts. Row validation runs asynchronously after the commit.

Do not overwrite manifest.json after a commit. The platform verifies the content of the accepted manifest and stops processing if it has been replaced.

Step 6. Track results

Call
Use it to

GET /v2/compliance/batch/{batch_id}

See row counters and the processed / done flags.

GET /v2/compliance/batch/{batch_id}/items

List rows, optionally filtered by status.

GET /v2/compliance/batch/{batch_id}/items/{row_key}

Get one row with full review details and rejection reasons.

GET /v2/compliance/batch/{batch_id}/status

Get a summary of problems with readable explanations, plus the list of created customers.

  • processed: true means every row has reached submitted, invalid or failed: onboarding is complete on your side.

  • done: true means every row has a final result.

A report.json file with the outcome of every row also appears in your prefix. You can download it with credentials obtained before the commit, as long as they have not expired.


Manifest format

The manifest is a JSON object with an items array, one item per customer. You can optionally include schema_version; if it is omitted or empty, the batch's frozen snapshot is used. A schema_version from another batch is rejected.

Row fields

Field
Type
Required
Description

row_key

string

Yes

Your unique identifier of the row. Must be unique within the manifest. You use it to find the row's result.

external_customer_id

string

No

Your stable customer identifier. Prevents the same customer from being created twice, in this or any other batch. Cannot be changed after commit.

type

string

Yes

individual or company. Must be one of the types selected when the batch was created.

fields

object

Yes

Profile field values, keyed by field id from the schema.

documents

array

Yes

Documents: type, optional sub_type, file (path relative to the prefix).

questionnaire

object

If the schema has one

Answers: sections → section id → items → question id → answer.

associated_parties

array

Companies only

Company participants: party_key, roles in types, their own fields and documents.

Individual row example

Field ids, document types, questionnaire section and question ids above are examples. Always take them from your batch's schema or example manifest.

Validation rules

  • Fields. Every field with required: true must have a non-empty value of the correct type. If the schema defines a format, the value must match it:

    • date: YYYY-MM-DD

    • country: ISO 3166-1 alpha-2 code (e.g. CY)

    • email: a valid address with @ and a domain

    • phone: E.164 (+ and up to 15 digits, no spaces or brackets)

  • Markup. Values containing < or > are rejected in profile fields, free-text questionnaire answers and external_customer_id.

  • Documents. The type must be allowed by the schema, and file must point to an uploaded file.

    • Two-sided documents (ID card, residence permit, driver's licence) are sent as two entries of the same typewith sub_type FRONT_SIDE and BACK_SIDE. If you have both sides, send both. A back side without a front side is not accepted.

    • A passport has no sides; send one entry without sub_type.

    • For companies, the document type is always COMPANY_DOC; the specific document kind goes in sub_type. Every required company document group must be covered by at least one file.

  • Questionnaire. The answer shape depends on the question type:

    • regular question: value

    • multiple-choice question: values (each must be one of the question's options)

    • file question: files, a list of paths. Never put a file path in value.

    All required visible questions must be answered.

  • Associated parties (companies). Each party has its own party_key, roles in types (UBO, DIRECTOR, AUTHORIZED_SIGNATORY), fields and documents. Roles with can_skip: false in the schema are mandatory. For a UBO, pass the ownership share in share_size.

How errors are handled

  • An error in a row marks only that row as invalid; all other rows are processed.

  • If the manifest as a whole cannot be accepted, the commit is rejected with 422 and the batch stays editable. This happens when manifest.json is missing or too large, is not valid JSON, has trailing content, has no items, has more than 10,000 rows, or has a foreign schema_version.


Row statuses

Status
Meaning

invalid

The row failed manifest validation. The reason is in error.

valid

Passed validation, waiting to be processed.

creating

The customer is being created and the documents submitted.

submitted

Submitted for compliance review.

finished

Customer approved. Final.

rejected

Customer rejected. Final.

change_requested

Reviewers ask to correct data or documents.

failed

Could not be processed: broken file, duplicate customer or another permanent error. The reason is in error. Final.

Batch counters are always numbers, including zeros. Uploading files alone does not change them; before the first commit all counters are 0.

Where to find rejection details

  • GET .../status returns problems: rows in invalid, failed, change_requested or rejected, each with a readable summary.

  • GET .../items/{row_key} returns the full review object, including rejection reasons per document (document_reject_reasons), per associated party (party_reject_reasons) and per verification step (step_reject_reasons).


Corrections

A typical situation: some rows ended up invalid or change_requested.

  1. Reopen the batch: POST /v2/compliance/batch/{batch_id}/change. Status becomes CHANGE_REQUESTED.

  2. Get new credentials and upload the corrected files. Put a replacement document under a new path; do not overwrite the old file.

  3. Upload the full manifest again. The manifest is always the source of truth: a row you remove that has not yet been submitted for review is withdrawn.

  4. Commit again.

Rules for existing rows

  • Rows in a final state (finished, rejected, failed) are never changed by a later commit.

  • To retry a customer whose row is failed, add a new row with a new row_key.

  • The type and external_customer_id of an existing row_key cannot be changed.

Letting the customer fix it themselves

For a row in change_requested, you can request a fresh verification link and send it to the end customer:

The response contains url and ttl_seconds. For rows in any other status the call returns 409.


Cancelling a batch

POST /v2/compliance/batch/{batch_id}/cancel closes the batch permanently and frees a slot in the open-batch limit. It works for OPEN and CHANGE_REQUESTED batches.

  • Rows that were not yet submitted for review become failed.

  • Rows already submitted cannot be withdrawn and will still receive a result.


Errors

Errors are returned in the following format:

code is a gRPC status code; use the HTTP status of the response for your error handling.

HTTP
When

400

Invalid request (e.g. empty or repeated types, unsupported format value).

403

Your partner account is not enabled for Bulk Client Import, or the token lacks the required scope.

404

The batch does not exist or belongs to another partner.

409

The action is not allowed in the batch's current status, the open-batch limit is reached, or a WebSDK link is requested for a row not in change_requested.

422

The manifest was rejected at commit. The batch stays editable.

503

The verification schema source is temporarily unavailable when creating a batch. Retry later.


Best practices

  • Start from the example manifest instead of building rows by hand.

  • Always send external_customer_id so a customer is never created twice, even across batches.

  • Upload everything before committing, and run uploads and commits sequentially, not in parallel.

  • Retry a commit only after checking the batch status. A repeated commit on a CLOSED batch returns 200 but does not accept a new manifest.

  • Use processed, not done, as your onboarding milestone. done also waits for compliance decisions, which can take longer.

  • Poll with reasonable intervals. Rows move asynchronously; there is no need to poll more often than once every few minutes.


Endpoint reference

Method
Endpoint
Description

List Batches

GET /v2/compliance/batch

List your batches.

Create Batch

POST /v2/compliance/batch

Create a batch and freeze its schema.

Get Batch

GET /v2/compliance/batch/{batch_id}

Batch status, counters and flags.

Get Batch Schema

GET /v2/compliance/batch/{batch_id}/schema

Frozen schema snapshot.

Get Example Manifest

GET /v2/compliance/batch/{batch_id}/example-manifest

Manifest template with placeholders.

Get Upload Credentials

GET /v2/compliance/batch/{batch_id}/credentials

Temporary storage credentials.

Commit Batch

POST /v2/compliance/batch/{batch_id}/commit

Start processing.

Request Batch Changes

POST /v2/compliance/batch/{batch_id}/change

Reopen a committed batch for corrections.

Cancel Batch

POST /v2/compliance/batch/{batch_id}/cancel

Close a batch permanently.

List Batch Items

GET /v2/compliance/batch/{batch_id}/items

List rows with a status filter.

Get Batch Item

GET /v2/compliance/batch/{batch_id}/items/{row_key}

One row with review details.

Get Item WebSDK Link

GET /v2/compliance/batch/{batch_id}/items/{row_key}/web_sdk_link

Verification link for a row in change_requested.

Get Batch Status

GET /v2/compliance/batch/{batch_id}/status

Problems summary and created customers.

Last updated