Товары

Каждая операция ниже сгенерирована из OpenAPI v2 и содержит параметры, поля запроса, поля ответа, ошибки и примеры.

Документы, партии и фактические остатки

stocks.physical / stocks.aggregateМассивы складских итогов: warehouse_id, warehouse_name, stockTotal, stockReserved, stockAvailable. stocks.available_by_warehouse — объект с ключами ID складов. Не воспринимайте эти три поля как одинаковую структуру.
GET /api/v2/products/{id}/stock-lotsФизически размещённый товар по партиям и датам. Резерв без конкретной партии нельзя вычитать из произвольно выбранной партии. Сверяйте единицы количества и склад в ответе.
accepted_lotsФактические партии приёмки. Ожидание, фактическая приёмка и размещение — разные показатели. Их расхождение само по себе не означает ошибку API.
requested_lot / fulfillment_lotsВ строке заказа requested_lot описывает требование, fulfillment_lots — фактический подбор; picked_quantity — подобранное количество. Несколько фактических партий нельзя сводить к одной дате.
movement_type / operationПодбор может давать пару снятия резерва и физического списания. Различайте operation; не считайте обе строки двумя списаниями. Перемещения объединяются через movement_group_id; transfer_kind уточняет вид.
GET /api/v2/closed-boxesРеальные закрытые короба с уникальным SSCC: balance=1, balance_unit=box. Штрихкод типа упаковки из products не является уникальным SSCC. Открытые, отгруженные и только ожидаемые короба не входят в текущий закрытый остаток.
acceptance_dateПри создании обычной/возвратной приёмки (type_id=1/2) текущий обработчик ставит серверное now(), даже если передана acceptance_date. Изменение существующей приёмки принимает дату. Создание type_id=3 использует отдельный cross-dock сервис. created_at/updated_at — технические метки, не дата документа.
LifecycleОтмена приёмки — отдельная команда cancel с проверкой состояния; она не равна удалению. Для строк используйте /lines, а устаревшие /offers сохраняются для совместимости. Подробные ограничения смотрите у операции.

Товары

GET /api/v2/products

Получить список товаров

operationIdlistProducts
РазделТовары
БезопасностьbearerAuth

Возвращает товары, видимые аутентифицированному аккаунту. Используйте описанные query parameters для фильтрации, сортировки и пагинации.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Unknown read parameters are ignored. per_page is silently capped; use meta.per_page. Date-only boundaries follow the installation's stored calendar dates; ISO timestamps are serialized in UTC. The default general API limit is 600/minute; a user-specific override may apply. Its bucket is shared by authenticated user, not by shop/domain; Retry-After is returned on throttling.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Unknown read parameters are ignored. per_page is silently capped; use meta.per_page. Date-only boundaries follow the installation's stored calendar dates; ISO timestamps are serialized in UTC. The default general API limit is 600/minute; a user-specific override may apply. Its bucket is shared by authenticated user, not by shop/domain; Retry-After is returned on throttling.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Unknown read parameters are ignored. per_page is silently capped; use meta.per_page. Date-only boundaries follow the installation's stored calendar dates; ISO timestamps are serialized in UTC. The default general API limit is 600/minute; a user-specific override may apply. Its bucket is shared by authenticated user, not by shop/domain; Retry-After is returned on throttling.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Unknown read parameters are ignored. per_page is silently capped; use meta.per_page. Date-only boundaries follow the installation's stored calendar dates; ISO timestamps are serialized in UTC. The default general API limit is 600/minute; a user-specific override may apply. Its bucket is shared by authenticated user, not by shop/domain; Retry-After is returned on throttling.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Unknown read parameters are ignored. per_page is silently capped; use meta.per_page. Date-only boundaries follow the installation's stored calendar dates; ISO timestamps are serialized in UTC. The default general API limit is 600/minute; a user-specific override may apply. Its bucket is shared by authenticated user, not by shop/domain; Retry-After is returned on throttling.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Unknown read parameters are ignored. per_page is silently capped; use meta.per_page. Date-only boundaries follow the installation's stored calendar dates; ISO timestamps are serialized in UTC. The default general API limit is 600/minute; a user-specific override may apply. Its bucket is shared by authenticated user, not by shop/domain; Retry-After is returned on throttling.

Пример HTTP-запроса (cURL)

Подставьте свой сервер и токен. ID из примера замените реальными доступными ID. Для тела запроса сохраните подходящий JSON из раздела ниже в request.json; перед отправкой замените демонстрационные значения. Заголовок Idempotency-Key использует ключ одной логической операции.

curl --globoff --request GET "${NWMS_BASE_URL}/api/v2/products" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${NWMS_TOKEN}"

Параметры

Имя Где Обязательное Тип Style Explode Ограничения Описание Пример
page query нет integer:int64 form true min: 1 Номер страницы. Этот фильтр также можно передать как filter[page], если это поддерживает Laravel query adapter. 1
per_page query нет integer:int64 form true min: 1
max: 250
Количество записей на странице. По умолчанию 50; максимум 250. Этот фильтр также можно передать как filter[per_page], если это поддерживает Laravel query adapter. 50
sort query нет string form false pattern: ^-?[A-Za-z0-9_]+(,-?[A-Za-z0-9_]+)*$ Поля сортировки через запятую. Префикс - означает сортировку по убыванию. Допустимые поля: id, name, article, sku, price, created_at, updated_at, inventory_updated_at. По умолчанию: -id. Этот фильтр также можно передать как filter[sort], если это поддерживает Laravel query adapter. "-id"
id query нет integer:int64 form true min: 1 Фильтр по id с точным совпадением. Этот фильтр также можно передать как filter[id], если это поддерживает Laravel query adapter. 1001
external_id query нет string form true Фильтр по external_id с точным совпадением. Этот фильтр также можно передать как filter[external_id], если это поддерживает Laravel query adapter. "EXT-10045"
shop_id query нет integer:int64 form true min: 1 Фильтр по shop_id с точным совпадением. Этот фильтр также можно передать как filter[shop_id], если это поддерживает Laravel query adapter. 12
status_id query нет ProductStatusId form true Фильтр по status_id с точным совпадением. Этот фильтр также можно передать как filter[status_id], если это поддерживает Laravel query adapter.
type_id query нет integer:int64 form true min: 1 Фильтр по type_id с точным совпадением. Этот фильтр также можно передать как filter[type_id], если это поддерживает Laravel query adapter. 1
package_kind query нет string form true Фильтр по package_kind с точным совпадением. Этот фильтр также можно передать как filter[package_kind], если это поддерживает Laravel query adapter. "unit"
parent_product_id query нет integer:int64 form true min: 1 Фильтр по parent_product_id с точным совпадением. Этот фильтр также можно передать как filter[parent_product_id], если это поддерживает Laravel query adapter. 1200
base_product_id query нет integer:int64 form true min: 1 Фильтр по base_product_id с точным совпадением. Этот фильтр также можно передать как filter[base_product_id], если это поддерживает Laravel query adapter. 1200
datamatrix_required query нет boolean form true Фильтр по datamatrix_required с точным совпадением. Этот фильтр также можно передать как filter[datamatrix_required], если это поддерживает Laravel query adapter. false
expiration_required query нет boolean form true Фильтр по expiration_required с точным совпадением. Этот фильтр также можно передать как filter[expiration_required], если это поддерживает Laravel query adapter. false
name query нет string form true Фильтр по name с частичным текстовым совпадением. Этот фильтр также можно передать как filter[name], если это поддерживает Laravel query adapter. "Coffee"
article query нет string form true Фильтр по article с частичным текстовым совпадением. Этот фильтр также можно передать как filter[article], если это поддерживает Laravel query adapter. "ART-001245"
sku query нет string form true Фильтр по sku с частичным текстовым совпадением. Этот фильтр также можно передать как filter[sku], если это поддерживает Laravel query adapter. "SKU-001245"
comment query нет string form true Фильтр по comment с частичным текстовым совпадением. Этот фильтр также можно передать как filter[comment], если это поддерживает Laravel query adapter. "Priority"
created_at_from query нет string:date form true Нижняя включительная граница даты для created_at. Этот фильтр также можно передать как filter[created_at_from], если это поддерживает Laravel query adapter. "2026-07-14"
created_at_to query нет string:date form true Верхняя включительная граница даты для created_at. Этот фильтр также можно передать как filter[created_at_to], если это поддерживает Laravel query adapter. "2026-07-14"
updated_at_from query нет string:date form true Нижняя включительная граница даты для updated_at. Этот фильтр также можно передать как filter[updated_at_from], если это поддерживает Laravel query adapter. "2026-07-14"
updated_at_to query нет string:date form true Верхняя включительная граница даты для updated_at. Этот фильтр также можно передать как filter[updated_at_to], если это поддерживает Laravel query adapter. "2026-07-14"
inventory_updated_at_from query нет string:date form true Нижняя включительная граница даты для inventory_updated_at. Этот фильтр также можно передать как filter[inventory_updated_at_from], если это поддерживает Laravel query adapter. "2026-07-14"
inventory_updated_at_to query нет string:date form true Верхняя включительная граница даты для inventory_updated_at. Этот фильтр также можно передать как filter[inventory_updated_at_to], если это поддерживает Laravel query adapter. "2026-07-14"
price_from query нет number:float form true Нижняя включительная числовая граница для price. Этот фильтр также можно передать как filter[price_from], если это поддерживает Laravel query adapter. 19.99
price_to query нет number:float form true Верхняя включительная числовая граница для price. Этот фильтр также можно передать как filter[price_to], если это поддерживает Laravel query adapter. 19.99
estimated_price_from query нет number:float form true Нижняя включительная числовая граница для estimated_price. Этот фильтр также можно передать как filter[estimated_price_from], если это поддерживает Laravel query adapter. 19.99
estimated_price_to query нет number:float form true Верхняя включительная числовая граница для estimated_price. Этот фильтр также можно передать как filter[estimated_price_to], если это поддерживает Laravel query adapter. 19.99

Тело запроса

Тело запроса отсутствует.

Ответы

200 Successful response.

Successful response.

Поле Обязательное Тип Флаги Ограничения Описание Пример
data да array<Product>
data[] нет Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data[].id да integer:int64 readOnly min: 1 1001
data[].created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].external_id нет string | null "EXT-10045"
data[].shop_id нет integer:int64 | null min: 1 12
data[].domain_id нет integer:int64 | null min: 1 3
data[].status_id нет integer:int64 | null 1
data[].type_id нет integer:int64 | null 1
data[].name да string "Coffee 250g"
data[].article нет string | null "ART-001245"
data[].sku нет string | null "SKU-001245"
data[].price нет number:float | null 19.99
data[].estimated_price нет number:float | null 21.5
data[].image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data[].dimensions нет Dimensions
data[].dimensions.x нет number:float | null min: 0 105
data[].dimensions.y нет number:float | null min: 0 200
data[].dimensions.z нет number:float | null min: 0 32
data[].dimensions.unit да enum enum: mm "mm"
data[].weight нет Weight
data[].weight.value нет number:float | null min: 0 250
data[].weight.unit да enum enum: g "g"
data[].datamatrix_required да boolean false
data[].expiration_required да boolean true
data[].comment нет string | null "Keep dry"
data[].description нет string | null "Ground coffee package"
data[].inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].barcodes нет array<ProductBarcode>
data[].barcodes[] нет ProductBarcode
data[].barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data[].barcodes[].is_main да boolean true
data[].stocks нет ProductStocks
data[].stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data[].stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data[].stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.physical[].warehouse_id да integer:int64 min: 1 42
data[].stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.physical[].stockTotal да number:float 24.0
data[].stocks.physical[].stockReserved да number:float 6.0
data[].stocks.physical[].stockAvailable да number:float 18.0
data[].stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data[].stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data[].stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.aggregate[].stockTotal да number:float 24.0
data[].stocks.aggregate[].stockReserved да number:float 6.0
data[].stocks.aggregate[].stockAvailable да number:float 18.0
data[].package нет object | null
data[].package.kind нет string | null "unit"
data[].package.parent_product_id нет integer:int64 | null min: 1 1201
data[].package.base_product_id нет integer:int64 | null min: 1 1200
data[].package.multiplicity нет number:float | null min: 0 6
links да PaginationLinks
links.first да string:uri | null "https://betawms.ffcdek.ru/api/v2/orders?page=1"
links.last да string:uri | null "https://betawms.ffcdek.ru/api/v2/orders?page=2"
links.prev да string:uri | null
links.next да string:uri | null "https://betawms.ffcdek.ru/api/v2/orders?page=2"
meta да PaginationMeta
meta.api_version да enum enum: v2 "v2"
meta.current_page да integer:int32 min: 1 1
meta.from да integer:int32 | null min: 1 1
meta.last_page да integer:int32 min: 1 2
meta.path да string:uri "https://betawms.ffcdek.ru/api/v2/orders"
meta.per_page да integer:int32 min: 1 50
meta.to да integer:int32 | null min: 1 50
meta.total да integer:int32 min: 0 73

Примеры ответа

success

{
  "data": [
    {
      "id": 1201,
      "external_id": "EXT-10045",
      "shop_id": 12,
      "domain_id": 3,
      "status_id": 1,
      "type_id": 1,
      "name": "Coffee 250g",
      "article": "ART-001245",
      "sku": "SKU-001245",
      "price": 19.99,
      "estimated_price": 21.5,
      "image_url": "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg",
      "dimensions": {
        "x": 105,
        "y": 200,
        "z": 32,
        "unit": "mm"
      },
      "weight": {
        "value": 250,
        "unit": "g"
      },
      "datamatrix_required": false,
      "expiration_required": true,
      "comment": "Keep dry",
      "description": "Ground coffee package",
      "inventory_updated_at": "2026-07-14T08:30:00Z",
      "barcodes": [
        {
          "barcode": "4601234567890",
          "is_main": true
        }
      ],
      "stocks": {
        "available_by_warehouse": {
          "42": 18
        },
        "physical": [
          {
            "warehouse_id": 42,
            "warehouse_name": "Warehouse Sofia",
            "stockTotal": 24,
            "stockReserved": 6,
            "stockAvailable": 18
          }
        ],
        "aggregate": [
          {
            "warehouse_id": 42,
            "warehouse_name": "Warehouse Sofia",
            "stockTotal": 30,
            "stockReserved": 7,
            "stockAvailable": 23
          }
        ]
      },
      "package": {
        "kind": "unit",
        "parent_product_id": null,
        "base_product_id": null,
        "multiplicity": null
      },
      "created_at": "2026-07-14T09:00:00Z",
      "updated_at": "2026-07-14T09:30:00Z"
    }
  ],
  "links": {
    "first": "https://betawms.ffcdek.ru/api/v2/products?page=1",
    "last": "https://betawms.ffcdek.ru/api/v2/products?page=2",
    "prev": null,
    "next": "https://betawms.ffcdek.ru/api/v2/products?page=2"
  },
  "meta": {
    "api_version": "v2",
    "current_page": 1,
    "from": 1,
    "last_page": 2,
    "path": "https://betawms.ffcdek.ru/api/v2/products",
    "per_page": 50,
    "to": 50,
    "total": 73
  }
}

401 Требуется аутентификация

Unauthorized

Требуется аутентификация.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

AUTH_REQUIRED

{
  "message": "Authentication is required.",
  "error": "AUTH_REQUIRED"
}

403 Доступ запрещен

Forbidden

Аутентифицированному аккаунту запрещено выполнять это действие.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

FORBIDDEN

{
  "message": "The authenticated account is not allowed to perform this action.",
  "error": "FORBIDDEN"
}

429 Превышен лимит запросов

TooManyRequests

Превышен лимит запросов.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "Too Many Attempts."
error да string "RATE_LIMITED"

500 Внутренняя ошибка сервера

InternalServerError

Произошла непредвиденная ошибка сервера.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

INTERNAL_SERVER_ERROR

{
  "message": "An unexpected server error occurred.",
  "error": "INTERNAL_SERVER_ERROR"
}
POST /api/v2/products

Создать товар

operationIdcreateProducts
РазделТовары
БезопасностьbearerAuth

Creates one product or imports multiple products. Barcodes, dimensions, weights, marking requirements, expiration requirements, and package metadata are accepted in public v2 field names.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Optional type_id accepts integer codes 1 ordinary, 2 composite, 3 component, 4 consumable, 5 packaging. Omission preserves the existing/default type; explicit null, empty, fractional or unknown values are rejected. Types 2/3 require composites enabled in the shop and permission to manage composition, in addition to product create/update rights. Quant packaging and links, existing composition links and dependent warehouse documents can prevent a type transition. This field does not create or replace a composition. Product and component prices are independent. Each item commits separately: a later rule failure may leave earlier items applied. Read back affected products before retrying a failed bulk request.

Пример HTTP-запроса (cURL)

Подставьте свой сервер и токен. ID из примера замените реальными доступными ID. Для тела запроса сохраните подходящий JSON из раздела ниже в request.json; перед отправкой замените демонстрационные значения. Заголовок Idempotency-Key использует ключ одной логической операции.

curl --globoff --request POST "${NWMS_BASE_URL}/api/v2/products" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${NWMS_TOKEN}" \
  --header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
  --header "Content-Type: application/json" \
  --data-binary @request.json

Параметры

Имя Где Обязательное Тип Style Explode Ограничения Описание Пример
Idempotency-Key header нет string maxLength: 191 Опциональный ключ идемпотентности для write-запросов API v2. Успешные ответы 2xx/3xx повторяются для того же ключа и идентичного payload в течение одного дня. Тот же ключ с другим payload возвращает 409. "ord-create-20260714-001"

Тело запроса

BulkCreateProductsRequest обязательно

Поле Обязательное Тип Флаги Ограничения Описание Пример
data да CreateProductPayload
data да array<CreateProductPayload> minItems: 1

Примеры запроса

default

{
  "data": [
    {
      "external_id": "EXT-10045",
      "shop_id": 12,
      "name": "Coffee 250g",
      "barcodes": [
        {
          "barcode": "4601234567890",
          "is_main": true
        }
      ],
      "type_id": 3
    }
  ]
}

Ответы

201 Created.

Created.

Поле Обязательное Тип Флаги Ограничения Описание Пример
(root) нет ProductMutationResponse Запись одного товара возвращает ProductResponse; запись массива товаров возвращает ProductCollectionResponse в порядке входных успешно обработанных элементов.
data да Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data.id да integer:int64 readOnly min: 1 1001
data.created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.external_id нет string | null "EXT-10045"
data.shop_id нет integer:int64 | null min: 1 12
data.domain_id нет integer:int64 | null min: 1 3
data.status_id нет integer:int64 | null 1
data.type_id нет integer:int64 | null 1
data.name да string "Coffee 250g"
data.article нет string | null "ART-001245"
data.sku нет string | null "SKU-001245"
data.price нет number:float | null 19.99
data.estimated_price нет number:float | null 21.5
data.image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data.dimensions нет Dimensions
data.dimensions.x нет number:float | null min: 0 105
data.dimensions.y нет number:float | null min: 0 200
data.dimensions.z нет number:float | null min: 0 32
data.dimensions.unit да enum enum: mm "mm"
data.weight нет Weight
data.weight.value нет number:float | null min: 0 250
data.weight.unit да enum enum: g "g"
data.datamatrix_required да boolean false
data.expiration_required да boolean true
data.comment нет string | null "Keep dry"
data.description нет string | null "Ground coffee package"
data.inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.barcodes нет array<ProductBarcode>
data.barcodes[] нет ProductBarcode
data.barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data.barcodes[].is_main да boolean true
data.stocks нет ProductStocks
data.stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data.stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data.stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.physical[].warehouse_id да integer:int64 min: 1 42
data.stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.physical[].stockTotal да number:float 24.0
data.stocks.physical[].stockReserved да number:float 6.0
data.stocks.physical[].stockAvailable да number:float 18.0
data.stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data.stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data.stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.aggregate[].stockTotal да number:float 24.0
data.stocks.aggregate[].stockReserved да number:float 6.0
data.stocks.aggregate[].stockAvailable да number:float 18.0
data.package нет object | null
data.package.kind нет string | null "unit"
data.package.parent_product_id нет integer:int64 | null min: 1 1201
data.package.base_product_id нет integer:int64 | null min: 1 1200
data.package.multiplicity нет number:float | null min: 0 6
meta да ResponseMeta
meta.api_version да enum enum: v2 "v2"
meta.deleted нет boolean true
meta.id нет integer:int64 | null min: 1 1001
meta.command_replayed нет boolean True when an idempotent cross-dock command returned the original successful result. false
meta.crossdock_configuration нет object | null
meta.crossdock_configuration.physical_warehouse_id да integer:int64 min: 1 42
meta.crossdock_configuration.enabled да boolean true
meta.crossdock_configuration.process_version да string "direct_order_v1"
data да array<Product>
data[] нет Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data[].id да integer:int64 readOnly min: 1 1001
data[].created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].external_id нет string | null "EXT-10045"
data[].shop_id нет integer:int64 | null min: 1 12
data[].domain_id нет integer:int64 | null min: 1 3
data[].status_id нет integer:int64 | null 1
data[].type_id нет integer:int64 | null 1
data[].name да string "Coffee 250g"
data[].article нет string | null "ART-001245"
data[].sku нет string | null "SKU-001245"
data[].price нет number:float | null 19.99
data[].estimated_price нет number:float | null 21.5
data[].image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data[].dimensions нет Dimensions
data[].dimensions.x нет number:float | null min: 0 105
data[].dimensions.y нет number:float | null min: 0 200
data[].dimensions.z нет number:float | null min: 0 32
data[].dimensions.unit да enum enum: mm "mm"
data[].weight нет Weight
data[].weight.value нет number:float | null min: 0 250
data[].weight.unit да enum enum: g "g"
data[].datamatrix_required да boolean false
data[].expiration_required да boolean true
data[].comment нет string | null "Keep dry"
data[].description нет string | null "Ground coffee package"
data[].inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].barcodes нет array<ProductBarcode>
data[].barcodes[] нет ProductBarcode
data[].barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data[].barcodes[].is_main да boolean true
data[].stocks нет ProductStocks
data[].stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data[].stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data[].stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.physical[].warehouse_id да integer:int64 min: 1 42
data[].stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.physical[].stockTotal да number:float 24.0
data[].stocks.physical[].stockReserved да number:float 6.0
data[].stocks.physical[].stockAvailable да number:float 18.0
data[].stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data[].stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data[].stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.aggregate[].stockTotal да number:float 24.0
data[].stocks.aggregate[].stockReserved да number:float 6.0
data[].stocks.aggregate[].stockAvailable да number:float 18.0
data[].package нет object | null
data[].package.kind нет string | null "unit"
data[].package.parent_product_id нет integer:int64 | null min: 1 1201
data[].package.base_product_id нет integer:int64 | null min: 1 1200
data[].package.multiplicity нет number:float | null min: 0 6
meta да ResponseMeta
meta.api_version да enum enum: v2 "v2"
meta.deleted нет boolean true
meta.id нет integer:int64 | null min: 1 1001
meta.command_replayed нет boolean True when an idempotent cross-dock command returned the original successful result. false
meta.crossdock_configuration нет object | null
meta.crossdock_configuration.physical_warehouse_id да integer:int64 min: 1 42
meta.crossdock_configuration.enabled да boolean true
meta.crossdock_configuration.process_version да string "direct_order_v1"

Примеры ответа

success

{
  "data": {
    "id": 1201,
    "external_id": "EXT-10045",
    "shop_id": 12,
    "domain_id": 3,
    "status_id": 1,
    "type_id": 1,
    "name": "Coffee 250g",
    "article": "ART-001245",
    "sku": "SKU-001245",
    "price": 19.99,
    "estimated_price": 21.5,
    "image_url": "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg",
    "dimensions": {
      "x": 105,
      "y": 200,
      "z": 32,
      "unit": "mm"
    },
    "weight": {
      "value": 250,
      "unit": "g"
    },
    "datamatrix_required": false,
    "expiration_required": true,
    "comment": "Keep dry",
    "description": "Ground coffee package",
    "inventory_updated_at": "2026-07-14T08:30:00Z",
    "barcodes": [
      {
        "barcode": "4601234567890",
        "is_main": true
      }
    ],
    "stocks": {
      "available_by_warehouse": {
        "42": 18
      },
      "physical": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 24,
          "stockReserved": 6,
          "stockAvailable": 18
        }
      ],
      "aggregate": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 30,
          "stockReserved": 7,
          "stockAvailable": 23
        }
      ]
    },
    "package": {
      "kind": "unit",
      "parent_product_id": null,
      "base_product_id": null,
      "multiplicity": null
    },
    "created_at": "2026-07-14T09:00:00Z",
    "updated_at": "2026-07-14T09:30:00Z"
  },
  "meta": {
    "api_version": "v2"
  }
}

400 Некорректный запрос

BadRequest

Некорректный запрос.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

BAD_REQUEST

{
  "message": "Bad request.",
  "error": "BAD_REQUEST"
}

401 Требуется аутентификация

Unauthorized

Требуется аутентификация.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

AUTH_REQUIRED

{
  "message": "Authentication is required.",
  "error": "AUTH_REQUIRED"
}

403 Доступ запрещен

Forbidden

Аутентифицированному аккаунту запрещено выполнять это действие.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

FORBIDDEN

{
  "message": "The authenticated account is not allowed to perform this action.",
  "error": "FORBIDDEN"
}

409 Конфликт

Conflict

Запрос конфликтует с текущим состоянием ресурса или ключа идемпотентности.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

idempotencyConflict

{
  "message": "The idempotency key is already used with a different payload.",
  "error": "IDEMPOTENCY_KEY_CONFLICT"
}

422 Ошибка валидации

ValidationError

Ошибка валидации.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The given data was invalid."
error нет string "VALIDATION_ERROR"
errors да object {"warehouse_id":["The selected warehouse is invalid."]}

Примеры ответа

validationError

{
  "message": "The given data was invalid.",
  "error": "VALIDATION_ERROR",
  "errors": {
    "warehouse_id": [
      "The selected warehouse is invalid."
    ]
  }
}

429 Превышен лимит запросов

TooManyRequests

Превышен лимит запросов.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "Too Many Attempts."
error да string "RATE_LIMITED"

500 Внутренняя ошибка сервера

InternalServerError

Произошла непредвиденная ошибка сервера.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

INTERNAL_SERVER_ERROR

{
  "message": "An unexpected server error occurred.",
  "error": "INTERNAL_SERVER_ERROR"
}
PUT /api/v2/products

Обновить товар

operationIdreplaceProducts
РазделТовары
БезопасностьbearerAuth

Bulk updates products identified by id or by external_id plus shop_id. When barcodes are supplied, the barcode set is replaced according to existing product rules.
Текущее поведение backend является legacy-семантикой частичного обновления: пропущенные поля не изменяются.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Optional type_id accepts integer codes 1 ordinary, 2 composite, 3 component, 4 consumable, 5 packaging. Omission preserves the existing/default type; explicit null, empty, fractional or unknown values are rejected. Types 2/3 require composites enabled in the shop and permission to manage composition, in addition to product create/update rights. Quant packaging and links, existing composition links and dependent warehouse documents can prevent a type transition. This field does not create or replace a composition. Product and component prices are independent. Each item commits separately: a later rule failure may leave earlier items applied. Read back affected products before retrying a failed bulk request.

Пример HTTP-запроса (cURL)

Подставьте свой сервер и токен. ID из примера замените реальными доступными ID. Для тела запроса сохраните подходящий JSON из раздела ниже в request.json; перед отправкой замените демонстрационные значения. Заголовок Idempotency-Key использует ключ одной логической операции.

curl --globoff --request PUT "${NWMS_BASE_URL}/api/v2/products" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${NWMS_TOKEN}" \
  --header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
  --header "Content-Type: application/json" \
  --data-binary @request.json

Параметры

Имя Где Обязательное Тип Style Explode Ограничения Описание Пример
Idempotency-Key header нет string maxLength: 191 Опциональный ключ идемпотентности для write-запросов API v2. Успешные ответы 2xx/3xx повторяются для того же ключа и идентичного payload в течение одного дня. Тот же ключ с другим payload возвращает 409. "ord-create-20260714-001"

Тело запроса

BulkReplaceProductsRequest обязательно

Поле Обязательное Тип Флаги Ограничения Описание Пример
data да ReplaceProductPayload
data да array<ReplaceProductPayload> minItems: 1

Примеры запроса

default

{
  "data": [
    {
      "id": 1201,
      "name": "Coffee 250g",
      "price": 19.99,
      "type_id": 3
    }
  ]
}

Ответы

200 Successful response.

Successful response.

Поле Обязательное Тип Флаги Ограничения Описание Пример
(root) нет ProductMutationResponse Запись одного товара возвращает ProductResponse; запись массива товаров возвращает ProductCollectionResponse в порядке входных успешно обработанных элементов.
data да Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data.id да integer:int64 readOnly min: 1 1001
data.created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.external_id нет string | null "EXT-10045"
data.shop_id нет integer:int64 | null min: 1 12
data.domain_id нет integer:int64 | null min: 1 3
data.status_id нет integer:int64 | null 1
data.type_id нет integer:int64 | null 1
data.name да string "Coffee 250g"
data.article нет string | null "ART-001245"
data.sku нет string | null "SKU-001245"
data.price нет number:float | null 19.99
data.estimated_price нет number:float | null 21.5
data.image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data.dimensions нет Dimensions
data.dimensions.x нет number:float | null min: 0 105
data.dimensions.y нет number:float | null min: 0 200
data.dimensions.z нет number:float | null min: 0 32
data.dimensions.unit да enum enum: mm "mm"
data.weight нет Weight
data.weight.value нет number:float | null min: 0 250
data.weight.unit да enum enum: g "g"
data.datamatrix_required да boolean false
data.expiration_required да boolean true
data.comment нет string | null "Keep dry"
data.description нет string | null "Ground coffee package"
data.inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.barcodes нет array<ProductBarcode>
data.barcodes[] нет ProductBarcode
data.barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data.barcodes[].is_main да boolean true
data.stocks нет ProductStocks
data.stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data.stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data.stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.physical[].warehouse_id да integer:int64 min: 1 42
data.stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.physical[].stockTotal да number:float 24.0
data.stocks.physical[].stockReserved да number:float 6.0
data.stocks.physical[].stockAvailable да number:float 18.0
data.stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data.stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data.stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.aggregate[].stockTotal да number:float 24.0
data.stocks.aggregate[].stockReserved да number:float 6.0
data.stocks.aggregate[].stockAvailable да number:float 18.0
data.package нет object | null
data.package.kind нет string | null "unit"
data.package.parent_product_id нет integer:int64 | null min: 1 1201
data.package.base_product_id нет integer:int64 | null min: 1 1200
data.package.multiplicity нет number:float | null min: 0 6
meta да ResponseMeta
meta.api_version да enum enum: v2 "v2"
meta.deleted нет boolean true
meta.id нет integer:int64 | null min: 1 1001
meta.command_replayed нет boolean True when an idempotent cross-dock command returned the original successful result. false
meta.crossdock_configuration нет object | null
meta.crossdock_configuration.physical_warehouse_id да integer:int64 min: 1 42
meta.crossdock_configuration.enabled да boolean true
meta.crossdock_configuration.process_version да string "direct_order_v1"
data да array<Product>
data[] нет Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data[].id да integer:int64 readOnly min: 1 1001
data[].created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].external_id нет string | null "EXT-10045"
data[].shop_id нет integer:int64 | null min: 1 12
data[].domain_id нет integer:int64 | null min: 1 3
data[].status_id нет integer:int64 | null 1
data[].type_id нет integer:int64 | null 1
data[].name да string "Coffee 250g"
data[].article нет string | null "ART-001245"
data[].sku нет string | null "SKU-001245"
data[].price нет number:float | null 19.99
data[].estimated_price нет number:float | null 21.5
data[].image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data[].dimensions нет Dimensions
data[].dimensions.x нет number:float | null min: 0 105
data[].dimensions.y нет number:float | null min: 0 200
data[].dimensions.z нет number:float | null min: 0 32
data[].dimensions.unit да enum enum: mm "mm"
data[].weight нет Weight
data[].weight.value нет number:float | null min: 0 250
data[].weight.unit да enum enum: g "g"
data[].datamatrix_required да boolean false
data[].expiration_required да boolean true
data[].comment нет string | null "Keep dry"
data[].description нет string | null "Ground coffee package"
data[].inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].barcodes нет array<ProductBarcode>
data[].barcodes[] нет ProductBarcode
data[].barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data[].barcodes[].is_main да boolean true
data[].stocks нет ProductStocks
data[].stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data[].stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data[].stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.physical[].warehouse_id да integer:int64 min: 1 42
data[].stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.physical[].stockTotal да number:float 24.0
data[].stocks.physical[].stockReserved да number:float 6.0
data[].stocks.physical[].stockAvailable да number:float 18.0
data[].stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data[].stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data[].stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.aggregate[].stockTotal да number:float 24.0
data[].stocks.aggregate[].stockReserved да number:float 6.0
data[].stocks.aggregate[].stockAvailable да number:float 18.0
data[].package нет object | null
data[].package.kind нет string | null "unit"
data[].package.parent_product_id нет integer:int64 | null min: 1 1201
data[].package.base_product_id нет integer:int64 | null min: 1 1200
data[].package.multiplicity нет number:float | null min: 0 6
meta да ResponseMeta
meta.api_version да enum enum: v2 "v2"
meta.deleted нет boolean true
meta.id нет integer:int64 | null min: 1 1001
meta.command_replayed нет boolean True when an idempotent cross-dock command returned the original successful result. false
meta.crossdock_configuration нет object | null
meta.crossdock_configuration.physical_warehouse_id да integer:int64 min: 1 42
meta.crossdock_configuration.enabled да boolean true
meta.crossdock_configuration.process_version да string "direct_order_v1"

Примеры ответа

success

{
  "data": {
    "id": 1201,
    "external_id": "EXT-10045",
    "shop_id": 12,
    "domain_id": 3,
    "status_id": 1,
    "type_id": 1,
    "name": "Coffee 250g",
    "article": "ART-001245",
    "sku": "SKU-001245",
    "price": 19.99,
    "estimated_price": 21.5,
    "image_url": "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg",
    "dimensions": {
      "x": 105,
      "y": 200,
      "z": 32,
      "unit": "mm"
    },
    "weight": {
      "value": 250,
      "unit": "g"
    },
    "datamatrix_required": false,
    "expiration_required": true,
    "comment": "Keep dry",
    "description": "Ground coffee package",
    "inventory_updated_at": "2026-07-14T08:30:00Z",
    "barcodes": [
      {
        "barcode": "4601234567890",
        "is_main": true
      }
    ],
    "stocks": {
      "available_by_warehouse": {
        "42": 18
      },
      "physical": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 24,
          "stockReserved": 6,
          "stockAvailable": 18
        }
      ],
      "aggregate": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 30,
          "stockReserved": 7,
          "stockAvailable": 23
        }
      ]
    },
    "package": {
      "kind": "unit",
      "parent_product_id": null,
      "base_product_id": null,
      "multiplicity": null
    },
    "created_at": "2026-07-14T09:00:00Z",
    "updated_at": "2026-07-14T09:30:00Z"
  },
  "meta": {
    "api_version": "v2"
  }
}

400 Некорректный запрос

BadRequest

Некорректный запрос.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

BAD_REQUEST

{
  "message": "Bad request.",
  "error": "BAD_REQUEST"
}

401 Требуется аутентификация

Unauthorized

Требуется аутентификация.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

AUTH_REQUIRED

{
  "message": "Authentication is required.",
  "error": "AUTH_REQUIRED"
}

403 Доступ запрещен

Forbidden

Аутентифицированному аккаунту запрещено выполнять это действие.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

FORBIDDEN

{
  "message": "The authenticated account is not allowed to perform this action.",
  "error": "FORBIDDEN"
}

409 Конфликт

Conflict

Запрос конфликтует с текущим состоянием ресурса или ключа идемпотентности.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

idempotencyConflict

{
  "message": "The idempotency key is already used with a different payload.",
  "error": "IDEMPOTENCY_KEY_CONFLICT"
}

422 Ошибка валидации

ValidationError

Ошибка валидации.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The given data was invalid."
error нет string "VALIDATION_ERROR"
errors да object {"warehouse_id":["The selected warehouse is invalid."]}

Примеры ответа

validationError

{
  "message": "The given data was invalid.",
  "error": "VALIDATION_ERROR",
  "errors": {
    "warehouse_id": [
      "The selected warehouse is invalid."
    ]
  }
}

429 Превышен лимит запросов

TooManyRequests

Превышен лимит запросов.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "Too Many Attempts."
error да string "RATE_LIMITED"

500 Внутренняя ошибка сервера

InternalServerError

Произошла непредвиденная ошибка сервера.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

INTERNAL_SERVER_ERROR

{
  "message": "An unexpected server error occurred.",
  "error": "INTERNAL_SERVER_ERROR"
}
PATCH /api/v2/products

Обновить товар

operationIdpatchProducts
РазделТовары
БезопасностьbearerAuth

Partially bulk updates products. Only supplied product fields are changed.
Текущее поведение backend является legacy-семантикой частичного обновления: пропущенные поля не изменяются.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
For unplaced consumable usage, stockTotal does not include a permanent physical write-off and must not be used as available packaging inventory. Addressed consumable write-offs remain the existing warehouse process.
Optional type_id accepts integer codes 1 ordinary, 2 composite, 3 component, 4 consumable, 5 packaging. Omission preserves the existing/default type; explicit null, empty, fractional or unknown values are rejected. Types 2/3 require composites enabled in the shop and permission to manage composition, in addition to product create/update rights. Quant packaging and links, existing composition links and dependent warehouse documents can prevent a type transition. This field does not create or replace a composition. Product and component prices are independent. Each item commits separately: a later rule failure may leave earlier items applied. Read back affected products before retrying a failed bulk request.

Пример HTTP-запроса (cURL)

Подставьте свой сервер и токен. ID из примера замените реальными доступными ID. Для тела запроса сохраните подходящий JSON из раздела ниже в request.json; перед отправкой замените демонстрационные значения. Заголовок Idempotency-Key использует ключ одной логической операции.

curl --globoff --request PATCH "${NWMS_BASE_URL}/api/v2/products" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${NWMS_TOKEN}" \
  --header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
  --header "Content-Type: application/json" \
  --data-binary @request.json

Параметры

Имя Где Обязательное Тип Style Explode Ограничения Описание Пример
Idempotency-Key header нет string maxLength: 191 Опциональный ключ идемпотентности для write-запросов API v2. Успешные ответы 2xx/3xx повторяются для того же ключа и идентичного payload в течение одного дня. Тот же ключ с другим payload возвращает 409. "ord-create-20260714-001"

Тело запроса

BulkPatchProductsRequest обязательно

Поле Обязательное Тип Флаги Ограничения Описание Пример
data да PatchProductPayload
data да array<PatchProductPayload> minItems: 1

Примеры запроса

default

{
  "data": [
    {
      "external_id": "EXT-10045",
      "shop_id": 12,
      "price": 18.99,
      "type_id": 3
    }
  ]
}

Ответы

200 Successful response.

Successful response.

Поле Обязательное Тип Флаги Ограничения Описание Пример
(root) нет ProductMutationResponse Запись одного товара возвращает ProductResponse; запись массива товаров возвращает ProductCollectionResponse в порядке входных успешно обработанных элементов.
data да Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data.id да integer:int64 readOnly min: 1 1001
data.created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.external_id нет string | null "EXT-10045"
data.shop_id нет integer:int64 | null min: 1 12
data.domain_id нет integer:int64 | null min: 1 3
data.status_id нет integer:int64 | null 1
data.type_id нет integer:int64 | null 1
data.name да string "Coffee 250g"
data.article нет string | null "ART-001245"
data.sku нет string | null "SKU-001245"
data.price нет number:float | null 19.99
data.estimated_price нет number:float | null 21.5
data.image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data.dimensions нет Dimensions
data.dimensions.x нет number:float | null min: 0 105
data.dimensions.y нет number:float | null min: 0 200
data.dimensions.z нет number:float | null min: 0 32
data.dimensions.unit да enum enum: mm "mm"
data.weight нет Weight
data.weight.value нет number:float | null min: 0 250
data.weight.unit да enum enum: g "g"
data.datamatrix_required да boolean false
data.expiration_required да boolean true
data.comment нет string | null "Keep dry"
data.description нет string | null "Ground coffee package"
data.inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.barcodes нет array<ProductBarcode>
data.barcodes[] нет ProductBarcode
data.barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data.barcodes[].is_main да boolean true
data.stocks нет ProductStocks
data.stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data.stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data.stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.physical[].warehouse_id да integer:int64 min: 1 42
data.stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.physical[].stockTotal да number:float 24.0
data.stocks.physical[].stockReserved да number:float 6.0
data.stocks.physical[].stockAvailable да number:float 18.0
data.stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data.stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data.stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.aggregate[].stockTotal да number:float 24.0
data.stocks.aggregate[].stockReserved да number:float 6.0
data.stocks.aggregate[].stockAvailable да number:float 18.0
data.package нет object | null
data.package.kind нет string | null "unit"
data.package.parent_product_id нет integer:int64 | null min: 1 1201
data.package.base_product_id нет integer:int64 | null min: 1 1200
data.package.multiplicity нет number:float | null min: 0 6
meta да ResponseMeta
meta.api_version да enum enum: v2 "v2"
meta.deleted нет boolean true
meta.id нет integer:int64 | null min: 1 1001
meta.command_replayed нет boolean True when an idempotent cross-dock command returned the original successful result. false
meta.crossdock_configuration нет object | null
meta.crossdock_configuration.physical_warehouse_id да integer:int64 min: 1 42
meta.crossdock_configuration.enabled да boolean true
meta.crossdock_configuration.process_version да string "direct_order_v1"
data да array<Product>
data[] нет Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data[].id да integer:int64 readOnly min: 1 1001
data[].created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].external_id нет string | null "EXT-10045"
data[].shop_id нет integer:int64 | null min: 1 12
data[].domain_id нет integer:int64 | null min: 1 3
data[].status_id нет integer:int64 | null 1
data[].type_id нет integer:int64 | null 1
data[].name да string "Coffee 250g"
data[].article нет string | null "ART-001245"
data[].sku нет string | null "SKU-001245"
data[].price нет number:float | null 19.99
data[].estimated_price нет number:float | null 21.5
data[].image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data[].dimensions нет Dimensions
data[].dimensions.x нет number:float | null min: 0 105
data[].dimensions.y нет number:float | null min: 0 200
data[].dimensions.z нет number:float | null min: 0 32
data[].dimensions.unit да enum enum: mm "mm"
data[].weight нет Weight
data[].weight.value нет number:float | null min: 0 250
data[].weight.unit да enum enum: g "g"
data[].datamatrix_required да boolean false
data[].expiration_required да boolean true
data[].comment нет string | null "Keep dry"
data[].description нет string | null "Ground coffee package"
data[].inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data[].barcodes нет array<ProductBarcode>
data[].barcodes[] нет ProductBarcode
data[].barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data[].barcodes[].is_main да boolean true
data[].stocks нет ProductStocks
data[].stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data[].stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data[].stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.physical[].warehouse_id да integer:int64 min: 1 42
data[].stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.physical[].stockTotal да number:float 24.0
data[].stocks.physical[].stockReserved да number:float 6.0
data[].stocks.physical[].stockAvailable да number:float 18.0
data[].stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data[].stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data[].stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data[].stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data[].stocks.aggregate[].stockTotal да number:float 24.0
data[].stocks.aggregate[].stockReserved да number:float 6.0
data[].stocks.aggregate[].stockAvailable да number:float 18.0
data[].package нет object | null
data[].package.kind нет string | null "unit"
data[].package.parent_product_id нет integer:int64 | null min: 1 1201
data[].package.base_product_id нет integer:int64 | null min: 1 1200
data[].package.multiplicity нет number:float | null min: 0 6
meta да ResponseMeta
meta.api_version да enum enum: v2 "v2"
meta.deleted нет boolean true
meta.id нет integer:int64 | null min: 1 1001
meta.command_replayed нет boolean True when an idempotent cross-dock command returned the original successful result. false
meta.crossdock_configuration нет object | null
meta.crossdock_configuration.physical_warehouse_id да integer:int64 min: 1 42
meta.crossdock_configuration.enabled да boolean true
meta.crossdock_configuration.process_version да string "direct_order_v1"

Примеры ответа

success

{
  "data": {
    "id": 1201,
    "external_id": "EXT-10045",
    "shop_id": 12,
    "domain_id": 3,
    "status_id": 1,
    "type_id": 1,
    "name": "Coffee 250g",
    "article": "ART-001245",
    "sku": "SKU-001245",
    "price": 19.99,
    "estimated_price": 21.5,
    "image_url": "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg",
    "dimensions": {
      "x": 105,
      "y": 200,
      "z": 32,
      "unit": "mm"
    },
    "weight": {
      "value": 250,
      "unit": "g"
    },
    "datamatrix_required": false,
    "expiration_required": true,
    "comment": "Keep dry",
    "description": "Ground coffee package",
    "inventory_updated_at": "2026-07-14T08:30:00Z",
    "barcodes": [
      {
        "barcode": "4601234567890",
        "is_main": true
      }
    ],
    "stocks": {
      "available_by_warehouse": {
        "42": 18
      },
      "physical": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 24,
          "stockReserved": 6,
          "stockAvailable": 18
        }
      ],
      "aggregate": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 30,
          "stockReserved": 7,
          "stockAvailable": 23
        }
      ]
    },
    "package": {
      "kind": "unit",
      "parent_product_id": null,
      "base_product_id": null,
      "multiplicity": null
    },
    "created_at": "2026-07-14T09:00:00Z",
    "updated_at": "2026-07-14T09:30:00Z"
  },
  "meta": {
    "api_version": "v2"
  }
}

400 Некорректный запрос

BadRequest

Некорректный запрос.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

BAD_REQUEST

{
  "message": "Bad request.",
  "error": "BAD_REQUEST"
}

401 Требуется аутентификация

Unauthorized

Требуется аутентификация.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

AUTH_REQUIRED

{
  "message": "Authentication is required.",
  "error": "AUTH_REQUIRED"
}

403 Доступ запрещен

Forbidden

Аутентифицированному аккаунту запрещено выполнять это действие.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

FORBIDDEN

{
  "message": "The authenticated account is not allowed to perform this action.",
  "error": "FORBIDDEN"
}

409 Конфликт

Conflict

Запрос конфликтует с текущим состоянием ресурса или ключа идемпотентности.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

idempotencyConflict

{
  "message": "The idempotency key is already used with a different payload.",
  "error": "IDEMPOTENCY_KEY_CONFLICT"
}

422 Ошибка валидации

ValidationError

Ошибка валидации.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The given data was invalid."
error нет string "VALIDATION_ERROR"
errors да object {"warehouse_id":["The selected warehouse is invalid."]}

Примеры ответа

validationError

{
  "message": "The given data was invalid.",
  "error": "VALIDATION_ERROR",
  "errors": {
    "warehouse_id": [
      "The selected warehouse is invalid."
    ]
  }
}

429 Превышен лимит запросов

TooManyRequests

Превышен лимит запросов.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "Too Many Attempts."
error да string "RATE_LIMITED"

500 Внутренняя ошибка сервера

InternalServerError

Произошла непредвиденная ошибка сервера.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

INTERNAL_SERVER_ERROR

{
  "message": "An unexpected server error occurred.",
  "error": "INTERNAL_SERVER_ERROR"
}
GET /api/v2/products/{id}

Получить товар

operationIdgetProducts
РазделТовары
БезопасностьbearerAuth

Возвращает один ресурс: товар, если он существует и видим аутентифицированному аккаунту.

Пример HTTP-запроса (cURL)

Подставьте свой сервер и токен. ID из примера замените реальными доступными ID. Для тела запроса сохраните подходящий JSON из раздела ниже в request.json; перед отправкой замените демонстрационные значения. Заголовок Idempotency-Key использует ключ одной логической операции.

curl --globoff --request GET "${NWMS_BASE_URL}/api/v2/products/1001" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${NWMS_TOKEN}"

Параметры

Имя Где Обязательное Тип Style Explode Ограничения Описание Пример
id path да integer:int64 min: 1 ID товара. 1001

Тело запроса

Тело запроса отсутствует.

Ответы

200 Successful response.

Successful response.

Поле Обязательное Тип Флаги Ограничения Описание Пример
data да Product Product catalog item exposed by API v2. Product barcodes identify a product or package type and are not unique SSCC values. Use /api/v2/closed-boxes to read individual sealed boxes and their current box balance.
data.id да integer:int64 readOnly min: 1 1001
data.created_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.external_id нет string | null "EXT-10045"
data.shop_id нет integer:int64 | null min: 1 12
data.domain_id нет integer:int64 | null min: 1 3
data.status_id нет integer:int64 | null 1
data.type_id нет integer:int64 | null 1
data.name да string "Coffee 250g"
data.article нет string | null "ART-001245"
data.sku нет string | null "SKU-001245"
data.price нет number:float | null 19.99
data.estimated_price нет number:float | null 21.5
data.image_url нет string:uri | null "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg"
data.dimensions нет Dimensions
data.dimensions.x нет number:float | null min: 0 105
data.dimensions.y нет number:float | null min: 0 200
data.dimensions.z нет number:float | null min: 0 32
data.dimensions.unit да enum enum: mm "mm"
data.weight нет Weight
data.weight.value нет number:float | null min: 0 250
data.weight.unit да enum enum: g "g"
data.datamatrix_required да boolean false
data.expiration_required да boolean true
data.comment нет string | null "Keep dry"
data.description нет string | null "Ground coffee package"
data.inventory_updated_at нет string:date-time | null "2026-07-14T10:30:00Z"
data.barcodes нет array<ProductBarcode>
data.barcodes[] нет ProductBarcode
data.barcodes[].barcode да string minLength: 1
maxLength: 64
"4601234567890"
data.barcodes[].is_main да boolean true
data.stocks нет ProductStocks
data.stocks.available_by_warehouse нет object Объект с ключами по ID склада. Значения являются количествами. {"42":18.0,"43":3.0}
data.stocks.physical нет array<ProductStockSummary> Physical stock rows for the product itself.
data.stocks.physical[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.physical[].warehouse_id да integer:int64 min: 1 42
data.stocks.physical[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.physical[].stockTotal да number:float 24.0
data.stocks.physical[].stockReserved да number:float 6.0
data.stocks.physical[].stockAvailable да number:float 18.0
data.stocks.aggregate нет array<ProductStockSummary> Aggregated base-unit stock rows for the product and its descendant quants.
data.stocks.aggregate[] нет ProductStockSummary Stock totals for one warehouse. Quantities may be negative when reservations exceed physical stock.
data.stocks.aggregate[].warehouse_id да integer:int64 min: 1 42
data.stocks.aggregate[].warehouse_name да string | null "Warehouse Sofia"
data.stocks.aggregate[].stockTotal да number:float 24.0
data.stocks.aggregate[].stockReserved да number:float 6.0
data.stocks.aggregate[].stockAvailable да number:float 18.0
data.package нет object | null
data.package.kind нет string | null "unit"
data.package.parent_product_id нет integer:int64 | null min: 1 1201
data.package.base_product_id нет integer:int64 | null min: 1 1200
data.package.multiplicity нет number:float | null min: 0 6
meta да ResponseMeta
meta.api_version да enum enum: v2 "v2"
meta.deleted нет boolean true
meta.id нет integer:int64 | null min: 1 1001
meta.command_replayed нет boolean True when an idempotent cross-dock command returned the original successful result. false
meta.crossdock_configuration нет object | null
meta.crossdock_configuration.physical_warehouse_id да integer:int64 min: 1 42
meta.crossdock_configuration.enabled да boolean true
meta.crossdock_configuration.process_version да string "direct_order_v1"

Примеры ответа

success

{
  "data": {
    "id": 1201,
    "external_id": "EXT-10045",
    "shop_id": 12,
    "domain_id": 3,
    "status_id": 1,
    "type_id": 1,
    "name": "Coffee 250g",
    "article": "ART-001245",
    "sku": "SKU-001245",
    "price": 19.99,
    "estimated_price": 21.5,
    "image_url": "https://betawms.ffcdek.ru/offer-images/products/coffee-250g.jpg",
    "dimensions": {
      "x": 105,
      "y": 200,
      "z": 32,
      "unit": "mm"
    },
    "weight": {
      "value": 250,
      "unit": "g"
    },
    "datamatrix_required": false,
    "expiration_required": true,
    "comment": "Keep dry",
    "description": "Ground coffee package",
    "inventory_updated_at": "2026-07-14T08:30:00Z",
    "barcodes": [
      {
        "barcode": "4601234567890",
        "is_main": true
      }
    ],
    "stocks": {
      "available_by_warehouse": {
        "42": 18
      },
      "physical": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 24,
          "stockReserved": 6,
          "stockAvailable": 18
        }
      ],
      "aggregate": [
        {
          "warehouse_id": 42,
          "warehouse_name": "Warehouse Sofia",
          "stockTotal": 30,
          "stockReserved": 7,
          "stockAvailable": 23
        }
      ]
    },
    "package": {
      "kind": "unit",
      "parent_product_id": null,
      "base_product_id": null,
      "multiplicity": null
    },
    "created_at": "2026-07-14T09:00:00Z",
    "updated_at": "2026-07-14T09:30:00Z"
  },
  "meta": {
    "api_version": "v2"
  }
}

401 Требуется аутентификация

Unauthorized

Требуется аутентификация.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

AUTH_REQUIRED

{
  "message": "Authentication is required.",
  "error": "AUTH_REQUIRED"
}

403 Доступ запрещен

Forbidden

Аутентифицированному аккаунту запрещено выполнять это действие.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

FORBIDDEN

{
  "message": "The authenticated account is not allowed to perform this action.",
  "error": "FORBIDDEN"
}

404 Не найдено

NotFound

Запрошенный ресурс не найден или находится вне области доступа аккаунта.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

NOT_FOUND

{
  "message": "The requested resource was not found or is outside the authenticated account scope.",
  "error": "NOT_FOUND"
}

429 Превышен лимит запросов

TooManyRequests

Превышен лимит запросов.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "Too Many Attempts."
error да string "RATE_LIMITED"

500 Внутренняя ошибка сервера

InternalServerError

Произошла непредвиденная ошибка сервера.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

INTERNAL_SERVER_ERROR

{
  "message": "An unexpected server error occurred.",
  "error": "INTERNAL_SERVER_ERROR"
}
DELETE /api/v2/products/{id}

Удалить товар

operationIddeleteProducts
РазделТовары
БезопасностьbearerAuth

Deletes the resource when the authenticated account has permission and the current lifecycle state allows deletion. If deletion is blocked by related records or document state, the API returns a validation error.

Пример HTTP-запроса (cURL)

Подставьте свой сервер и токен. ID из примера замените реальными доступными ID. Для тела запроса сохраните подходящий JSON из раздела ниже в request.json; перед отправкой замените демонстрационные значения. Заголовок Idempotency-Key использует ключ одной логической операции.

curl --globoff --request DELETE "${NWMS_BASE_URL}/api/v2/products/1001" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${NWMS_TOKEN}" \
  --header "Idempotency-Key: ${NWMS_REQUEST_KEY}"

Параметры

Имя Где Обязательное Тип Style Explode Ограничения Описание Пример
id path да integer:int64 min: 1 ID товара. 1001
Idempotency-Key header нет string maxLength: 191 Опциональный ключ идемпотентности для write-запросов API v2. Успешные ответы 2xx/3xx повторяются для того же ключа и идентичного payload в течение одного дня. Тот же ключ с другим payload возвращает 409. "ord-create-20260714-001"

Тело запроса

Тело запроса отсутствует.

Ответы

200 Successful response.

Successful response.

Поле Обязательное Тип Флаги Ограничения Описание Пример
data да object | null
meta да object
meta.api_version да enum enum: v2 "v2"
meta.deleted да boolean true
meta.id да integer:int64 min: 1 1001

Примеры ответа

success

{
  "data": null,
  "meta": {
    "api_version": "v2",
    "deleted": true,
    "id": 1001
  }
}

400 Некорректный запрос

BadRequest

Некорректный запрос.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

BAD_REQUEST

{
  "message": "Bad request.",
  "error": "BAD_REQUEST"
}

401 Требуется аутентификация

Unauthorized

Требуется аутентификация.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

AUTH_REQUIRED

{
  "message": "Authentication is required.",
  "error": "AUTH_REQUIRED"
}

403 Доступ запрещен

Forbidden

Аутентифицированному аккаунту запрещено выполнять это действие.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

FORBIDDEN

{
  "message": "The authenticated account is not allowed to perform this action.",
  "error": "FORBIDDEN"
}

404 Не найдено

NotFound

Запрошенный ресурс не найден или находится вне области доступа аккаунта.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

NOT_FOUND

{
  "message": "The requested resource was not found or is outside the authenticated account scope.",
  "error": "NOT_FOUND"
}

409 Конфликт

Conflict

Запрос конфликтует с текущим состоянием ресурса или ключа идемпотентности.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

idempotencyConflict

{
  "message": "The idempotency key is already used with a different payload.",
  "error": "IDEMPOTENCY_KEY_CONFLICT"
}

422 Ошибка валидации

ValidationError

Ошибка валидации.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The given data was invalid."
error нет string "VALIDATION_ERROR"
errors да object {"warehouse_id":["The selected warehouse is invalid."]}

Примеры ответа

validationError

{
  "message": "The given data was invalid.",
  "error": "VALIDATION_ERROR",
  "errors": {
    "warehouse_id": [
      "The selected warehouse is invalid."
    ]
  }
}

429 Превышен лимит запросов

TooManyRequests

Превышен лимит запросов.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "Too Many Attempts."
error да string "RATE_LIMITED"

500 Внутренняя ошибка сервера

InternalServerError

Произошла непредвиденная ошибка сервера.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

INTERNAL_SERVER_ERROR

{
  "message": "An unexpected server error occurred.",
  "error": "INTERNAL_SERVER_ERROR"
}
GET /api/v2/products/{id}/stock-lots

List physical stock lots

operationIdgetProductStockLots
РазделТовары
БезопасностьbearerAuth

Read physical placed stock per warehouse, place and lot in this product's units. Unplaced reservations are excluded because they have no actual lot yet. Aggregate physical_quantity by warehouse and lot for reconciliation. Results use current product visibility and container rules, standard pagination (maximum 500) and no snapshot isolation.
Unknown read parameters are ignored. per_page is silently capped; use meta.per_page. Date-only boundaries follow the installation's stored calendar dates; ISO timestamps are serialized in UTC. The default general API limit is 600/minute; a user-specific override may apply. Its bucket is shared by authenticated user, not by shop/domain; Retry-After is returned on throttling.

Пример HTTP-запроса (cURL)

Подставьте свой сервер и токен. ID из примера замените реальными доступными ID. Для тела запроса сохраните подходящий JSON из раздела ниже в request.json; перед отправкой замените демонстрационные значения. Заголовок Idempotency-Key использует ключ одной логической операции.

curl --globoff --request GET "${NWMS_BASE_URL}/api/v2/products/1001/stock-lots" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${NWMS_TOKEN}"

Параметры

Имя Где Обязательное Тип Style Explode Ограничения Описание Пример
id path да integer:int64 min: 1 ID товара. 1001
page query нет integer:int64 form true min: 1 Номер страницы. Этот фильтр также можно передать как filter[page], если это поддерживает Laravel query adapter. 1
per_page query нет integer:int64 form true min: 1
max: 500
Количество записей на странице. По умолчанию 100; максимум 500. Этот фильтр также можно передать как filter[per_page], если это поддерживает Laravel query adapter. 100
sort query нет string form false pattern: ^-?[A-Za-z0-9_]+(,-?[A-Za-z0-9_]+)*$ Поля сортировки через запятую. Префикс - означает сортировку по убыванию. Допустимые поля: id, warehouse_id, expiration_date. По умолчанию: id. Этот фильтр также можно передать как filter[sort], если это поддерживает Laravel query adapter. "id"
warehouse_id query нет integer:int64 form true min: 1 Фильтр по warehouse_id с точным совпадением. Этот фильтр также можно передать как filter[warehouse_id], если это поддерживает Laravel query adapter. 42
batch query нет string form true Фильтр по batch с частичным текстовым совпадением. Этот фильтр также можно передать как filter[batch], если это поддерживает Laravel query adapter. "LOT-2026"
production_date_from query нет string:date form true Нижняя включительная граница даты для production_date. Этот фильтр также можно передать как filter[production_date_from], если это поддерживает Laravel query adapter. "2026-07-14"
production_date_to query нет string:date form true Верхняя включительная граница даты для production_date. Этот фильтр также можно передать как filter[production_date_to], если это поддерживает Laravel query adapter. "2026-07-14"
expiration_date_from query нет string:date form true Нижняя включительная граница даты для expiration_date. Этот фильтр также можно передать как filter[expiration_date_from], если это поддерживает Laravel query adapter. "2026-07-14"
expiration_date_to query нет string:date form true Верхняя включительная граница даты для expiration_date. Этот фильтр также можно передать как filter[expiration_date_to], если это поддерживает Laravel query adapter. "2026-07-14"

Тело запроса

Тело запроса отсутствует.

Ответы

200 Successful response.

Successful response.

Поле Обязательное Тип Флаги Ограничения Описание Пример
data да array<StockLot>
data[] нет StockLot One active positive placed stock slice in product units, using the same container visibility rules as product stock. Does not allocate unplaced reservations to lots. Not a snapshot cursor or append-only feed.
data[].batch да string | null "LOT-2026"
data[].production_date да string:date | null "2026-01-15"
data[].expiration_date да string:date | null "2027-01-15"
data[].id да integer:int64 min: 1 5001
data[].product_id да integer:int64 min: 1 1201
data[].warehouse_id да integer:int64 min: 1 734
data[].place_id да integer:int64 min: 1 501
data[].physical_quantity да number:float min: 0 12
links да PaginationLinks
links.first да string:uri | null "https://betawms.ffcdek.ru/api/v2/orders?page=1"
links.last да string:uri | null "https://betawms.ffcdek.ru/api/v2/orders?page=2"
links.prev да string:uri | null
links.next да string:uri | null "https://betawms.ffcdek.ru/api/v2/orders?page=2"
meta да PaginationMeta
meta.api_version да enum enum: v2 "v2"
meta.current_page да integer:int32 min: 1 1
meta.from да integer:int32 | null min: 1 1
meta.last_page да integer:int32 min: 1 2
meta.path да string:uri "https://betawms.ffcdek.ru/api/v2/orders"
meta.per_page да integer:int32 min: 1 50
meta.to да integer:int32 | null min: 1 50
meta.total да integer:int32 min: 0 73

Примеры ответа

success

{
  "data": [
    {
      "batch": "LOT-2026",
      "production_date": "2026-01-15",
      "expiration_date": "2027-01-15",
      "id": 5001,
      "product_id": 1201,
      "warehouse_id": 734,
      "place_id": 501,
      "physical_quantity": 12
    }
  ],
  "links": {
    "first": "https://betawms.ffcdek.ru/api/v2/products/5101/stock-lots?page=1",
    "last": "https://betawms.ffcdek.ru/api/v2/products/5101/stock-lots?page=2",
    "prev": null,
    "next": "https://betawms.ffcdek.ru/api/v2/products/5101/stock-lots?page=2"
  },
  "meta": {
    "api_version": "v2",
    "current_page": 1,
    "from": 1,
    "last_page": 2,
    "path": "https://betawms.ffcdek.ru/api/v2/products/5101/stock-lots",
    "per_page": 100,
    "to": 100,
    "total": 123
  }
}

401 Требуется аутентификация

Unauthorized

Требуется аутентификация.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

AUTH_REQUIRED

{
  "message": "Authentication is required.",
  "error": "AUTH_REQUIRED"
}

403 Доступ запрещен

Forbidden

Аутентифицированному аккаунту запрещено выполнять это действие.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

FORBIDDEN

{
  "message": "The authenticated account is not allowed to perform this action.",
  "error": "FORBIDDEN"
}

404 Не найдено

NotFound

Запрошенный ресурс не найден или находится вне области доступа аккаунта.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

NOT_FOUND

{
  "message": "The requested resource was not found or is outside the authenticated account scope.",
  "error": "NOT_FOUND"
}

429 Превышен лимит запросов

TooManyRequests

Превышен лимит запросов.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "Too Many Attempts."
error да string "RATE_LIMITED"

500 Внутренняя ошибка сервера

InternalServerError

Произошла непредвиденная ошибка сервера.

Поле Обязательное Тип Флаги Ограничения Описание Пример
message да string "The request could not be processed."
error да string "BAD_REQUEST"

Примеры ответа

INTERNAL_SERVER_ERROR

{
  "message": "An unexpected server error occurred.",
  "error": "INTERNAL_SERVER_ERROR"
}