> ## Documentation Index
> Fetch the complete documentation index at: https://docs.1unic.com/odatav4/llms.txt
> Use this file to discover all available pages before exploring further.

# $batch

> Несколько операций одним запросом: multipart/mixed и JSON batch, транзакции, ссылки Content-ID

`standard.odata` не поддерживает `$batch` (отвечает `501`), поэтому поведение здесь задаёт спецификация OData v4 и 4.01.

## Адрес и форматы

`POST …/v4/$batch` работает на обоих сервисах. На `odatat` токен передаётся в заголовке, в адресе или в пути `…/t/<токен>/v4/$batch`.

| Формат | `Content-Type` запроса | Ответ |
| - | - | - |
| OData 4.0 | `multipart/mixed; boundary=…` | `multipart/mixed; boundary=batchresponse_…` |
| OData 4.01, JSON batch | `application/json`, тело `{"requests": [...]}` | `application/json`, тело `{"responses": [...]}`. JSON-тело операции встраивается объектом |

| Ошибка | Ответ |
| - | - |
| Иной `Content-Type` | `415` |
| Испорченное тело или пакет без операций | `400` |
| Другой метод на `$batch` | `405` с `Allow` |
| JSON batch с `OData-MaxVersion` ниже 4.01 | `400`. Клиенту OData 4.0 нужен `multipart/mixed` |

Вход выполняется один раз на пакет. Все операции идут от того же субъекта и профиля, тем же порядком, что одиночные запросы. В пакете допустимы:

* чтение, `$count`, `$metadata`, служебный документ;
* создание, изменение и удаление;
* наборы движений;
* `Post` и `Unpost`.

Адрес операции может быть относительным к корню сервиса, абсолютным или от корня хоста. Адрес с сегментами `.` или `..` (в том числе закодированными) и абсолютный адрес чужого хоста дают `400` у этой операции.

## Наборы изменений

Набор изменений (`changeset` в multipart, `atomicityGroup` в JSON) выполняется **одной транзакцией 1С**, проведение внутри разрешено. Ошибка любой операции откатывает весь набор:

* в multipart вместо набора приходит один ответ с ошибкой;
* в JSON ошибку получает операция, на которой всё сорвалось, а остальные операции группы — `424`.

`GET` внутри набора изменений даёт `400` всему пакету ещё до выполнения.

**Ссылки на созданное.** `$<Content-ID>` объекта, созданного в наборе, подставляется:

* в начало адреса следующей операции: `$1`, `$1/Post`, `$1/Товары`;
* в значения `…@odata.bind` тела: `"Parent@odata.bind": "$1"`.

Основа подстановки — заголовок `Location` ответа `201`. Ключ подставляется в кодировке URL, тело — значением JSON, поэтому внедрение в адрес невозможно. Ссылка действует внутри своего набора изменений, а в JSON batch — ещё и на операцию или группу из `dependsOn`. Иначе ответ — `400`.

## Ошибки вне наборов

По умолчанию пакет останавливается на первой ошибке: выполненное остаётся, остальные операции не выполняются. С заголовком `Prefer: odata.continue-on-error` выполняются все операции, у каждой свой ответ, а в ответе есть `Preference-Applied: odata.continue-on-error`.

Асинхронная обработка (`Prefer: respond-async`) не поддерживается.

## Примеры

Создание документа и его проведение одной транзакцией:

<Tabs>
  <Tab title="multipart/mixed">
    ```http theme={null}
    POST /base/hs/odata/v4/$batch HTTP/1.1
    Content-Type: multipart/mixed; boundary=batch_1

    --batch_1
    Content-Type: multipart/mixed; boundary=changeset_1

    --changeset_1
    Content-Type: application/http
    Content-Transfer-Encoding: binary
    Content-ID: 1

    POST Document_РеализацияТоваровУслуг HTTP/1.1
    Content-Type: application/json

    {"Date":"2026-10-01T12:00:00","Контрагент_Key":"…","Товары":[{"Номенклатура_Key":"…","Количество":2,"Цена":150}]}
    --changeset_1
    Content-Type: application/http
    Content-Transfer-Encoding: binary
    Content-ID: 2

    POST $1/Post HTTP/1.1
    Content-Type: application/json

    {}
    --changeset_1--
    --batch_1
    Content-Type: application/http
    Content-Transfer-Encoding: binary

    GET Catalog_Контрагенты?$top=1&$select=Description HTTP/1.1


    --batch_1--
    ```
  </Tab>

  <Tab title="JSON batch">
    ```http theme={null}
    POST /base/hs/odata/v4/$batch HTTP/1.1
    Content-Type: application/json
    OData-MaxVersion: 4.01

    {
      "requests": [
        {
          "id": "1", "atomicityGroup": "g1",
          "method": "POST", "url": "Document_РеализацияТоваровУслуг",
          "headers": { "content-type": "application/json" },
          "body": { "Date": "2026-10-01T12:00:00", "Контрагент_Key": "…",
                    "Товары": [ { "Номенклатура_Key": "…", "Количество": 2, "Цена": 150 } ] }
        },
        {
          "id": "2", "atomicityGroup": "g1", "dependsOn": ["1"],
          "method": "POST", "url": "$1/Post"
        },
        {
          "id": "3", "method": "GET", "url": "Catalog_Контрагенты?$top=1&$select=Description"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Ответ JSON">
    ```json theme={null}
    {
      "responses": [
        { "id": "1", "atomicityGroup": "g1", "status": 201,
          "headers": { "Location": "https://server/base/hs/odata/v4/Document_РеализацияТоваровУслуг(guid'…')" },
          "body": { "Ref_Key": "…", "Number": "0000-000123", "Posted": false } },
        { "id": "2", "atomicityGroup": "g1", "status": 204 },
        { "id": "3", "status": 200,
          "body": { "value": [ { "Description": "ООО «Ромашка»" } ] } }
      ]
    }
    ```
  </Tab>
</Tabs>

## Лимиты

Лимиты проверяются до выполнения пакета.

| Лимит | По умолчанию | Превышение |
| - | - | - |
| «Наибольший размер `$batch`, МБ» | 10 | `413` до разбора |
| «Наибольшее число операций в `$batch`» | 100 | `400` с фактом. Лимит профиля «Операций в `$batch`» действует, если он строже |

Обе настройки находятся на вкладке «Запись». У `multipart/mixed` части верхнего уровня считаются до разбора, поэтому пакет с заведомо лишними частями отклоняется сразу.

**Частота.** Правила частоты профиля считают каждую операцию отдельным запросом. Если лимита не хватает на весь пакет, весь пакет получает `429` с `Retry-After`. Отклонённый пакет всё равно расходует лимит на все свои операции, поэтому повторяйте его после `Retry-After`.

## Журнал

Журнал запросов пишет сам `POST /v4/$batch` (статус, общая длительность, число операций) и каждую операцию по обычным правилам уровня журнала. Записи одного пакета объединяет поле `Пакет`. На уровне «Только запись» пакет из одних чтений не пишется.

<Warning>
  Если запись журнала после выполнения пакета сорвётся из-за сбоя платформы (см. [Известные ограничения](/odatav4/reference/limitations)), клиент получит `500` на весь пакет, хотя операции уже зафиксированы. Чтобы повтор не создавал дубли, передавайте `Ref_Key` создаваемых объектов с `If-None-Match: *` или `Repeatability-Request-ID` в операциях. Результат сверяйте по `Content-ID` или `id` операций.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.