---
title: "Create a batch of products"
method: POST
path: "/products/batch"
tags: ["Products"]
---

# Create a batch of products

`POST /products/batch`

Batch process helps to add multiple products in one request. 
⚠️ If a product already exists, an update is applied. Missing parameters in update will be ignored and will not change. Erasing values is not possible.
⚠️ Adjust batch sizes based on processing times. We recommended use maximum amount of 1000 records and adjust the batch size based on processing time.
⚠️ Endpoint is available only in the Enterprise interface.

## Headers

- `Accept-Language` string

## Request body

- object
  - `products` ProductBatch[], required — List of the CareCloud products.
    - `product_id` string — The unique ID of the product.
    - `name` string, required — Name of the product.
    - `code` string — Code of the product.
    - `plu_ids` PluId[], required — An array of all available pluIDs from the particular product lists (default is Product ID from Global product list (consist cleaned data - unique ID of every product across all POS systems)).
      - `list_code` string, required — Code of the particular product list (basic is code of Global product list (consist cleaned data - unique ID of every product across all POS systems)). For example, “GLOBAL”, “SKU”, “PLU”, etc.
      - `code` string, required — Code of product from the product list (basic is Product ID from Global product list (consist cleaned data - unique ID of every product across all POS systems)).
    - `product_group_id` string — The unique ID of the product group. If `product_group_external_id` is also set, both parameters have to represent the same product group. [GET /product-groups](https://carecloud.readme.io/reference/getproductgroups)
    - `product_group_external_id` string — The unique external ID of the product group. If `product_group_id` is also set, both parameters have to represent the same product group.
    - `product_brand_id` string — The unique ID of the product brand. If `product_brand_external_id` is also set, both parameters have to represent the same product brand. [GET /product-brands](https://carecloud.readme.io/reference/getproductbrands)
    - `product_brand_external_id` string — The unique external ID of the product brand. If `product_brand_id` is also set, both parameters have to represent the same product brand.
    - `store_id` string — The unique ID of the store where the product group is valid. The product group is global if this value is not set. [GET /stores](https://carecloud.readme.io/reference/getstores)
    - `partner_id` string — The unique ID of the partner. If the partner is not set, the partner is selected from the logged in user. [GET /partners](https://carecloud.readme.io/reference/getpartners)
    - `property_records` PropertyRecord[] — List of additional properties.
      - `property_record_id` string — The unique ID of the property record.
      - `property_id` string, required — The unique ID of the property.
      - `property_name` string — Name of the property.
      - `property_value` union — Value of the property record. The format depends on the data type of the property. - **string** – a plain text value: ```json { "property_id": "p1_note", "property_value": "VIP customer" } ``` - **date** – a date string in `YYYY-MM-DD` format: ```json { "property_id": "p1_birth_date", "property_value": "1985-06-15" } ``` - **integer** – a whole number: ```json { "property_id": "p1_visit_count", "property_value": 42 } ``` - **float** – a decimal number: ```json { "property_id": "p1_average_spend", "property_value": 149.90 } ``` - **enum** – a single-item array containing a PropertyItem object: ```json { "property_id": "p1_favourite_color", "property_value": [ { "id": "86e05affc7a7abefcd513ab400", "name": "Blue", "resource_record_id": null, "state": 1 } ] } ``` - **multiselect** – a multi-item array of PropertyItem objects: ```json { "property_id": "p1_favourite_color", "property_value": [ { "id": "86e05affc7a7abefcd513ab400", "name": "Blue", "resource_record_id": null, "state": 1 }, { "id": "81eaeea13b8984a169c490a325", "name": "Green", "resource_record_id": null, "state": 1 } ] } ``` - **custom data type** – the format depends on the specific data type configuration. For example, a serialized JSON object: ```json { "property_id": "p1_address", "property_value": "{\"street\":\"Main St\",\"city\":\"Prague\"}" } ```
        - string
        - number
        - integer
        - boolean
        - unknown[]
          - unknown
        - object
      - `last_change` string — Date and time of the last change. *(YYYY-MM-DD HH:MM:SS)*
    - `prices` Price[]
      - `currency_id` string, required — The unique ID of the currency. [GET /currencies](https://carecloud.readme.io/reference/getcurrencies)
      - `value` number, float, required — Price of the product
    - `tags` Tag[] — List of tags assigned to the product.
      - `tag_id` string — The unique ID of the tag.
      - `name` string — Name of the tag in language from the HTTP header.
      - `text_id` string — Text ID of the tag.
      - `state` 0 | 1 | 2 — State of the tag. *Possible values are: 0 - deleted / 1 - active / 2 - non active*
      - `last_change` string — Date and time of the last change. *(YYYY-MM-DD HH:MM:SS)*
    - `state` 0 | 1 — State of the product. If not set, the product is synchronized as active(`state=1`). *Possible values are: 0 - deleted / 1 - active*
  - `error_processing` 1 | 2 — The parameter describes the batch method behavior in case of error occurs. *Possible values are: 1 - It returns the first error found and rollback all previous changes (this is also the default behavior if the parameter is not set) / 2 - It creates all valid records and creates an error report from failed attempts.*

## Response `204`

No Content

## Other responses

- `400` — Bad input parameter. The response body's `error.error_data.invalid_params[]` array lists the parameters that caused the failure, each carrying a `reason` code. See the `BadRequestErrorBody` schema for the generic reason taxonomy. Operations with domain-specific business rules document additional reasons at the operation level.
- `401` — The client has invalid credentials or auth token.
- `403` — The client does not exist or the client tried to access an unauthorized property or resource.
- `404` — The resource was not found.
- `405` — The resource does not support the specified HTTP method.
- `429` — Too many requests - more than the resource limit.
- `500` — Server is not working as expected.
- `503` — Temporary state when the service is temporarily unavailable, overloaded or there is a maintenance window.

---

[API](https://skmtc.net/crmcarecloud/apis/rest-api-reference.md) · [All operations](https://skmtc.net/crmcarecloud/apis/rest-api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/crmcarecloud/rest-api-reference/revisions/329c06dbf8d9/schema)
