For AI agents: markdown of this page — /docs-content-en/entities/shipment-items/batch.md documentation index — /llms.txt

Batch operations on shipment items

POST /v1/shipment-items/batch

Create, update, delete or read shipment items in bulk with one request — up to 500 items per write and up to 50 calls per read. This is a dedicated endpoint for this entity, not to be confused with the universal batch, which combines operations on different entities and is limited to 50 calls.

Request fields (body)

Field Type Required Description
action string yes Batch operation: create, update, delete for writes, list, get for reads. One request performs one operation
items array yes for create and update List of items, up to 500
items[].orderDeliveryId number yes for create Shipment ID. List: GET /v1/shipments. Not passed in update — the field is read-only
items[].basketId number yes for create ID of a basket item of the same order. List: GET /v1/basket-items. Not passed in update — the field is read-only
items[].quantity number yes Product quantity in the shipment; a fractional value is stored without rounding. Required both in create and in every update item. An update item without quantity does not reject the batch — it fails inside a 200 response
items[].xmlId string no External code
items[].id number yes for update Shipment item ID. List: GET /v1/shipment-items
ids number[] yes for delete IDs of the shipment items to delete, up to 500. List: GET /v1/shipment-items
calls array yes for list and get List of read calls, up to 50. Each call is an object { "params": { … } }
calls[].params object yes For list — the item list parameters: filter, select, limit, offset. For get — { "id": 1363 }

The field set of an items element matches the body of POST /v1/shipment-items and PATCH /v1/shipment-items/:id. The full list of item fields is in GET /v1/shipment-items/fields.

The create body is in the "Examples" section. Bodies of the other operations:

  • update — { "action": "update", "items": [{ "id": 1363, "quantity": 0.75 }] }
  • delete — { "action": "delete", "ids": [1363] }
  • list — { "action": "list", "calls": [{ "params": { "filter": { "orderDeliveryId": 985 }, "limit": 50 } }] }
  • get — { "action": "get", "calls": [{ "params": { "id": 1363 } }] }

Examples

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/shipment-items/batch" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "create",
    "items": [
      { "orderDeliveryId": 1215, "basketId": 1387, "quantity": 0.5 }
    ]
  }'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/shipment-items/batch" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "create",
    "items": [
      { "orderDeliveryId": 1215, "basketId": 1387, "quantity": 0.5 }
    ]
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/shipment-items/batch', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    action: 'create',
    items: [
      { orderDeliveryId: 1215, basketId: 1387, quantity: 0.5 },
    ],
  }),
})

const { data } = await res.json()
data.results.forEach((item) => {
  if (item.success) console.log(`#${item.index} → id=${item.id}`)
  else console.log(`#${item.index} → error: ${item.error} ${item.message}`)
})

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/shipment-items/batch', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    action: 'create',
    items: [
      { orderDeliveryId: 1215, basketId: 1387, quantity: 0.5 },
    ],
  }),
})

const { data } = await res.json()

Response fields

The shape of data depends on the operation. For create, update and delete:

Field Type Description
success boolean Always true if the request passed validation as a whole. The result of each item is in data.results[i].success
data.results array Array of results in the same order as the request's items or ids
data.results[].index number Item index, starting from 0
data.results[].success boolean Result of this operation
data.results[].id number ID of the shipment item — created, updated or deleted. Absent in a failed item
data.results[].error string Error code of a failed item, for example 201250000001 for a repeated basketId + orderDeliveryId pair
data.results[].message string Error text of a failed item
data.summary.total number Total items processed
data.summary.succeeded number How many succeeded
data.summary.failed number How many failed

For list and get, the data field is an array of results in the order of calls, not an object with results. Each element carries either data or error. Here the error code is in the error object as error.code, while for writes it is a string in data.results[].error:

Field Type Description
success boolean Always true if the request passed validation as a whole
data[].data array | object | null For list — an array of items, for get — an item object or null. Item fields — Shipment item fields. With select, an item contains only the listed fields
data[].total number list only — number of items matching the call's filter
data[].hasMore boolean list only — whether there are items beyond limit and offset
data[].error.code string Error code of a failed call: CALL_FAILED for a non-existent id, INVALID_PARAMS for a non-integer id, a filter validation code for an invalid filter, for example UNKNOWN_FILTER_FIELD
data[].error.message string Error text of a failed call

Response example

action: create — the item is created:

JSON
{
  "success": true,
  "data": {
    "results": [
      { "index": 0, "success": true, "id": 1363 }
    ],
    "summary": { "total": 1, "succeeded": 1, "failed": 0 }
  }
}

action: create — the second item repeated the basketId + orderDeliveryId pair of the first one and failed, while the top-level success stayed true:

JSON
{
  "success": true,
  "data": {
    "results": [
      { "index": 0, "success": true, "id": 1361 },
      {
        "index": 1,
        "success": false,
        "error": "201250000001",
        "message": "Duplicate entry for key [basketId, orderDeliveryId]"
      }
    ],
    "summary": { "total": 2, "succeeded": 1, "failed": 1 }
  }
}

action: list — two calls for shipments 975 and 985 with the filter { "orderDeliveryId": { "$in": [975, 985] } }: the first with select: ["id", "orderDeliveryId", "quantity"], the second with limit: 1 and offset: 1:

JSON
{
  "success": true,
  "data": [
    {
      "data": [
        { "id": 875, "orderDeliveryId": 975, "quantity": 1 },
        { "id": 885, "orderDeliveryId": 985, "quantity": 10 },
        { "id": 887, "orderDeliveryId": 985, "quantity": 5 }
      ],
      "total": 3,
      "hasMore": false
    },
    {
      "data": [
        {
          "basketId": 953,
          "dateInsert": "2025-03-03T22:02:39.000Z",
          "id": 885,
          "orderDeliveryId": 985,
          "quantity": 10,
          "reservedQuantity": 0,
          "xmlId": "bx_67c618efc3256"
        }
      ],
      "total": 3,
      "hasMore": true
    }
  ]
}

Error response example

400 — a create item lacks a required field, the whole batch is rejected:

JSON
{
  "success": false,
  "error": {
    "code": "BATCH_ITEM_VALIDATION",
    "message": "Item at index 0: field 'basketId' is required to create shipmentItem"
  }
}

Errors

HTTP Code Description
400 INVALID_BATCH_ACTION action is not passed or is not one of the allowed operations — the list comes in the error text
400 BATCH_ITEM_VALIDATION items, ids or calls is empty or not an array, or an items element is not an object
400 BATCH_ITEM_VALIDATION A create item lacks orderDeliveryId, basketId or quantity, or a read-only field is passed: id, dateInsert, reservedQuantity
400 BATCH_ITEM_VALIDATION An update item lacks id, has no field other than id, or a read-only field is passed: orderDeliveryId, basketId
400 BATCH_ITEM_VALIDATION A field value has the wrong type, for example an object in quantity — the message names the field and the expected type
400 BATCH_ITEM_VALIDATION An ID in ids or items[].id is not a non-negative integer, for example "1.5"
400 BATCH_LIMIT_EXCEEDED More than 500 elements in items or ids, or more than 50 calls in calls
403 SCOPE_DENIED The API key lacks the sale scope
403 WRITE_BLOCKED_READONLY_KEY create, update or delete with a read-only key — the batch is not executed
403 MANAGEMENT_KEY_NO_ENTITY_ACCESS Management key: entity sections are not available to it, a personal key or an OAuth application key is required
401 MISSING_API_KEY The X-Api-Key header is not passed
401 TOKEN_MISSING The API key has no configured tokens
429 RATE_LIMITED Rate limit exceeded: 30 requests per minute per portal (a batch costs more than a plain read), all API keys of the portal share one limit. The exact value arrives in the x-ratelimit-limit header (the cap is divided across replicas). Retry after the delay in the Retry-After header

A 400 response means the whole batch is rejected before any write. Errors of individual items come inside a 200 response: for writes — in data.results[i] as the error and message fields, for reads — in data[i].error. This is how, for example, an update item without quantity fails — with the error "Required fields: quantity".

Full list of common API errors — Errors.

Known specifics

An item of a system shipment is returned as null by get, and update on it fails. Unlike the single GET /v1/shipment-items/:id, which responds with 404, a get call in the batch returns { "data": null } without an error. An update element for such an item fails, just like the single PATCH, while the other items of the batch continue to be processed. For what a system shipment is, see Shipment items.

See also