> For the complete documentation index, see [llms.txt](https://docs.delos.financial/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.delos.financial/batchservice/create-batch.md).

# Create Batch

Creates a new Bulk Client Import batch for the customer types you select: individuals, companies, or both. At creation the platform **freezes the verification schema** for the selected types, so the batch is always validated against the requirements that were in effect at this moment, even if they change later.

The new batch starts in status `OPEN` with all row counters at `0`. Counters stay at zero until you commit a manifest; uploading files to storage does not change them.

A batch is created completely or not at all: if any required schema cannot be resolved, no partially usable batch is created.

You can have at most **3 batches that are not closed** at the same time. Creating a fourth returns `409`; cancel a batch you no longer need to free a slot.

**Endpoint**

`POST /v2/compliance/batch`

**Link**

<https://partner.sandbox.delos.financial/openapi/v2.html#/operations/BatchService_CreateBatch>

**Request**

**Headers**

| Key             | Value              | Required |
| --------------- | ------------------ | -------- |
| `Authorization` | `<JWT>`            | Yes      |
| `Content-Type`  | `application/json` | Yes      |
| `Accept`        | `application/json` | Yes      |

**Body**

`CreateBatchRequest` selects the application types the batch will accept. The platform resolves the matching verification levels automatically.

| Field       | Type            | Description                                                                                                    | Required | Example                     |
| ----------- | --------------- | -------------------------------------------------------------------------------------------------------------- | -------- | --------------------------- |
| **`types`** | `array[string]` | Customer types the batch will accept: `individual`, `company`, or both. Empty and repeated values are invalid. | Yes      | `["individual", "company"]` |

**Example Request Body:**

```json
{
  "types": ["individual", "company"]
}
```

**Response (201 Created)**

Returns the created `Batch` object.

**Response Fields**

| Field                      | Type                 | Description                                                                                                       | Example                                  |
| -------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| **`batch_id`**             | `string`             | Unique batch identifier. Use it in all other batch methods.                                                       | `"01a0af8b-831f-7dbe-8eaf-459f81998958"` |
| **`status`**               | `string`             | Batch status: `OPEN`, `CLOSED`, `CHANGE_REQUESTED` or `CANCELLED`. Always `OPEN` for a new batch.                 | `"OPEN"`                                 |
| **`schema_version`**       | `string`             | Version of the frozen schema snapshot. You can pass it in `manifest.json`; a foreign value is rejected at commit. | `"string"`                               |
| **`types`**                | `array[string]`      | Customer types selected at creation.                                                                              | `["individual", "company"]`              |
| **`individual_kyc_level`** | `string`             | Opaque reference to the individual schema. Empty if individual rows are not enabled.                              | `"string"`                               |
| **`company_kyc_level`**    | `string`             | Opaque reference to the company schema. Empty if company rows are not enabled.                                    | `"string"`                               |
| **`party_kyc_levels`**     | `array[string]`      | Opaque references to associated-party schemas in `associated_party_levels` of Get Batch Schema, sorted.           | `["string"]`                             |
| **`counters`**             | `object`             | `ItemCounters` — number of rows per status. Always numbers, including zeros.                                      | see below                                |
| **`processed`**            | `boolean`            | `true` when every row has reached `submitted`, `invalid`or `failed`.                                              | `false`                                  |
| **`done`**                 | `boolean`            | `true` when every row has a final result.                                                                         | `false`                                  |
| **`created_at`**           | `string (date-time)` | When the batch was created.                                                                                       | `"2026-09-28T10:15:30Z"`                 |
| **`committed_at`**         | `string (date-time)` | When the batch was last committed. Empty for a new batch.                                                         | —                                        |
| **`processed_at`**         | `string (date-time)` | When `processed` became `true`. Empty for a new batch.                                                            | —                                        |
| **`done_at`**              | `string (date-time)` | When `done` became `true`. Empty for a new batch.                                                                 | —                                        |
| **`error`**                | `string`             | Set only if the batch itself failed (e.g. an unreadable manifest). Row-level problems are reported on rows.       | `""`                                     |

**`counters` object (`ItemCounters`)**

| Field                  | Type      | Description                                         |
| ---------------------- | --------- | --------------------------------------------------- |
| **`total`**            | `integer` | Total rows in the batch.                            |
| **`draft`**            | `integer` | Rows accepted from the manifest, not yet validated. |
| **`valid`**            | `integer` | Rows that passed validation.                        |
| **`invalid`**          | `integer` | Rows that failed validation.                        |
| **`creating`**         | `integer` | Rows whose customer is being created.               |
| **`submitted`**        | `integer` | Rows submitted for compliance review.               |
| **`finished`**         | `integer` | Approved customers.                                 |
| **`change_requested`** | `integer` | Rows where reviewers requested changes.             |
| **`rejected`**         | `integer` | Rejected customers.                                 |
| **`failed`**           | `integer` | Rows that could not be processed.                   |

**Example Response:**

```json
{
  "batch_id": "01a0af8b-831f-7dbe-8eaf-459f81998958",
  "status": "OPEN",
  "schema_version": "string",
  "types": ["individual", "company"],
  "individual_kyc_level": "string",
  "company_kyc_level": "string",
  "party_kyc_levels": ["string"],
  "counters": {
    "total": 0,
    "draft": 0,
    "valid": 0,
    "invalid": 0,
    "creating": 0,
    "submitted": 0,
    "finished": 0,
    "change_requested": 0,
    "rejected": 0,
    "failed": 0
  },
  "processed": false,
  "done": false,
  "created_at": "2026-09-28T10:15:30Z",
  "error": ""
}
```

***

**Examples**

**Request — individuals only**

```bash
curl --request POST \
  --url <https://partner.sandbox.delos.financial/v2/compliance/batch> \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <JWT>' \
  --header 'Content-Type: application/json' \
  --data '{
  "types": ["individual"]
}'
```

**Response**

```json
{
  "batch_id": "01a0c461-2b7e-7c3a-9f10-5d2e8a4b6c01",
  "status": "OPEN",
  "schema_version": "string",
  "types": ["individual"],
  "individual_kyc_level": "string",
  "company_kyc_level": "",
  "party_kyc_levels": [],
  "counters": {
    "total": 0,
    "draft": 0,
    "valid": 0,
    "invalid": 0,
    "creating": 0,
    "submitted": 0,
    "finished": 0,
    "change_requested": 0,
    "rejected": 0,
    "failed": 0
  },
  "processed": false,
  "done": false,
  "created_at": "2026-09-28T10:15:30Z",
  "error": ""
}
```

***

**Error Responses**

Errors are returned as `{"code", "message", "details"}`, where `code` is a gRPC status code. Use the HTTP status for error handling.

**Invalid Request (400)** — `types` is empty, contains a repeated or unknown value, or a required associated-party structure is not supported:

```json
{
  "code": 3,
  "message": "types must not be empty",
  "details": []
}
```

**Authorization fail (401)**:

```json
{
  "code": 16,
  "message": "Unauthorized",
  "details": []
}
```

**Access Restricted (403)** — your partner account is not enabled for Bulk Client Import:

```json
{
  "code": 7,
  "message": "partner is not allowed to import batches",
  "details": []
}
```

**Open-Batch Limit Reached (409)** — you already have 3 batches that are not closed:

```json
{
  "code": 6,
  "message": "open batch limit reached",
  "details": []
}
```

**Schema Source Unavailable (503)** — the verification schema could not be resolved right now. No batch is created; retry later:

```json
{
  "code": 14,
  "message": "schema source unavailable",
  "details": []
}
```

***

**Next Steps**

1. **Get the schema** — call `GET /v2/compliance/batch/{batch_id}/schema` to see which fields, documents, questionnaire answers and associated parties each row needs.
2. **Get the example manifest** — call `GET /v2/compliance/batch/{batch_id}/example-manifest` and use it as the starting point for `manifest.json`.
3. **Get storage credentials** — call `GET /v2/compliance/batch/{batch_id}/credentials` and upload documents and the manifest.

***

**Notes**

* **Frozen schema**: the requirements captured at creation apply for the whole life of the batch. To onboard against newer requirements, create a new batch.
* **Select only the types you need**: rows of a type that was not selected at creation are rejected as `invalid`. You can't add a type to an existing batch.
* **Open-batch limit**: `OPEN`, `CLOSED` and `CHANGE_REQUESTED` batches count towards the limit of 3; a `CANCELLED` batch does not. Use Cancel Batch to free a slot.
* **Opaque identifiers**: `individual_kyc_level`, `company_kyc_level` and `party_kyc_levels` are references into the schema returned by Get Batch Schema. Do not parse them or rely on their format.
* **Counters**: all counters are `0` until the first commit. Uploading files to the prefix does not add rows.

**Typical Workflow**:

1. Call `POST /v2/compliance/batch` with the types you plan to onboard.
2. Save `batch_id` from the response.
3. Fetch the schema and the example manifest.
4. Get storage credentials, upload documents and `manifest.json`.
5. Commit the batch with `POST /v2/compliance/batch/{batch_id}/commit`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.delos.financial/batchservice/create-batch.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
