# Batch add or update items asynchronously

- Operation ID: `addItemsBatchAsync`
- HTTP method: `POST`
- Path: `/catalogs/v1/async/bags/{catalogId}/items`
- [Human-readable API reference](https://hub.synerise.com/api-reference/asset-management#operation/addItemsBatchAsync)

## Self-contained OpenAPI method

The fenced document below contains this method's documentation and all of its local references. It is self-contained; no category or master specification fetch is required.

```yaml
openapi: 3.0.0
info:
  title: Synerise Public API
  version: 1.9.5
paths:
  /catalogs/v1/async/bags/{catalogId}/items:
    post:
      tags:
        - Catalogs
      summary: Batch add or update items asynchronously
      description: |
        Add a number of items asynchronously at once. If an item already exists, it's entirely overwritten by the item you send.

        Asynchronous requests are processed according to the time they reach the service.  
        This means that requests to synchronous endpoints (for example, [`/bags/{catalogId}/items/{itemId}`](#operation/updateItem) may overwrite asynchronous operations which were sent earlier and queued due to high traffic.  
        This behavior also applies to requests from Automation and AI feed synchronization, which use the asynchronous mechanism.

        The request body can't exceed 256KB.


        ---

        **API consumers:** <a href="/api-reference/authorization?tag=Authorization&amp;operationId=userLogin" target="_blank" rel="noopener">Synerise User</a>, <a href="/api-reference/authorization?tag=Authorization&amp;operationId=profileLogin" target="_blank" rel="noopener">Workspace (Business Profile)</a>

        **API key permissions required (at least one):** `CATALOGS_ITEM_BATCH_CREATE`, `CATALOGS_ITEM_BATCH_CATALOG_CREATE`

        **User role permission required:** `assets_catalogs: create`
      operationId: addItemsBatchAsync
      security:
        - JWT: []
        - BasicAuth: []
      parameters:
        - in: path
          name: catalogId
          description: ID of the catalog
          required: true
          schema:
            type: integer
      requestBody:
        description: JSON object with any number of key/value pairs
        required: true
        content:
          application/json:
            schema:
              type: array
              maxItems: 200
              items:
                type: object
                required:
                  - itemKey
                  - value
                properties:
                  itemKey:
                    type: string
                    description: |
                      The value of the unique key of the item.

                      Slashes (`/`) are not allowed in the value.

                      In the Synerise Portal, this value is saved under **Primary key**.
                    example: sku1357
                  value:
                    type: object
                    description: Properties of the item. Can be an empty object.
                    additionalProperties:
                      type: string
                      description: Key:value data
                    example:
                      itemCategory: smartphone
                      itemColor: blue
      responses:
        "204":
          description: Operation added to queue
      x-snr-doc-urls:
        - /api-reference/data-management#tag/Catalogs/operation/addItemsBatchAsync
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |-
            curl --request POST \
              --url https://api.synerise.com/catalogs/v1/async/bags/%7BcatalogId%7D/items \
              --header 'Authorization: Basic REPLACE_BASIC_AUTH' \
              --header 'content-type: application/json' \
              --data '[{"itemKey":"sku1357","value":{"itemCategory":"smartphone","itemColor":"blue"}}]'
        - lang: Python
          label: Python
          source: |-
            import http.client

            conn = http.client.HTTPSConnection("api.synerise.com")

            payload = "[{\"itemKey\":\"sku1357\",\"value\":{\"itemCategory\":\"smartphone\",\"itemColor\":\"blue\"}}]"

            headers = {
                'Authorization': "Basic REPLACE_BASIC_AUTH",
                'content-type': "application/json"
                }

            conn.request("POST", "/catalogs/v1/async/bags/%7BcatalogId%7D/items", payload, headers)

            res = conn.getresponse()
            data = res.read()

            print(data.decode("utf-8"))
        - lang: JavaScript
          label: JavaScript
          source: |-
            const data = JSON.stringify([
              {
                "itemKey": "sku1357",
                "value": {
                  "itemCategory": "smartphone",
                  "itemColor": "blue"
                }
              }
            ]);

            const xhr = new XMLHttpRequest();
            xhr.withCredentials = true;

            xhr.addEventListener("readystatechange", function () {
              if (this.readyState === this.DONE) {
                console.log(this.responseText);
              }
            });

            xhr.open("POST", "https://api.synerise.com/catalogs/v1/async/bags/%7BcatalogId%7D/items");
            xhr.setRequestHeader("Authorization", "Basic REPLACE_BASIC_AUTH");
            xhr.setRequestHeader("content-type", "application/json");

            xhr.send(data);
        - lang: Node.js
          label: Node.js
          source: |-
            const http = require("https");

            const options = {
              "method": "POST",
              "hostname": "api.synerise.com",
              "port": null,
              "path": "/catalogs/v1/async/bags/%7BcatalogId%7D/items",
              "headers": {
                "Authorization": "Basic REPLACE_BASIC_AUTH",
                "content-type": "application/json"
              }
            };

            const req = http.request(options, function (res) {
              const chunks = [];

              res.on("data", function (chunk) {
                chunks.push(chunk);
              });

              res.on("end", function () {
                const body = Buffer.concat(chunks);
                console.log(body.toString());
              });
            });

            req.write(JSON.stringify([{itemKey: 'sku1357', value: {itemCategory: 'smartphone', itemColor: 'blue'}}]));
            req.end();
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $request = new HttpRequest();
            $request->setUrl('https://api.synerise.com/catalogs/v1/async/bags/%7BcatalogId%7D/items');
            $request->setMethod(HTTP_METH_POST);

            $request->setHeaders([
              'Authorization' => 'Basic REPLACE_BASIC_AUTH',
              'content-type' => 'application/json'
            ]);

            $request->setBody('[{"itemKey":"sku1357","value":{"itemCategory":"smartphone","itemColor":"blue"}}]');

            try {
              $response = $request->send();

              echo $response->getBody();
            } catch (HttpException $ex) {
              echo $ex;
            }
        - lang: Java
          label: Java
          source: |-
            HttpResponse<String> response = Unirest.post("https://api.synerise.com/catalogs/v1/async/bags/%7BcatalogId%7D/items")
              .header("Authorization", "Basic REPLACE_BASIC_AUTH")
              .header("content-type", "application/json")
              .body("[{\"itemKey\":\"sku1357\",\"value\":{\"itemCategory\":\"smartphone\",\"itemColor\":\"blue\"}}]")
              .asString();
servers:
  - url: https://api.synerise.com
    description: Microsoft Azure EU
  - url: https://api.azu.synerise.com
    description: Microsoft Azure USA
  - url: https://api.geb.synerise.com
    description: Google Cloud Platform
tags:
  - name: Catalogs
components:
  securitySchemes:
    JWT:
      type: http
      scheme: bearer
      description: |
        Synerise uses [JSON Web Token (JWT)](https://jwt.io/) as the authorization method.

        The token is generated by the *auth/login* endpoints.

        You need to include it in the `Authorization` header of your requests, with a `Bearer` prefix.


        By default, the token is valid for **one week** (see [workspace settings](https://hub.synerise.com/docs/settings/tool/iam-for-apps/general/#jwt-lifetime)).  
        You can request a refreshed key for the session by using the *auth/refresh* endpoint **before** the current token expires.


        You can verify your JWT signature by using the [public key](https://api.synerise.com/v4/public.pem).


        See Developer Guides on JWT API authentication for:
        - [profiles](https://hub.synerise.com/developers/api/api-authorization/client-login/);
        - [workspaces](https://hub.synerise.com/developers/api/api-authorization/workspace-login/#api-authentication-with-jwt);
        - [users](https://hub.synerise.com/developers/api/api-authorization/user-login/).
    BasicAuth:
      type: http
      scheme: basic
      description: |
        Basic authentication with login (workspace GUID) and password (workspace API key) encoded with Base64 and sent in the `Authorization` header. **Must be enabled in the settings of the API key**.

        <span style="color:red">This is less secure than JWTs.</span> Limit the API key permissions to only those that you need. Consider API key rotation and other security measures.

        You can still use JWTs from the same API key when basic authentication is enabled.

        For details, see ["Workspace authentication"](https://hub.synerise.com/jwt-or-basic/#basic-api-authentication-with-api-keys).
```
