Товары
Каждая операция ниже сгенерирована из 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 сохраняются для совместимости. Подробные ограничения смотрите у операции. |
Товары
Получить список товаров
| operationId | listProducts |
|---|---|
| Раздел | Товары |
| Безопасность | 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"
}
Создать товар
| operationId | createProducts |
|---|---|
| Раздел | Товары |
| Безопасность | 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"
}
Обновить товар
| operationId | replaceProducts |
|---|---|
| Раздел | Товары |
| Безопасность | 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"
}
Обновить товар
| operationId | patchProducts |
|---|---|
| Раздел | Товары |
| Безопасность | 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"
}
Получить товар
| operationId | getProducts |
|---|---|
| Раздел | Товары |
| Безопасность | 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"
}
Удалить товар
| operationId | deleteProducts |
|---|---|
| Раздел | Товары |
| Безопасность | 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"
}
List physical stock lots
| operationId | getProductStockLots |
|---|---|
| Раздел | Товары |
| Безопасность | 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"
}