Orders
Every operation below is generated from the OpenAPI v2 specification and includes parameters, request fields, response fields, errors, and examples.
Documents, lots and physical stock
| stocks.physical / stocks.aggregate | Arrays of warehouse totals: warehouse_id, warehouse_name, stockTotal, stockReserved, stockAvailable. stocks.available_by_warehouse is an object keyed by warehouse ID; these are not identical shapes. |
|---|---|
| GET /api/v2/products/{id}/stock-lots | Physically placed quantities by lot and dates. An unassigned reservation cannot be subtracted from an arbitrary lot. Check quantity units and warehouse in the response. |
| accepted_lots | Actual receipt lots. Expected, accepted and placed quantities are distinct measures; a difference does not itself indicate an API error. |
| requested_lot / fulfillment_lots | Order requested_lot expresses a requirement; fulfillment_lots records actual picking and picked_quantity the picked amount. Multiple actual lots cannot be reduced to one date. |
| movement_type / operation | Picking can emit a reservation-release and physical-issue pair. Distinguish operation instead of counting two physical issues. Transfers correlate through movement_group_id; transfer_kind specifies the kind. |
| GET /api/v2/closed-boxes | Actual sealed boxes with a unique SSCC: balance=1 and balance_unit=box. A packaging-type barcode from products is not a unique SSCC. Opened, shipped and expected-only boxes are excluded. |
| acceptance_date | For standard/return creation (type_id=1/2), the current handler assigns server now() even when acceptance_date is supplied. Updating an existing acceptance accepts the date. Type 3 uses a separate cross-dock service. created_at/updated_at are technical timestamps, not the document date. |
| Lifecycle | Acceptance cancellation is a separate cancel command with state checks, not deletion. Prefer /lines; deprecated /offers remain for compatibility. See operation-specific constraints. |
Orders
List orders
| operationId | listOrders |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Returns orders visible to the authenticated account. Use documented query parameters for filtering, sorting, and pagination.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
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.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
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.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
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.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
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.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
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.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
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.
Request include=status_history to receive chronological WMS status transitions with changed_at (ISO 8601 and explicit timezone offset), source and inferred. status_history_meta reports availability and whether the last event matches the current status; surviving logs do not guarantee a complete history. send_date is the stored order date field and may come from import, manual input or integration processing; it is not a universal physical carrier-handover timestamp. Status transitions and shipment-document closure must be interpreted as separate recorded events. Dedicated picked_at, packed_at and shipped_at milestones are not exposed.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request GET "${NWMS_BASE_URL}/api/v2/orders" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}"Parameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
page |
query | no | integer:int64 |
form | true | min: 1 | Page number. The same filter may also be sent as filter[page] where supported by the Laravel query adapter. |
1 |
per_page |
query | no | integer:int64 |
form | true | min: 1 max: 500 |
Number of records per page. Default is 50; maximum is 500. The same filter may also be sent as filter[per_page] where supported by the Laravel query adapter. |
50 |
sort |
query | no | string |
form | false | pattern: ^-?[A-Za-z0-9_]+(,-?[A-Za-z0-9_]+)*$ | Comma-separated sort fields. Prefix with - for descending order. Allowed fields: id, order_date, send_date, sum, created_at, updated_at. Default: -id. The same filter may also be sent as filter[sort] where supported by the Laravel query adapter. |
"-id" |
include |
query | no | string |
form | false | Comma-separated optional relations. Allowed values: offers, contact, delivery, comments, consumables, status_history. The same filter may also be sent as filter[include] where supported by the Laravel query adapter. |
"offers,contact,delivery,comments,consumables,status_history" |
|
id |
query | no | integer:int64 |
form | true | min: 1 | Filter by id using exact matching. The same filter may also be sent as filter[id] where supported by the Laravel query adapter. |
1001 |
external_id |
query | no | string |
form | true | Filter by external_id using exact matching. The same filter may also be sent as filter[external_id] where supported by the Laravel query adapter. |
"EXT-10045" |
|
status_id |
query | no | integer:int64 |
form | true | min: 1 | Filter by status_id using exact matching. The same filter may also be sent as filter[status_id] where supported by the Laravel query adapter. |
1 |
warehouse_id |
query | no | integer:int64 |
form | true | min: 1 | Filter by warehouse_id using exact matching. The same filter may also be sent as filter[warehouse_id] where supported by the Laravel query adapter. |
42 |
shop_id |
query | no | integer:int64 |
form | true | min: 1 | Filter by shop_id using exact matching. The same filter may also be sent as filter[shop_id] where supported by the Laravel query adapter. |
12 |
type_id |
query | no | integer:int64 |
form | true | min: 1 | Filter by type_id using exact matching. The same filter may also be sent as filter[type_id] where supported by the Laravel query adapter. |
1 |
source_id |
query | no | integer:int64 |
form | true | min: 1 | Filter by source_id using exact matching. The same filter may also be sent as filter[source_id] where supported by the Laravel query adapter. |
1 |
customer_type |
query | no | integer:int64 |
form | true | min: 1 | Filter by customer_type using exact matching. The same filter may also be sent as filter[customer_type] where supported by the Laravel query adapter. |
1 |
company_id |
query | no | integer:int64 |
form | true | min: 1 | Filter by company_id using exact matching. The same filter may also be sent as filter[company_id] where supported by the Laravel query adapter. |
7 |
is_cod |
query | no | boolean |
form | true | Filter by is_cod using exact matching. The same filter may also be sent as filter[is_cod] where supported by the Laravel query adapter. |
false |
|
order_date_from |
query | no | string:date |
form | true | Lower inclusive date boundary for order_date. The same filter may also be sent as filter[order_date_from] where supported by the Laravel query adapter. |
"2026-07-14" |
|
order_date_to |
query | no | string:date |
form | true | Upper inclusive date boundary for order_date. The same filter may also be sent as filter[order_date_to] where supported by the Laravel query adapter. |
"2026-07-14" |
|
send_date_from |
query | no | string:date |
form | true | Lower inclusive date boundary for send_date. The same filter may also be sent as filter[send_date_from] where supported by the Laravel query adapter. |
"2026-07-14" |
|
send_date_to |
query | no | string:date |
form | true | Upper inclusive date boundary for send_date. The same filter may also be sent as filter[send_date_to] where supported by the Laravel query adapter. |
"2026-07-14" |
|
created_at_from |
query | no | string:date |
form | true | Lower inclusive date boundary for created_at. The same filter may also be sent as filter[created_at_from] where supported by the Laravel query adapter. |
"2026-07-14" |
|
created_at_to |
query | no | string:date |
form | true | Upper inclusive date boundary for created_at. The same filter may also be sent as filter[created_at_to] where supported by the Laravel query adapter. |
"2026-07-14" |
|
updated_at_from |
query | no | string |
form | true | pattern: ^\d{4}-\d{2}-\d{2}(?: \d{2}:\d{2}:\d{2})?$ | Lower inclusive date or date-time boundary for updated_at. The same filter may also be sent as filter[updated_at_from] where supported by the Laravel query adapter. Use YYYY-MM-DD HH:mm:ss for an exact inclusive timestamp in the application timezone; YYYY-MM-DD starts at midnight. |
"2026-07-14 10:30:00" |
updated_at_to |
query | no | string |
form | true | pattern: ^\d{4}-\d{2}-\d{2}(?: \d{2}:\d{2}:\d{2})?$ | Upper inclusive date or date-time boundary for updated_at. The same filter may also be sent as filter[updated_at_to] where supported by the Laravel query adapter. Use YYYY-MM-DD HH:mm:ss for an exact inclusive timestamp in the application timezone; YYYY-MM-DD includes the entire day. |
"2026-07-14 10:30:00" |
sum_from |
query | no | number:float |
form | true | Lower inclusive numeric boundary for sum. The same filter may also be sent as filter[sum_from] where supported by the Laravel query adapter. |
48.58 |
|
sum_to |
query | no | number:float |
form | true | Upper inclusive numeric boundary for sum. The same filter may also be sent as filter[sum_to] where supported by the Laravel query adapter. |
48.58 |
Request body
No request body.
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | array<Order> |
|
|||
data[] |
no | Order |
Outbound warehouse order. Optional relation fields are present when loaded by the controller or requested through include. |
|
||
data[].id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].external_id |
no | string | null |
"ORD-100245" |
|||
data[].domain_id |
no | integer:int64 | null |
min: 1 | 3 |
||
data[].type_id |
no | integer:int64 | null |
1 |
|||
data[].shop_id |
no | integer:int64 | null |
min: 1 | 12 |
||
data[].warehouse_id |
no | integer:int64 | null |
min: 1 | 42 |
||
data[].status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data[].status |
no | object | null |
|
|||
data[].status.id |
yes | integer:int64 |
20 |
|||
data[].status.name |
yes | string |
"Created" |
|||
data[].status.color |
no | string | null |
"#2457c5" |
|||
data[].status.background_color |
no | string | null |
"#eaf0ff" |
|||
data[].order_date |
no | string:date | null |
"2026-07-14" |
|||
data[].send_date |
no | string | null |
Stored order send date, potentially supplied by import, manual input or integration processing. It may be a date or date-time string; it is not a universal physical carrier-handover timestamp. | "2026-07-15 20:25:08" |
||
data[].source_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data[].customer_type |
no | integer:int64 | null |
1 |
|||
data[].is_cod |
no | boolean |
true |
|||
data[].amounts |
no | OrderAmounts |
|
|||
data[].amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data[].amounts.shipping_cost |
no | number:float | null |
0 |
|||
data[].amounts.sum |
no | number:float | null |
39.98 |
|||
data[].amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data[].company_id |
no | integer:int64 | null |
min: 1 | 7 |
||
data[].marking |
yes | OrderMarking |
Marking data expected for products in the order. | |
||
data[].marking.required |
yes | boolean |
Whether the order contains products that require marking data after picking. | true |
||
data[].marking.types |
yes | array<string> |
Marking types required by products in the order. Currently chestny_znak; the list may gain values such as jewel_uin and imei. |
|
||
data[].marking.types[] |
no | string |
"chestny_znak" |
|||
data[].contact |
no | object | null |
|
|||
data[].contact.first_name |
no | string | null |
"Ivan" |
|||
data[].contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data[].contact.last_name |
no | string | null |
"Petrov" |
|||
data[].contact.phone |
no | string | null |
"+359888123456" |
|||
data[].contact.email |
no | string:email | null |
"customer@example.com" |
|||
data[].contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data[].contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data[].contact.postcode |
no | string | null |
"1000" |
|||
data[].contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data[].contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data[].contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data[].delivery |
no | object | null |
|
|||
data[].delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data[].delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data[].delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data[].delivery.status |
no | string | null |
"created" |
|||
data[].delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data[].delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data[].delivery.source_id |
no | string | null |
"cdek-15" |
|||
data[].delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data[].delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data[].delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data[].delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data[].delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data[].delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data[].comments |
no | object | null |
|
|||
data[].comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data[].comments.inner_text |
no | string | null |
"VIP customer" |
|||
data[].offers |
no | array<OrderLineEmbedded> |
|
|||
data[].offers[] |
no | OrderLineEmbedded |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data[].offers[].id |
yes | integer:int64 |
readOnly | min: 1 | 7001 |
|
data[].offers[].product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data[].offers[].quantity |
no | number:float | null |
min: 0 | 2 |
||
data[].offers[].estimated_price |
no | number:float | null |
19.5 |
|||
data[].offers[].price |
no | number:float | null |
19.99 |
|||
data[].offers[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data[].offers[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data[].offers[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data[].offers[].product |
no | object | null |
|
|||
data[].offers[].product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data[].offers[].product.name |
yes | string |
"Coffee 250g" |
|||
data[].offers[].product.external_id |
no | string | null |
"EXT-10045" |
|||
data[].offers[].reservation |
no | OrderReservationLine |
Reservation totals for one order line. | |
||
data[].offers[].reservation.required_qty |
yes | number:float |
3 |
|||
data[].offers[].reservation.reserved_qty |
yes | number:float |
1 |
|||
data[].offers[].reservation.unreserved_qty |
yes | number:float |
2 |
|||
data[].offers[].reservation.missing_qty |
yes | number:float |
2 |
|||
data[].offers[].reservation.status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data[].offers[].reservation_items |
no | array<OrderReservationItem> |
|
|||
data[].offers[].reservation_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data[].offers[].reservation_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data[].offers[].reservation_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data[].offers[].reservation_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data[].offers[].reservation_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data[].offers[].reservation_items[].required_qty |
yes | number:float |
3 |
|||
data[].offers[].reservation_items[].reserved_qty |
yes | number:float |
1 |
|||
data[].offers[].reservation_items[].unreserved_qty |
yes | number:float |
2 |
|||
data[].offers[].reservation_items[].missing_qty |
yes | number:float |
2 |
|||
data[].offers[].reservation_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data[].offers[].reservation_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data[].offers[].reservation_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data[].offers[].reservation_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data[].offers[].reservation_items[].expanded_from_composite |
yes | boolean |
false |
|||
data[].offers[].reservation_items[].expanded_from_quant |
yes | boolean |
false |
|||
data[].offers[].reservation_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data[].offers[].reservation_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data[].offers[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].offers[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].offers[].production_date |
no | string:date | null |
"2026-01-15" |
|||
data[].offers[].requested_lot |
no | WarehouseLot |
|
|||
data[].offers[].requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data[].offers[].requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data[].offers[].requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data[].offers[].picked_quantity |
no | number:float |
min: 0 | 2 |
||
data[].offers[].fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data[].offers[].fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data[].offers[].fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data[].offers[].fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data[].offers[].fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data[].offers[].fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data[].offers[].fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data[].offers[].fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
data[].reservation |
no | OrderReservation |
Reservation readiness and shortages calculated for the order. | |
||
data[].reservation.ready |
yes | boolean |
false |
|||
data[].reservation.reason |
yes | string | null |
"Not all order products are reserved." |
|||
data[].reservation.expected_total |
yes | number:float |
3 |
|||
data[].reservation.reserved_total |
yes | number:float |
1 |
|||
data[].reservation.unreserved_total |
yes | number:float |
2 |
|||
data[].reservation.missing_total |
yes | number:float |
2 |
|||
data[].reservation.missing_items |
yes | array<OrderReservationItem> |
|
|||
data[].reservation.missing_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data[].reservation.missing_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data[].reservation.missing_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data[].reservation.missing_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data[].reservation.missing_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data[].reservation.missing_items[].required_qty |
yes | number:float |
3 |
|||
data[].reservation.missing_items[].reserved_qty |
yes | number:float |
1 |
|||
data[].reservation.missing_items[].unreserved_qty |
yes | number:float |
2 |
|||
data[].reservation.missing_items[].missing_qty |
yes | number:float |
2 |
|||
data[].reservation.missing_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data[].reservation.missing_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data[].reservation.missing_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data[].reservation.missing_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data[].reservation.missing_items[].expanded_from_composite |
yes | boolean |
false |
|||
data[].reservation.missing_items[].expanded_from_quant |
yes | boolean |
false |
|||
data[].reservation.missing_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data[].reservation.missing_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data[].reservation.error |
yes | boolean |
false |
|||
data[].consumables |
no | array<OrderConsumable> |
|
|||
data[].consumables[] |
no | OrderConsumable |
Current consumable line, not an append-only consumption event. Unplaced usage creates a commitment but does not decrease physical stockTotal; do not treat that stockTotal as remaining packaging inventory. | |
||
data[].consumables[].id |
yes | integer:int64 |
min: 1 | 301 |
||
data[].consumables[].order_id |
yes | integer:int64 |
min: 1 | 8101 |
||
data[].consumables[].product_id |
yes | integer:int64 |
min: 1 | 1202 |
||
data[].consumables[].warehouse_id |
yes | integer:int64 | null |
min: 1 | 734 |
||
data[].consumables[].place_id |
yes | integer:int64 | null |
min: 1 | 501 |
||
data[].consumables[].quantity |
yes | number:float |
1 |
|||
data[].consumables[].stock_location_mode |
yes | enum |
enum: placed, unplaced | "unplaced" |
||
data[].consumables[].created_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].consumables[].updated_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].status_history |
no | array<OrderStatusHistoryEvent> |
Present only on GET list/detail with include=status_history. Ordered chronologically, retains repeat status cycles and combines surviving audit and action-log entries. Missing history returns an empty array. | |
||
data[].status_history[] |
no | OrderStatusHistoryEvent |
Recorded WMS status transition or explicitly inferred initial status. It does not independently confirm physical carrier handover. | |
||
data[].status_history[].status_id |
yes | integer:int64 |
130 |
|||
data[].status_history[].previous_status_id |
yes | integer:int64 | null |
110 |
|||
data[].status_history[].changed_at |
yes | string:date-time |
Time of the WMS status transition in ISO 8601 with an explicit timezone offset. | "2026-07-14T12:00:00+03:00" |
||
data[].status_history[].source |
yes | enum |
enum: audit, action_log, inferred | "action_log" |
||
data[].status_history[].inferred |
yes | boolean |
True only for a reconstructed initial status at order creation; this is not a separately recorded transition. | false |
||
data[].status_history_meta |
no | OrderStatusHistoryMeta |
|
|||
data[].status_history_meta.available |
yes | boolean |
At least one event is available. This does not guarantee complete historical coverage. | true |
||
data[].status_history_meta.current_status_matches_history |
yes | boolean |
The last available event has the current order status. False also when history is empty. | true |
||
links |
yes | PaginationLinks |
|
|||
links.first |
yes | string:uri | null |
"https://betawms.ffcdek.ru/api/v2/orders?page=1" |
|||
links.last |
yes | string:uri | null |
"https://betawms.ffcdek.ru/api/v2/orders?page=2" |
|||
links.prev |
yes | string:uri | null |
|
|||
links.next |
yes | string:uri | null |
"https://betawms.ffcdek.ru/api/v2/orders?page=2" |
|||
meta |
yes | PaginationMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.current_page |
yes | integer:int32 |
min: 1 | 1 |
||
meta.from |
yes | integer:int32 | null |
min: 1 | 1 |
||
meta.last_page |
yes | integer:int32 |
min: 1 | 2 |
||
meta.path |
yes | string:uri |
"https://betawms.ffcdek.ru/api/v2/orders" |
|||
meta.per_page |
yes | integer:int32 |
min: 1 | 50 |
||
meta.to |
yes | integer:int32 | null |
min: 1 | 50 |
||
meta.total |
yes | integer:int32 |
min: 0 | 73 |
Response examples
success
{
"data": [
{
"id": 8101,
"external_id": "ORD-100245",
"domain_id": 3,
"type_id": 1,
"shop_id": 12,
"warehouse_id": 42,
"status_id": 20,
"status": {
"id": 20,
"name": "Created",
"color": "#2457c5",
"background_color": "#eaf0ff"
},
"order_date": "2026-07-14",
"send_date": "2026-07-15",
"source_id": 1,
"customer_type": 1,
"is_cod": true,
"amounts": {
"shipping_price": 8.6,
"shipping_cost": 0,
"sum": 39.98,
"cod_sum": 48.58
},
"company_id": 7,
"marking": {
"required": true,
"types": [
"chestny_znak"
]
},
"contact": {
"first_name": "Ivan",
"middle_name": null,
"last_name": "Petrov",
"phone": "+359888123456",
"email": "customer@example.com",
"country_id": 100,
"city_id": 200,
"postcode": "1000",
"latitude": 42.6977,
"longitude": 23.3219,
"full_address": "1 Vitosha Boulevard, Sofia"
},
"delivery": {
"service_id": 1,
"delivery_type": "door",
"is_courier": true,
"status": "created",
"track_number": "CDEK-123456789",
"source_id": "cdek-15",
"tariff_code": 136,
"label": "https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf",
"delivery_date": "2026-07-16",
"delivery_time_start": "09:00:00Z",
"delivery_time_end": "18:00:00Z"
},
"comments": {
"delivery_service_text": "Call before delivery",
"inner_text": "VIP customer"
},
"offers": [
{
"id": 7001,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
}
],
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z",
"status_history": [
{
"status_id": 20,
"previous_status_id": 10,
"changed_at": "2026-07-14T12:00:00+03:00",
"source": "action_log",
"inferred": false
}
],
"status_history_meta": {
"available": true,
"current_status_matches_history": true
}
}
],
"links": {
"first": "https://betawms.ffcdek.ru/api/v2/orders?page=1",
"last": "https://betawms.ffcdek.ru/api/v2/orders?page=2",
"prev": null,
"next": "https://betawms.ffcdek.ru/api/v2/orders?page=2"
},
"meta": {
"api_version": "v2",
"current_page": 1,
"from": 1,
"last_page": 2,
"path": "https://betawms.ffcdek.ru/api/v2/orders",
"per_page": 50,
"to": 50,
"total": 73
}
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Create order
| operationId | createOrders |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Creates an outbound order with public v2 fields. The order may include contact, delivery, comments, and line items. Server-side validation checks shop and warehouse visibility, rejects system-calculated totals, and applies idempotency when Idempotency-Key is provided.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request POST "${NWMS_BASE_URL}/api/v2/orders" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
CreateOrderRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | CreateOrderPayload |
|
|||
data.type_id |
yes | integer:int64 |
1 |
|||
data.shop_id |
yes | integer:int64 |
min: 1 | 12 |
||
data.warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
data.external_id |
no | string | null |
"ORD-100245" |
|||
data.group_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.send_date |
no | string:date | null |
"2026-07-15" |
|||
data.source_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data.customer_type |
no | integer:int64 | null |
1 |
|||
data.is_cod |
no | boolean |
true |
|||
data.company_id |
no | integer:int64 | null |
min: 1 | 7 |
||
data.amounts |
no | object | null |
|
|||
data.amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data.amounts.shipping_cost |
no | number:float | null |
0 |
|||
data.amounts.sum |
no | number:float | null |
39.98 |
|||
data.amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data.weight |
no | object | null |
|
|||
data.weight.value |
no | number:float | null |
min: 0 | 250 |
||
data.weight.unit |
yes | enum |
enum: g | "g" |
||
data.dimensions |
no | object | null |
|
|||
data.dimensions.x |
no | number:float | null |
min: 0 | 105 |
||
data.dimensions.y |
no | number:float | null |
min: 0 | 200 |
||
data.dimensions.z |
no | number:float | null |
min: 0 | 32 |
||
data.dimensions.unit |
yes | enum |
enum: mm | "mm" |
||
data.contact |
no | object | null |
|
|||
data.contact.first_name |
no | string | null |
"Ivan" |
|||
data.contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data.contact.last_name |
no | string | null |
"Petrov" |
|||
data.contact.phone |
no | string | null |
"+359888123456" |
|||
data.contact.email |
no | string:email | null |
"customer@example.com" |
|||
data.contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data.contact.postcode |
no | string | null |
"1000" |
|||
data.contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data.contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data.contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data.delivery |
no | object | null |
|
|||
data.delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data.delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data.delivery.status |
no | string | null |
"created" |
|||
data.delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data.delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data.delivery.source_id |
no | string | null |
"cdek-15" |
|||
data.delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data.delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data.delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data.delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data.delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data.delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data.comments |
no | object | null |
|
|||
data.comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data.comments.inner_text |
no | string | null |
"VIP customer" |
|||
data.lines |
no | array<OrderEmbeddedLineCreatePayload> |
|
|||
data.lines[] |
no | OrderEmbeddedLineCreatePayload |
Line payload used inside order creation. The product is resolved by product_id or product_external_id. |
|
||
data.lines[] |
no | object |
|
|||
data.lines[] |
no | object |
|
Request examples
default
{
"data": {
"type_id": 1,
"shop_id": 12,
"warehouse_id": 42,
"external_id": "ORD-100245",
"send_date": "2026-07-15",
"contact": {
"first_name": "Ivan",
"last_name": "Petrov",
"phone": "+359888123456"
},
"lines": [
{
"product_id": 1201,
"quantity": 2,
"price": 19.99
}
]
}
}
Responses
201 Created.
Created.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | Order |
Outbound warehouse order. Optional relation fields are present when loaded by the controller or requested through include. |
|
||
data.id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data.created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.external_id |
no | string | null |
"ORD-100245" |
|||
data.domain_id |
no | integer:int64 | null |
min: 1 | 3 |
||
data.type_id |
no | integer:int64 | null |
1 |
|||
data.shop_id |
no | integer:int64 | null |
min: 1 | 12 |
||
data.warehouse_id |
no | integer:int64 | null |
min: 1 | 42 |
||
data.status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data.status |
no | object | null |
|
|||
data.status.id |
yes | integer:int64 |
20 |
|||
data.status.name |
yes | string |
"Created" |
|||
data.status.color |
no | string | null |
"#2457c5" |
|||
data.status.background_color |
no | string | null |
"#eaf0ff" |
|||
data.order_date |
no | string:date | null |
"2026-07-14" |
|||
data.send_date |
no | string | null |
Stored order send date, potentially supplied by import, manual input or integration processing. It may be a date or date-time string; it is not a universal physical carrier-handover timestamp. | "2026-07-15 20:25:08" |
||
data.source_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.customer_type |
no | integer:int64 | null |
1 |
|||
data.is_cod |
no | boolean |
true |
|||
data.amounts |
no | OrderAmounts |
|
|||
data.amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data.amounts.shipping_cost |
no | number:float | null |
0 |
|||
data.amounts.sum |
no | number:float | null |
39.98 |
|||
data.amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data.company_id |
no | integer:int64 | null |
min: 1 | 7 |
||
data.marking |
yes | OrderMarking |
Marking data expected for products in the order. | |
||
data.marking.required |
yes | boolean |
Whether the order contains products that require marking data after picking. | true |
||
data.marking.types |
yes | array<string> |
Marking types required by products in the order. Currently chestny_znak; the list may gain values such as jewel_uin and imei. |
|
||
data.marking.types[] |
no | string |
"chestny_znak" |
|||
data.contact |
no | object | null |
|
|||
data.contact.first_name |
no | string | null |
"Ivan" |
|||
data.contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data.contact.last_name |
no | string | null |
"Petrov" |
|||
data.contact.phone |
no | string | null |
"+359888123456" |
|||
data.contact.email |
no | string:email | null |
"customer@example.com" |
|||
data.contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data.contact.postcode |
no | string | null |
"1000" |
|||
data.contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data.contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data.contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data.delivery |
no | object | null |
|
|||
data.delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data.delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data.delivery.status |
no | string | null |
"created" |
|||
data.delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data.delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data.delivery.source_id |
no | string | null |
"cdek-15" |
|||
data.delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data.delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data.delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data.delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data.delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data.delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data.comments |
no | object | null |
|
|||
data.comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data.comments.inner_text |
no | string | null |
"VIP customer" |
|||
data.offers |
no | array<OrderLineEmbedded> |
|
|||
data.offers[] |
no | OrderLineEmbedded |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data.offers[].id |
yes | integer:int64 |
readOnly | min: 1 | 7001 |
|
data.offers[].product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].quantity |
no | number:float | null |
min: 0 | 2 |
||
data.offers[].estimated_price |
no | number:float | null |
19.5 |
|||
data.offers[].price |
no | number:float | null |
19.99 |
|||
data.offers[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.offers[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.offers[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data.offers[].product |
no | object | null |
|
|||
data.offers[].product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data.offers[].product.name |
yes | string |
"Coffee 250g" |
|||
data.offers[].product.external_id |
no | string | null |
"EXT-10045" |
|||
data.offers[].reservation |
no | OrderReservationLine |
Reservation totals for one order line. | |
||
data.offers[].reservation.required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation.reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation.unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items |
no | array<OrderReservationItem> |
|
|||
data.offers[].reservation_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.offers[].reservation_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].reservation_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.offers[].reservation_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.offers[].reservation_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.offers[].reservation_items[].required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation_items[].reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.offers[].reservation_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.offers[].reservation_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.offers[].reservation_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.offers[].reservation_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.offers[].reservation_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].reservation_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.offers[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].production_date |
no | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot |
no | WarehouseLot |
|
|||
data.offers[].requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].picked_quantity |
no | number:float |
min: 0 | 2 |
||
data.offers[].fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data.offers[].fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data.offers[].fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data.offers[].fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
data.reservation |
no | OrderReservation |
Reservation readiness and shortages calculated for the order. | |
||
data.reservation.ready |
yes | boolean |
false |
|||
data.reservation.reason |
yes | string | null |
"Not all order products are reserved." |
|||
data.reservation.expected_total |
yes | number:float |
3 |
|||
data.reservation.reserved_total |
yes | number:float |
1 |
|||
data.reservation.unreserved_total |
yes | number:float |
2 |
|||
data.reservation.missing_total |
yes | number:float |
2 |
|||
data.reservation.missing_items |
yes | array<OrderReservationItem> |
|
|||
data.reservation.missing_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.reservation.missing_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.reservation.missing_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.reservation.missing_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.reservation.missing_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.reservation.missing_items[].required_qty |
yes | number:float |
3 |
|||
data.reservation.missing_items[].reserved_qty |
yes | number:float |
1 |
|||
data.reservation.missing_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].missing_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.reservation.missing_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.reservation.missing_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.reservation.missing_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.reservation.missing_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.reservation.missing_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.reservation.missing_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.reservation.missing_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.reservation.error |
yes | boolean |
false |
|||
data.consumables |
no | array<OrderConsumable> |
|
|||
data.consumables[] |
no | OrderConsumable |
Current consumable line, not an append-only consumption event. Unplaced usage creates a commitment but does not decrease physical stockTotal; do not treat that stockTotal as remaining packaging inventory. | |
||
data.consumables[].id |
yes | integer:int64 |
min: 1 | 301 |
||
data.consumables[].order_id |
yes | integer:int64 |
min: 1 | 8101 |
||
data.consumables[].product_id |
yes | integer:int64 |
min: 1 | 1202 |
||
data.consumables[].warehouse_id |
yes | integer:int64 | null |
min: 1 | 734 |
||
data.consumables[].place_id |
yes | integer:int64 | null |
min: 1 | 501 |
||
data.consumables[].quantity |
yes | number:float |
1 |
|||
data.consumables[].stock_location_mode |
yes | enum |
enum: placed, unplaced | "unplaced" |
||
data.consumables[].created_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.consumables[].updated_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.status_history |
no | array<OrderStatusHistoryEvent> |
Present only on GET list/detail with include=status_history. Ordered chronologically, retains repeat status cycles and combines surviving audit and action-log entries. Missing history returns an empty array. | |
||
data.status_history[] |
no | OrderStatusHistoryEvent |
Recorded WMS status transition or explicitly inferred initial status. It does not independently confirm physical carrier handover. | |
||
data.status_history[].status_id |
yes | integer:int64 |
130 |
|||
data.status_history[].previous_status_id |
yes | integer:int64 | null |
110 |
|||
data.status_history[].changed_at |
yes | string:date-time |
Time of the WMS status transition in ISO 8601 with an explicit timezone offset. | "2026-07-14T12:00:00+03:00" |
||
data.status_history[].source |
yes | enum |
enum: audit, action_log, inferred | "action_log" |
||
data.status_history[].inferred |
yes | boolean |
True only for a reconstructed initial status at order creation; this is not a separately recorded transition. | false |
||
data.status_history_meta |
no | OrderStatusHistoryMeta |
|
|||
data.status_history_meta.available |
yes | boolean |
At least one event is available. This does not guarantee complete historical coverage. | true |
||
data.status_history_meta.current_status_matches_history |
yes | boolean |
The last available event has the current order status. False also when history is empty. | true |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": {
"id": 8101,
"external_id": "ORD-100245",
"domain_id": 3,
"type_id": 1,
"shop_id": 12,
"warehouse_id": 42,
"status_id": 20,
"status": {
"id": 20,
"name": "Created",
"color": "#2457c5",
"background_color": "#eaf0ff"
},
"order_date": "2026-07-14",
"send_date": "2026-07-15",
"source_id": 1,
"customer_type": 1,
"is_cod": true,
"amounts": {
"shipping_price": 8.6,
"shipping_cost": 0,
"sum": 39.98,
"cod_sum": 48.58
},
"company_id": 7,
"marking": {
"required": true,
"types": [
"chestny_znak"
]
},
"contact": {
"first_name": "Ivan",
"middle_name": null,
"last_name": "Petrov",
"phone": "+359888123456",
"email": "customer@example.com",
"country_id": 100,
"city_id": 200,
"postcode": "1000",
"latitude": 42.6977,
"longitude": 23.3219,
"full_address": "1 Vitosha Boulevard, Sofia"
},
"delivery": {
"service_id": 1,
"delivery_type": "door",
"is_courier": true,
"status": "created",
"track_number": "CDEK-123456789",
"source_id": "cdek-15",
"tariff_code": 136,
"label": "https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf",
"delivery_date": "2026-07-16",
"delivery_time_start": "09:00:00Z",
"delivery_time_end": "18:00:00Z"
},
"comments": {
"delivery_service_text": "Call before delivery",
"inner_text": "VIP customer"
},
"offers": [
{
"id": 7001,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
}
],
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
},
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Get order
| operationId | getOrders |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Returns one order when it exists and is visible to the authenticated account.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Request include=status_history to receive chronological WMS status transitions with changed_at (ISO 8601 and explicit timezone offset), source and inferred. status_history_meta reports availability and whether the last event matches the current status; surviving logs do not guarantee a complete history. send_date is the stored order date field and may come from import, manual input or integration processing; it is not a universal physical carrier-handover timestamp. Status transitions and shipment-document closure must be interpreted as separate recorded events. Dedicated picked_at, packed_at and shipped_at milestones are not exposed.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request GET "${NWMS_BASE_URL}/api/v2/orders/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}"Parameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
include |
query | no | string |
form | false | Add status_history for recorded WMS status transitions; the other detail relations remain included by default. The same filter may also be sent as filter[include] where supported by the Laravel query adapter. |
"status_history" |
Request body
No request body.
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | Order |
Outbound warehouse order. Optional relation fields are present when loaded by the controller or requested through include. |
|
||
data.id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data.created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.external_id |
no | string | null |
"ORD-100245" |
|||
data.domain_id |
no | integer:int64 | null |
min: 1 | 3 |
||
data.type_id |
no | integer:int64 | null |
1 |
|||
data.shop_id |
no | integer:int64 | null |
min: 1 | 12 |
||
data.warehouse_id |
no | integer:int64 | null |
min: 1 | 42 |
||
data.status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data.status |
no | object | null |
|
|||
data.status.id |
yes | integer:int64 |
20 |
|||
data.status.name |
yes | string |
"Created" |
|||
data.status.color |
no | string | null |
"#2457c5" |
|||
data.status.background_color |
no | string | null |
"#eaf0ff" |
|||
data.order_date |
no | string:date | null |
"2026-07-14" |
|||
data.send_date |
no | string | null |
Stored order send date, potentially supplied by import, manual input or integration processing. It may be a date or date-time string; it is not a universal physical carrier-handover timestamp. | "2026-07-15 20:25:08" |
||
data.source_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.customer_type |
no | integer:int64 | null |
1 |
|||
data.is_cod |
no | boolean |
true |
|||
data.amounts |
no | OrderAmounts |
|
|||
data.amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data.amounts.shipping_cost |
no | number:float | null |
0 |
|||
data.amounts.sum |
no | number:float | null |
39.98 |
|||
data.amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data.company_id |
no | integer:int64 | null |
min: 1 | 7 |
||
data.marking |
yes | OrderMarking |
Marking data expected for products in the order. | |
||
data.marking.required |
yes | boolean |
Whether the order contains products that require marking data after picking. | true |
||
data.marking.types |
yes | array<string> |
Marking types required by products in the order. Currently chestny_znak; the list may gain values such as jewel_uin and imei. |
|
||
data.marking.types[] |
no | string |
"chestny_znak" |
|||
data.contact |
no | object | null |
|
|||
data.contact.first_name |
no | string | null |
"Ivan" |
|||
data.contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data.contact.last_name |
no | string | null |
"Petrov" |
|||
data.contact.phone |
no | string | null |
"+359888123456" |
|||
data.contact.email |
no | string:email | null |
"customer@example.com" |
|||
data.contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data.contact.postcode |
no | string | null |
"1000" |
|||
data.contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data.contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data.contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data.delivery |
no | object | null |
|
|||
data.delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data.delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data.delivery.status |
no | string | null |
"created" |
|||
data.delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data.delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data.delivery.source_id |
no | string | null |
"cdek-15" |
|||
data.delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data.delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data.delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data.delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data.delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data.delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data.comments |
no | object | null |
|
|||
data.comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data.comments.inner_text |
no | string | null |
"VIP customer" |
|||
data.offers |
no | array<OrderLineEmbedded> |
|
|||
data.offers[] |
no | OrderLineEmbedded |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data.offers[].id |
yes | integer:int64 |
readOnly | min: 1 | 7001 |
|
data.offers[].product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].quantity |
no | number:float | null |
min: 0 | 2 |
||
data.offers[].estimated_price |
no | number:float | null |
19.5 |
|||
data.offers[].price |
no | number:float | null |
19.99 |
|||
data.offers[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.offers[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.offers[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data.offers[].product |
no | object | null |
|
|||
data.offers[].product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data.offers[].product.name |
yes | string |
"Coffee 250g" |
|||
data.offers[].product.external_id |
no | string | null |
"EXT-10045" |
|||
data.offers[].reservation |
no | OrderReservationLine |
Reservation totals for one order line. | |
||
data.offers[].reservation.required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation.reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation.unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items |
no | array<OrderReservationItem> |
|
|||
data.offers[].reservation_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.offers[].reservation_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].reservation_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.offers[].reservation_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.offers[].reservation_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.offers[].reservation_items[].required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation_items[].reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.offers[].reservation_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.offers[].reservation_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.offers[].reservation_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.offers[].reservation_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.offers[].reservation_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].reservation_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.offers[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].production_date |
no | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot |
no | WarehouseLot |
|
|||
data.offers[].requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].picked_quantity |
no | number:float |
min: 0 | 2 |
||
data.offers[].fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data.offers[].fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data.offers[].fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data.offers[].fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
data.reservation |
no | OrderReservation |
Reservation readiness and shortages calculated for the order. | |
||
data.reservation.ready |
yes | boolean |
false |
|||
data.reservation.reason |
yes | string | null |
"Not all order products are reserved." |
|||
data.reservation.expected_total |
yes | number:float |
3 |
|||
data.reservation.reserved_total |
yes | number:float |
1 |
|||
data.reservation.unreserved_total |
yes | number:float |
2 |
|||
data.reservation.missing_total |
yes | number:float |
2 |
|||
data.reservation.missing_items |
yes | array<OrderReservationItem> |
|
|||
data.reservation.missing_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.reservation.missing_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.reservation.missing_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.reservation.missing_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.reservation.missing_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.reservation.missing_items[].required_qty |
yes | number:float |
3 |
|||
data.reservation.missing_items[].reserved_qty |
yes | number:float |
1 |
|||
data.reservation.missing_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].missing_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.reservation.missing_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.reservation.missing_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.reservation.missing_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.reservation.missing_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.reservation.missing_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.reservation.missing_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.reservation.missing_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.reservation.error |
yes | boolean |
false |
|||
data.consumables |
no | array<OrderConsumable> |
|
|||
data.consumables[] |
no | OrderConsumable |
Current consumable line, not an append-only consumption event. Unplaced usage creates a commitment but does not decrease physical stockTotal; do not treat that stockTotal as remaining packaging inventory. | |
||
data.consumables[].id |
yes | integer:int64 |
min: 1 | 301 |
||
data.consumables[].order_id |
yes | integer:int64 |
min: 1 | 8101 |
||
data.consumables[].product_id |
yes | integer:int64 |
min: 1 | 1202 |
||
data.consumables[].warehouse_id |
yes | integer:int64 | null |
min: 1 | 734 |
||
data.consumables[].place_id |
yes | integer:int64 | null |
min: 1 | 501 |
||
data.consumables[].quantity |
yes | number:float |
1 |
|||
data.consumables[].stock_location_mode |
yes | enum |
enum: placed, unplaced | "unplaced" |
||
data.consumables[].created_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.consumables[].updated_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.status_history |
no | array<OrderStatusHistoryEvent> |
Present only on GET list/detail with include=status_history. Ordered chronologically, retains repeat status cycles and combines surviving audit and action-log entries. Missing history returns an empty array. | |
||
data.status_history[] |
no | OrderStatusHistoryEvent |
Recorded WMS status transition or explicitly inferred initial status. It does not independently confirm physical carrier handover. | |
||
data.status_history[].status_id |
yes | integer:int64 |
130 |
|||
data.status_history[].previous_status_id |
yes | integer:int64 | null |
110 |
|||
data.status_history[].changed_at |
yes | string:date-time |
Time of the WMS status transition in ISO 8601 with an explicit timezone offset. | "2026-07-14T12:00:00+03:00" |
||
data.status_history[].source |
yes | enum |
enum: audit, action_log, inferred | "action_log" |
||
data.status_history[].inferred |
yes | boolean |
True only for a reconstructed initial status at order creation; this is not a separately recorded transition. | false |
||
data.status_history_meta |
no | OrderStatusHistoryMeta |
|
|||
data.status_history_meta.available |
yes | boolean |
At least one event is available. This does not guarantee complete historical coverage. | true |
||
data.status_history_meta.current_status_matches_history |
yes | boolean |
The last available event has the current order status. False also when history is empty. | true |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": {
"id": 8101,
"external_id": "ORD-100245",
"domain_id": 3,
"type_id": 1,
"shop_id": 12,
"warehouse_id": 42,
"status_id": 20,
"status": {
"id": 20,
"name": "Created",
"color": "#2457c5",
"background_color": "#eaf0ff"
},
"order_date": "2026-07-14",
"send_date": "2026-07-15",
"source_id": 1,
"customer_type": 1,
"is_cod": true,
"amounts": {
"shipping_price": 8.6,
"shipping_cost": 0,
"sum": 39.98,
"cod_sum": 48.58
},
"company_id": 7,
"marking": {
"required": true,
"types": [
"chestny_znak"
]
},
"contact": {
"first_name": "Ivan",
"middle_name": null,
"last_name": "Petrov",
"phone": "+359888123456",
"email": "customer@example.com",
"country_id": 100,
"city_id": 200,
"postcode": "1000",
"latitude": 42.6977,
"longitude": 23.3219,
"full_address": "1 Vitosha Boulevard, Sofia"
},
"delivery": {
"service_id": 1,
"delivery_type": "door",
"is_courier": true,
"status": "created",
"track_number": "CDEK-123456789",
"source_id": "cdek-15",
"tariff_code": 136,
"label": "https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf",
"delivery_date": "2026-07-16",
"delivery_time_start": "09:00:00Z",
"delivery_time_end": "18:00:00Z"
},
"comments": {
"delivery_service_text": "Call before delivery",
"inner_text": "VIP customer"
},
"offers": [
{
"id": 7001,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
}
],
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z",
"status_history": [
{
"status_id": 20,
"previous_status_id": 10,
"changed_at": "2026-07-14T12:00:00+03:00",
"source": "action_log",
"inferred": false
}
],
"status_history_meta": {
"available": true,
"current_status_matches_history": true
}
},
"meta": {
"api_version": "v2"
}
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Update order
| operationId | replaceOrders |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Replaces editable order fields before the lifecycle reaches a locked status. Contact, delivery, comments, dimensions, and selected header fields may be changed; system totals remain server-calculated.
Current backend behavior is legacy partial-update semantics: omitted fields are left unchanged.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request PUT "${NWMS_BASE_URL}/api/v2/orders/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
ReplaceOrderRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | ReplaceOrderPayload |
Legacy PUT payload. Current backend applies partial-update semantics and leaves omitted fields unchanged. | |
||
data.external_id |
no | string | null |
"ORD-100245" |
|||
data.send_date |
no | string:date | null |
"2026-07-16" |
|||
data.status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data.is_cod |
no | boolean |
true |
|||
data.amounts |
no | object | null |
|
|||
data.amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data.amounts.shipping_cost |
no | number:float | null |
0 |
|||
data.amounts.sum |
no | number:float | null |
39.98 |
|||
data.amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data.weight |
no | object | null |
|
|||
data.weight.value |
no | number:float | null |
min: 0 | 250 |
||
data.weight.unit |
yes | enum |
enum: g | "g" |
||
data.dimensions |
no | object | null |
|
|||
data.dimensions.x |
no | number:float | null |
min: 0 | 105 |
||
data.dimensions.y |
no | number:float | null |
min: 0 | 200 |
||
data.dimensions.z |
no | number:float | null |
min: 0 | 32 |
||
data.dimensions.unit |
yes | enum |
enum: mm | "mm" |
||
data.contact |
no | object | null |
|
|||
data.contact.first_name |
no | string | null |
"Ivan" |
|||
data.contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data.contact.last_name |
no | string | null |
"Petrov" |
|||
data.contact.phone |
no | string | null |
"+359888123456" |
|||
data.contact.email |
no | string:email | null |
"customer@example.com" |
|||
data.contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data.contact.postcode |
no | string | null |
"1000" |
|||
data.contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data.contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data.contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data.delivery |
no | object | null |
|
|||
data.delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data.delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data.delivery.status |
no | string | null |
"created" |
|||
data.delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data.delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data.delivery.source_id |
no | string | null |
"cdek-15" |
|||
data.delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data.delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data.delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data.delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data.delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data.delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data.comments |
no | object | null |
|
|||
data.comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data.comments.inner_text |
no | string | null |
"VIP customer" |
Request examples
default
{
"data": {
"send_date": "2026-07-16",
"comments": {
"inner_text": "Priority shipment"
}
}
}
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | Order |
Outbound warehouse order. Optional relation fields are present when loaded by the controller or requested through include. |
|
||
data.id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data.created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.external_id |
no | string | null |
"ORD-100245" |
|||
data.domain_id |
no | integer:int64 | null |
min: 1 | 3 |
||
data.type_id |
no | integer:int64 | null |
1 |
|||
data.shop_id |
no | integer:int64 | null |
min: 1 | 12 |
||
data.warehouse_id |
no | integer:int64 | null |
min: 1 | 42 |
||
data.status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data.status |
no | object | null |
|
|||
data.status.id |
yes | integer:int64 |
20 |
|||
data.status.name |
yes | string |
"Created" |
|||
data.status.color |
no | string | null |
"#2457c5" |
|||
data.status.background_color |
no | string | null |
"#eaf0ff" |
|||
data.order_date |
no | string:date | null |
"2026-07-14" |
|||
data.send_date |
no | string | null |
Stored order send date, potentially supplied by import, manual input or integration processing. It may be a date or date-time string; it is not a universal physical carrier-handover timestamp. | "2026-07-15 20:25:08" |
||
data.source_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.customer_type |
no | integer:int64 | null |
1 |
|||
data.is_cod |
no | boolean |
true |
|||
data.amounts |
no | OrderAmounts |
|
|||
data.amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data.amounts.shipping_cost |
no | number:float | null |
0 |
|||
data.amounts.sum |
no | number:float | null |
39.98 |
|||
data.amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data.company_id |
no | integer:int64 | null |
min: 1 | 7 |
||
data.marking |
yes | OrderMarking |
Marking data expected for products in the order. | |
||
data.marking.required |
yes | boolean |
Whether the order contains products that require marking data after picking. | true |
||
data.marking.types |
yes | array<string> |
Marking types required by products in the order. Currently chestny_znak; the list may gain values such as jewel_uin and imei. |
|
||
data.marking.types[] |
no | string |
"chestny_znak" |
|||
data.contact |
no | object | null |
|
|||
data.contact.first_name |
no | string | null |
"Ivan" |
|||
data.contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data.contact.last_name |
no | string | null |
"Petrov" |
|||
data.contact.phone |
no | string | null |
"+359888123456" |
|||
data.contact.email |
no | string:email | null |
"customer@example.com" |
|||
data.contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data.contact.postcode |
no | string | null |
"1000" |
|||
data.contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data.contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data.contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data.delivery |
no | object | null |
|
|||
data.delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data.delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data.delivery.status |
no | string | null |
"created" |
|||
data.delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data.delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data.delivery.source_id |
no | string | null |
"cdek-15" |
|||
data.delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data.delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data.delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data.delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data.delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data.delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data.comments |
no | object | null |
|
|||
data.comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data.comments.inner_text |
no | string | null |
"VIP customer" |
|||
data.offers |
no | array<OrderLineEmbedded> |
|
|||
data.offers[] |
no | OrderLineEmbedded |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data.offers[].id |
yes | integer:int64 |
readOnly | min: 1 | 7001 |
|
data.offers[].product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].quantity |
no | number:float | null |
min: 0 | 2 |
||
data.offers[].estimated_price |
no | number:float | null |
19.5 |
|||
data.offers[].price |
no | number:float | null |
19.99 |
|||
data.offers[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.offers[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.offers[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data.offers[].product |
no | object | null |
|
|||
data.offers[].product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data.offers[].product.name |
yes | string |
"Coffee 250g" |
|||
data.offers[].product.external_id |
no | string | null |
"EXT-10045" |
|||
data.offers[].reservation |
no | OrderReservationLine |
Reservation totals for one order line. | |
||
data.offers[].reservation.required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation.reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation.unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items |
no | array<OrderReservationItem> |
|
|||
data.offers[].reservation_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.offers[].reservation_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].reservation_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.offers[].reservation_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.offers[].reservation_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.offers[].reservation_items[].required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation_items[].reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.offers[].reservation_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.offers[].reservation_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.offers[].reservation_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.offers[].reservation_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.offers[].reservation_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].reservation_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.offers[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].production_date |
no | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot |
no | WarehouseLot |
|
|||
data.offers[].requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].picked_quantity |
no | number:float |
min: 0 | 2 |
||
data.offers[].fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data.offers[].fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data.offers[].fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data.offers[].fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
data.reservation |
no | OrderReservation |
Reservation readiness and shortages calculated for the order. | |
||
data.reservation.ready |
yes | boolean |
false |
|||
data.reservation.reason |
yes | string | null |
"Not all order products are reserved." |
|||
data.reservation.expected_total |
yes | number:float |
3 |
|||
data.reservation.reserved_total |
yes | number:float |
1 |
|||
data.reservation.unreserved_total |
yes | number:float |
2 |
|||
data.reservation.missing_total |
yes | number:float |
2 |
|||
data.reservation.missing_items |
yes | array<OrderReservationItem> |
|
|||
data.reservation.missing_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.reservation.missing_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.reservation.missing_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.reservation.missing_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.reservation.missing_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.reservation.missing_items[].required_qty |
yes | number:float |
3 |
|||
data.reservation.missing_items[].reserved_qty |
yes | number:float |
1 |
|||
data.reservation.missing_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].missing_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.reservation.missing_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.reservation.missing_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.reservation.missing_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.reservation.missing_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.reservation.missing_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.reservation.missing_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.reservation.missing_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.reservation.error |
yes | boolean |
false |
|||
data.consumables |
no | array<OrderConsumable> |
|
|||
data.consumables[] |
no | OrderConsumable |
Current consumable line, not an append-only consumption event. Unplaced usage creates a commitment but does not decrease physical stockTotal; do not treat that stockTotal as remaining packaging inventory. | |
||
data.consumables[].id |
yes | integer:int64 |
min: 1 | 301 |
||
data.consumables[].order_id |
yes | integer:int64 |
min: 1 | 8101 |
||
data.consumables[].product_id |
yes | integer:int64 |
min: 1 | 1202 |
||
data.consumables[].warehouse_id |
yes | integer:int64 | null |
min: 1 | 734 |
||
data.consumables[].place_id |
yes | integer:int64 | null |
min: 1 | 501 |
||
data.consumables[].quantity |
yes | number:float |
1 |
|||
data.consumables[].stock_location_mode |
yes | enum |
enum: placed, unplaced | "unplaced" |
||
data.consumables[].created_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.consumables[].updated_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.status_history |
no | array<OrderStatusHistoryEvent> |
Present only on GET list/detail with include=status_history. Ordered chronologically, retains repeat status cycles and combines surviving audit and action-log entries. Missing history returns an empty array. | |
||
data.status_history[] |
no | OrderStatusHistoryEvent |
Recorded WMS status transition or explicitly inferred initial status. It does not independently confirm physical carrier handover. | |
||
data.status_history[].status_id |
yes | integer:int64 |
130 |
|||
data.status_history[].previous_status_id |
yes | integer:int64 | null |
110 |
|||
data.status_history[].changed_at |
yes | string:date-time |
Time of the WMS status transition in ISO 8601 with an explicit timezone offset. | "2026-07-14T12:00:00+03:00" |
||
data.status_history[].source |
yes | enum |
enum: audit, action_log, inferred | "action_log" |
||
data.status_history[].inferred |
yes | boolean |
True only for a reconstructed initial status at order creation; this is not a separately recorded transition. | false |
||
data.status_history_meta |
no | OrderStatusHistoryMeta |
|
|||
data.status_history_meta.available |
yes | boolean |
At least one event is available. This does not guarantee complete historical coverage. | true |
||
data.status_history_meta.current_status_matches_history |
yes | boolean |
The last available event has the current order status. False also when history is empty. | true |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": {
"id": 8101,
"external_id": "ORD-100245",
"domain_id": 3,
"type_id": 1,
"shop_id": 12,
"warehouse_id": 42,
"status_id": 20,
"status": {
"id": 20,
"name": "Created",
"color": "#2457c5",
"background_color": "#eaf0ff"
},
"order_date": "2026-07-14",
"send_date": "2026-07-15",
"source_id": 1,
"customer_type": 1,
"is_cod": true,
"amounts": {
"shipping_price": 8.6,
"shipping_cost": 0,
"sum": 39.98,
"cod_sum": 48.58
},
"company_id": 7,
"marking": {
"required": true,
"types": [
"chestny_znak"
]
},
"contact": {
"first_name": "Ivan",
"middle_name": null,
"last_name": "Petrov",
"phone": "+359888123456",
"email": "customer@example.com",
"country_id": 100,
"city_id": 200,
"postcode": "1000",
"latitude": 42.6977,
"longitude": 23.3219,
"full_address": "1 Vitosha Boulevard, Sofia"
},
"delivery": {
"service_id": 1,
"delivery_type": "door",
"is_courier": true,
"status": "created",
"track_number": "CDEK-123456789",
"source_id": "cdek-15",
"tariff_code": 136,
"label": "https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf",
"delivery_date": "2026-07-16",
"delivery_time_start": "09:00:00Z",
"delivery_time_end": "18:00:00Z"
},
"comments": {
"delivery_service_text": "Call before delivery",
"inner_text": "VIP customer"
},
"offers": [
{
"id": 7001,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
}
],
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
},
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Update order
| operationId | patchOrders |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Partially updates editable order fields. Omitted fields are left unchanged and the same lifecycle, data-scope, and idempotency rules as PUT /api/v2/orders/{id} apply.
Current backend behavior is legacy partial-update semantics: omitted fields are left unchanged.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request PATCH "${NWMS_BASE_URL}/api/v2/orders/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
PatchOrderRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | PatchOrderPayload |
Partial order update payload. Omitted fields are unchanged. | |
||
data.external_id |
no | string | null |
"ORD-100245" |
|||
data.send_date |
no | string:date | null |
"2026-07-16" |
|||
data.status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data.is_cod |
no | boolean |
true |
|||
data.amounts |
no | object | null |
|
|||
data.amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data.amounts.shipping_cost |
no | number:float | null |
0 |
|||
data.amounts.sum |
no | number:float | null |
39.98 |
|||
data.amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data.weight |
no | object | null |
|
|||
data.weight.value |
no | number:float | null |
min: 0 | 250 |
||
data.weight.unit |
yes | enum |
enum: g | "g" |
||
data.dimensions |
no | object | null |
|
|||
data.dimensions.x |
no | number:float | null |
min: 0 | 105 |
||
data.dimensions.y |
no | number:float | null |
min: 0 | 200 |
||
data.dimensions.z |
no | number:float | null |
min: 0 | 32 |
||
data.dimensions.unit |
yes | enum |
enum: mm | "mm" |
||
data.contact |
no | object | null |
|
|||
data.contact.first_name |
no | string | null |
"Ivan" |
|||
data.contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data.contact.last_name |
no | string | null |
"Petrov" |
|||
data.contact.phone |
no | string | null |
"+359888123456" |
|||
data.contact.email |
no | string:email | null |
"customer@example.com" |
|||
data.contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data.contact.postcode |
no | string | null |
"1000" |
|||
data.contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data.contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data.contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data.delivery |
no | object | null |
|
|||
data.delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data.delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data.delivery.status |
no | string | null |
"created" |
|||
data.delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data.delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data.delivery.source_id |
no | string | null |
"cdek-15" |
|||
data.delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data.delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data.delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data.delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data.delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data.delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data.comments |
no | object | null |
|
|||
data.comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data.comments.inner_text |
no | string | null |
"VIP customer" |
Request examples
default
{
"data": {
"send_date": "2026-07-16"
}
}
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | Order |
Outbound warehouse order. Optional relation fields are present when loaded by the controller or requested through include. |
|
||
data.id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data.created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.external_id |
no | string | null |
"ORD-100245" |
|||
data.domain_id |
no | integer:int64 | null |
min: 1 | 3 |
||
data.type_id |
no | integer:int64 | null |
1 |
|||
data.shop_id |
no | integer:int64 | null |
min: 1 | 12 |
||
data.warehouse_id |
no | integer:int64 | null |
min: 1 | 42 |
||
data.status_id |
no | integer:int64 | null |
Order status ID. The current backend stores status records in the database; values are not modeled as a closed enum in the public contract. | 20 |
||
data.status |
no | object | null |
|
|||
data.status.id |
yes | integer:int64 |
20 |
|||
data.status.name |
yes | string |
"Created" |
|||
data.status.color |
no | string | null |
"#2457c5" |
|||
data.status.background_color |
no | string | null |
"#eaf0ff" |
|||
data.order_date |
no | string:date | null |
"2026-07-14" |
|||
data.send_date |
no | string | null |
Stored order send date, potentially supplied by import, manual input or integration processing. It may be a date or date-time string; it is not a universal physical carrier-handover timestamp. | "2026-07-15 20:25:08" |
||
data.source_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.customer_type |
no | integer:int64 | null |
1 |
|||
data.is_cod |
no | boolean |
true |
|||
data.amounts |
no | OrderAmounts |
|
|||
data.amounts.shipping_price |
no | number:float | null |
8.6 |
|||
data.amounts.shipping_cost |
no | number:float | null |
0 |
|||
data.amounts.sum |
no | number:float | null |
39.98 |
|||
data.amounts.cod_sum |
no | number:float | null |
48.58 |
|||
data.company_id |
no | integer:int64 | null |
min: 1 | 7 |
||
data.marking |
yes | OrderMarking |
Marking data expected for products in the order. | |
||
data.marking.required |
yes | boolean |
Whether the order contains products that require marking data after picking. | true |
||
data.marking.types |
yes | array<string> |
Marking types required by products in the order. Currently chestny_znak; the list may gain values such as jewel_uin and imei. |
|
||
data.marking.types[] |
no | string |
"chestny_znak" |
|||
data.contact |
no | object | null |
|
|||
data.contact.first_name |
no | string | null |
"Ivan" |
|||
data.contact.middle_name |
no | string | null |
"Ivanovich" |
|||
data.contact.last_name |
no | string | null |
"Petrov" |
|||
data.contact.phone |
no | string | null |
"+359888123456" |
|||
data.contact.email |
no | string:email | null |
"customer@example.com" |
|||
data.contact.country_id |
no | integer:int64 | null |
min: 1 | 100 |
||
data.contact.city_id |
no | integer:int64 | null |
min: 1 | 200 |
||
data.contact.postcode |
no | string | null |
"1000" |
|||
data.contact.latitude |
no | number:float | null |
min: -90 max: 90 |
42.6977 |
||
data.contact.longitude |
no | number:float | null |
min: -180 max: 180 |
23.3219 |
||
data.contact.full_address |
no | string | null |
"1 Vitosha Boulevard, Sofia" |
|||
data.delivery |
no | object | null |
|
|||
data.delivery.service_id |
no | integer:int64 | null |
min: 1 | 1 |
||
data.delivery.delivery_type |
yes | enum | null |
enum: door, pickup_point | Normalized delivery channel derived from the configured delivery service. Null when the service type is unknown. | "door" |
|
data.delivery.is_courier |
yes | boolean |
True for door delivery; false for pickup-point delivery or an unknown service type. | true |
||
data.delivery.status |
no | string | null |
"created" |
|||
data.delivery.track_number |
no | string | null |
"CDEK-123456789" |
|||
data.delivery.pickup_point_id |
no | string | null |
"SOFIA-01" |
|||
data.delivery.source_id |
no | string | null |
"cdek-15" |
|||
data.delivery.tariff_code |
no | integer:int64 | null |
136 |
|||
data.delivery.additional_services |
no | object |
Values of additional CDEK services configured for the selected integration. Boolean true enables a code-only service; other values are sent as the CDEK parameter. |
{"TRYING_ON":true,"PART_DELIV":false,"PACKAGE_1":2} |
||
data.delivery.label |
no | string:uri | null |
"https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf" |
|||
data.delivery.delivery_date |
no | string:date | null |
"2026-07-16" |
|||
data.delivery.delivery_time_start |
no | string:time | null |
"09:00:00Z" |
|||
data.delivery.delivery_time_end |
no | string:time | null |
"18:00:00Z" |
|||
data.comments |
no | object | null |
|
|||
data.comments.delivery_service_text |
no | string | null |
"Call before delivery" |
|||
data.comments.inner_text |
no | string | null |
"VIP customer" |
|||
data.offers |
no | array<OrderLineEmbedded> |
|
|||
data.offers[] |
no | OrderLineEmbedded |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data.offers[].id |
yes | integer:int64 |
readOnly | min: 1 | 7001 |
|
data.offers[].product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].quantity |
no | number:float | null |
min: 0 | 2 |
||
data.offers[].estimated_price |
no | number:float | null |
19.5 |
|||
data.offers[].price |
no | number:float | null |
19.99 |
|||
data.offers[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.offers[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.offers[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data.offers[].product |
no | object | null |
|
|||
data.offers[].product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data.offers[].product.name |
yes | string |
"Coffee 250g" |
|||
data.offers[].product.external_id |
no | string | null |
"EXT-10045" |
|||
data.offers[].reservation |
no | OrderReservationLine |
Reservation totals for one order line. | |
||
data.offers[].reservation.required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation.reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation.unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation.status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items |
no | array<OrderReservationItem> |
|
|||
data.offers[].reservation_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.offers[].reservation_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].reservation_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.offers[].reservation_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.offers[].reservation_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.offers[].reservation_items[].required_qty |
yes | number:float |
3 |
|||
data.offers[].reservation_items[].reserved_qty |
yes | number:float |
1 |
|||
data.offers[].reservation_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].missing_qty |
yes | number:float |
2 |
|||
data.offers[].reservation_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.offers[].reservation_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.offers[].reservation_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.offers[].reservation_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.offers[].reservation_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.offers[].reservation_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.offers[].reservation_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.offers[].reservation_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.offers[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.offers[].production_date |
no | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot |
no | WarehouseLot |
|
|||
data.offers[].requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].picked_quantity |
no | number:float |
min: 0 | 2 |
||
data.offers[].fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data.offers[].fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data.offers[].fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data.offers[].fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.offers[].fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.offers[].fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data.offers[].fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.offers[].fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
data.reservation |
no | OrderReservation |
Reservation readiness and shortages calculated for the order. | |
||
data.reservation.ready |
yes | boolean |
false |
|||
data.reservation.reason |
yes | string | null |
"Not all order products are reserved." |
|||
data.reservation.expected_total |
yes | number:float |
3 |
|||
data.reservation.reserved_total |
yes | number:float |
1 |
|||
data.reservation.unreserved_total |
yes | number:float |
2 |
|||
data.reservation.missing_total |
yes | number:float |
2 |
|||
data.reservation.missing_items |
yes | array<OrderReservationItem> |
|
|||
data.reservation.missing_items[] |
no | OrderReservationItem |
Physical product or expanded component used to explain a reservation shortage. | |
||
data.reservation.missing_items[].offer_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.reservation.missing_items[].offer_name |
no | string | null |
"Coffee 250g" |
|||
data.reservation.missing_items[].offer_article |
no | string | null |
"ART-001245" |
|||
data.reservation.missing_items[].offer_sku |
no | string | null |
"SKU-001245" |
|||
data.reservation.missing_items[].required_qty |
yes | number:float |
3 |
|||
data.reservation.missing_items[].reserved_qty |
yes | number:float |
1 |
|||
data.reservation.missing_items[].unreserved_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].missing_qty |
yes | number:float |
2 |
|||
data.reservation.missing_items[].status |
yes | enum |
enum: not_required, missing, partial, reserved | Reservation state calculated from the quantity required by the order and the quantity actually reserved. | "partial" |
|
data.reservation.missing_items[].source_order_offer_ids |
yes | array<integer:int64> |
|
|||
data.reservation.missing_items[].source_order_offer_ids[] |
no | integer:int64 |
min: 1 | 7001 |
||
data.reservation.missing_items[].source |
yes | enum |
enum: order_offer, component, quant, composite_quant | "order_offer" |
||
data.reservation.missing_items[].expanded_from_composite |
yes | boolean |
false |
|||
data.reservation.missing_items[].expanded_from_quant |
yes | boolean |
false |
|||
data.reservation.missing_items[].quant_base_offer_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.reservation.missing_items[].quant_base_multiplicity |
no | number:float | null |
6 |
|||
data.reservation.error |
yes | boolean |
false |
|||
data.consumables |
no | array<OrderConsumable> |
|
|||
data.consumables[] |
no | OrderConsumable |
Current consumable line, not an append-only consumption event. Unplaced usage creates a commitment but does not decrease physical stockTotal; do not treat that stockTotal as remaining packaging inventory. | |
||
data.consumables[].id |
yes | integer:int64 |
min: 1 | 301 |
||
data.consumables[].order_id |
yes | integer:int64 |
min: 1 | 8101 |
||
data.consumables[].product_id |
yes | integer:int64 |
min: 1 | 1202 |
||
data.consumables[].warehouse_id |
yes | integer:int64 | null |
min: 1 | 734 |
||
data.consumables[].place_id |
yes | integer:int64 | null |
min: 1 | 501 |
||
data.consumables[].quantity |
yes | number:float |
1 |
|||
data.consumables[].stock_location_mode |
yes | enum |
enum: placed, unplaced | "unplaced" |
||
data.consumables[].created_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.consumables[].updated_at |
yes | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.status_history |
no | array<OrderStatusHistoryEvent> |
Present only on GET list/detail with include=status_history. Ordered chronologically, retains repeat status cycles and combines surviving audit and action-log entries. Missing history returns an empty array. | |
||
data.status_history[] |
no | OrderStatusHistoryEvent |
Recorded WMS status transition or explicitly inferred initial status. It does not independently confirm physical carrier handover. | |
||
data.status_history[].status_id |
yes | integer:int64 |
130 |
|||
data.status_history[].previous_status_id |
yes | integer:int64 | null |
110 |
|||
data.status_history[].changed_at |
yes | string:date-time |
Time of the WMS status transition in ISO 8601 with an explicit timezone offset. | "2026-07-14T12:00:00+03:00" |
||
data.status_history[].source |
yes | enum |
enum: audit, action_log, inferred | "action_log" |
||
data.status_history[].inferred |
yes | boolean |
True only for a reconstructed initial status at order creation; this is not a separately recorded transition. | false |
||
data.status_history_meta |
no | OrderStatusHistoryMeta |
|
|||
data.status_history_meta.available |
yes | boolean |
At least one event is available. This does not guarantee complete historical coverage. | true |
||
data.status_history_meta.current_status_matches_history |
yes | boolean |
The last available event has the current order status. False also when history is empty. | true |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": {
"id": 8101,
"external_id": "ORD-100245",
"domain_id": 3,
"type_id": 1,
"shop_id": 12,
"warehouse_id": 42,
"status_id": 20,
"status": {
"id": 20,
"name": "Created",
"color": "#2457c5",
"background_color": "#eaf0ff"
},
"order_date": "2026-07-14",
"send_date": "2026-07-15",
"source_id": 1,
"customer_type": 1,
"is_cod": true,
"amounts": {
"shipping_price": 8.6,
"shipping_cost": 0,
"sum": 39.98,
"cod_sum": 48.58
},
"company_id": 7,
"marking": {
"required": true,
"types": [
"chestny_znak"
]
},
"contact": {
"first_name": "Ivan",
"middle_name": null,
"last_name": "Petrov",
"phone": "+359888123456",
"email": "customer@example.com",
"country_id": 100,
"city_id": 200,
"postcode": "1000",
"latitude": 42.6977,
"longitude": 23.3219,
"full_address": "1 Vitosha Boulevard, Sofia"
},
"delivery": {
"service_id": 1,
"delivery_type": "door",
"is_courier": true,
"status": "created",
"track_number": "CDEK-123456789",
"source_id": "cdek-15",
"tariff_code": 136,
"label": "https://betawms.ffcdek.ru/labels/CDEK-123456789.pdf",
"delivery_date": "2026-07-16",
"delivery_time_start": "09:00:00Z",
"delivery_time_end": "18:00:00Z"
},
"comments": {
"delivery_service_text": "Call before delivery",
"inner_text": "VIP customer"
},
"offers": [
{
"id": 7001,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
}
],
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
},
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Delete order
| operationId | deleteOrders |
|---|---|
| Tag | Orders |
| Security | 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 request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request DELETE "${NWMS_BASE_URL}/api/v2/orders/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}"Parameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
No request body.
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | object | null |
|
|||
meta |
yes | object |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
yes | boolean |
true |
|||
meta.id |
yes | integer:int64 |
min: 1 | 1001 |
Response examples
success
{
"data": null,
"meta": {
"api_version": "v2",
"deleted": true,
"id": 1001
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Export Ozon and Wildberries interaction history for one order
| operationId | getOrderIntegrationEvents |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Streams one JSON document with all retained order-related records, without the UI history limit.
Includes new HTTP attempts, legacy diagnostics and WB inbox versions, latest operation states and the current order payload.
This is not a paginated response. Dates are UTC. Read the complete document and verify export_complete.
coverage.complete is false because historical data may be missing, truncated, masked or expired.
Credentials, contact and marking data are masked. Binary responses contain metadata and SHA256 only. JSON and text responses are not truncated.
Shared bodies are omitted unless all referenced orders are visible. Unknown membership is fail-closed.
Application-internal and external marketplace activity without a captured HTTP call is not guaranteed.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request GET "${NWMS_BASE_URL}/api/v2/orders/1001/integration-events" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}"Parameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
download |
query | no | boolean |
Return the same JSON as a downloadable attachment. | |
Request body
No request body.
Responses
200 Streamed history. Check export_complete even when HTTP status is 200.
Streamed history. Check export_complete even when HTTP status is 200.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
meta |
yes | object |
Schema version, UTC timezone, order/integration identifiers and coverage limitations. | |
||
events |
yes | array<object> |
|
|||
events[] |
no | object |
Source-qualified id, source, provider, account_id, at, HTTP details or snapshot, masked request/response and omission reason. | |
||
event_count |
yes | integer |
min: 0 | |
||
export_complete |
yes | boolean |
All retained readable sources were exported; not a guarantee of historical coverage. | |
||
export_error |
yes | string | null |
journal_read_failed if streaming was interrupted by a storage/read error. | |
401 Authentication required
Authentication required.
No response body.
403 Forbidden
Order/log access denied.
No response body.
404 Not found
Order not visible or no Ozon/Wildberries link exists.
No response body.
Create order
| operationId | createOrdersLines |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Adds one or more product lines to an editable order. Products are resolved by product_id or product_external_id within the caller visible scope.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request POST "${NWMS_BASE_URL}/api/v2/orders/1001/lines" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
AddOrderLinesRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | object |
|
|||
data.lines |
yes | array<OrderLineCreatePayload> |
minItems: 1 | |
||
data.lines[] |
no | OrderLineCreatePayload |
Line payload for /orders/{id}/lines. Backend validation requires product_id for this endpoint. |
|
||
data.lines[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.lines[].quantity |
yes | number:float |
min: 0.01 | 2 |
||
data.lines[].estimated_price |
no | number:float | null |
19.5 |
|||
data.lines[].price |
no | number:float | null |
19.99 |
|||
data.lines[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.lines[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.lines[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
Request examples
default
{
"data": {
"lines": [
{
"product_id": 1201,
"quantity": 2,
"price": 19.99
}
]
}
}
Responses
201 Created.
Created.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | array<OrderLine> |
|
|||
data[] |
no | OrderLine |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data[].id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].order_id |
no | integer:int64 | null |
min: 1 | 8101 |
||
data[].product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data[].quantity |
no | number:float | null |
min: 0 | 2 |
||
data[].estimated_price |
no | number:float | null |
19.5 |
|||
data[].price |
no | number:float | null |
19.99 |
|||
data[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data[].product |
no | object | null |
|
|||
data[].product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data[].product.name |
yes | string |
"Coffee 250g" |
|||
data[].product.external_id |
no | string | null |
"EXT-10045" |
|||
data[].production_date |
no | string:date | null |
"2026-01-15" |
|||
data[].requested_lot |
no | WarehouseLot |
|
|||
data[].requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data[].requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data[].requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data[].picked_quantity |
no | number:float |
min: 0 | 2 |
||
data[].fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data[].fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data[].fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data[].fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data[].fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data[].fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data[].fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data[].fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": [
{
"id": 7001,
"order_id": 8101,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
}
],
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Update order
| operationId | replaceOrdersLines |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Update order. The request uses the documented payload schema, validates tenant visibility, and returns a normalized API envelope.
Current backend behavior is legacy partial-update semantics: omitted fields are left unchanged.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request PUT "${NWMS_BASE_URL}/api/v2/orders/1001/lines/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
lineId |
path | yes | integer:int64 |
min: 1 | Document line ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
ReplaceOrderLineRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | OrderLineReplacePayload |
Legacy PUT line update payload. Current backend treats PUT as partial update. | |
||
data.quantity |
no | number:float | null |
min: 0.01 | 2 |
||
data.estimated_price |
no | number:float | null |
19.5 |
|||
data.price |
no | number:float | null |
19.99 |
|||
data.expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
Request examples
default
{
"data": {
"quantity": 3,
"batch": "LOT-2026"
}
}
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | OrderLine |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data.id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data.created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.order_id |
no | integer:int64 | null |
min: 1 | 8101 |
||
data.product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.quantity |
no | number:float | null |
min: 0 | 2 |
||
data.estimated_price |
no | number:float | null |
19.5 |
|||
data.price |
no | number:float | null |
19.99 |
|||
data.expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data.product |
no | object | null |
|
|||
data.product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data.product.name |
yes | string |
"Coffee 250g" |
|||
data.product.external_id |
no | string | null |
"EXT-10045" |
|||
data.production_date |
no | string:date | null |
"2026-01-15" |
|||
data.requested_lot |
no | WarehouseLot |
|
|||
data.requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data.requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.picked_quantity |
no | number:float |
min: 0 | 2 |
||
data.fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data.fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data.fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data.fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data.fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": {
"id": 7001,
"order_id": 8101,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
},
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Update order
| operationId | patchOrdersLines |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Update order. The request uses the documented payload schema, validates tenant visibility, and returns a normalized API envelope.
Current backend behavior is legacy partial-update semantics: omitted fields are left unchanged.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request PATCH "${NWMS_BASE_URL}/api/v2/orders/1001/lines/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
lineId |
path | yes | integer:int64 |
min: 1 | Document line ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
PatchOrderLineRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | OrderLinePatchPayload |
Editable order line fields. The line ID is taken from the path and must not be repeated in the body. | |
||
data.quantity |
no | number:float | null |
min: 0.01 | 2 |
||
data.estimated_price |
no | number:float | null |
19.5 |
|||
data.price |
no | number:float | null |
19.99 |
|||
data.expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
Request examples
default
{
"data": {
"quantity": 3
}
}
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | OrderLine |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data.id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data.created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.order_id |
no | integer:int64 | null |
min: 1 | 8101 |
||
data.product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.quantity |
no | number:float | null |
min: 0 | 2 |
||
data.estimated_price |
no | number:float | null |
19.5 |
|||
data.price |
no | number:float | null |
19.99 |
|||
data.expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data.product |
no | object | null |
|
|||
data.product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data.product.name |
yes | string |
"Coffee 250g" |
|||
data.product.external_id |
no | string | null |
"EXT-10045" |
|||
data.production_date |
no | string:date | null |
"2026-01-15" |
|||
data.requested_lot |
no | WarehouseLot |
|
|||
data.requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data.requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.picked_quantity |
no | number:float |
min: 0 | 2 |
||
data.fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data.fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data.fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data.fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data.fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": {
"id": 7001,
"order_id": 8101,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
},
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Delete order
| operationId | deleteOrdersLines |
|---|---|
| Tag | Orders |
| Security | 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 request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request DELETE "${NWMS_BASE_URL}/api/v2/orders/1001/lines/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}"Parameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
lineId |
path | yes | integer:int64 |
min: 1 | Document line ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
No request body.
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | object | null |
|
|||
meta |
yes | object |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
yes | boolean |
true |
|||
meta.id |
yes | integer:int64 |
min: 1 | 1001 |
Response examples
success
{
"data": null,
"meta": {
"api_version": "v2",
"deleted": true,
"id": 1001
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Create order
| operationId | createOrdersOffers |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Compatibility alias for adding order lines. Prefer /lines in new integrations; behavior and validation are identical.
This /offers route is a compatibility alias for /lines; use the /lines route in new integrations.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request POST "${NWMS_BASE_URL}/api/v2/orders/1001/offers" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
AddOrderLinesRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | object |
|
|||
data.lines |
yes | array<OrderLineCreatePayload> |
minItems: 1 | |
||
data.lines[] |
no | OrderLineCreatePayload |
Line payload for /orders/{id}/lines. Backend validation requires product_id for this endpoint. |
|
||
data.lines[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.lines[].quantity |
yes | number:float |
min: 0.01 | 2 |
||
data.lines[].estimated_price |
no | number:float | null |
19.5 |
|||
data.lines[].price |
no | number:float | null |
19.99 |
|||
data.lines[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.lines[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.lines[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
Request examples
default
{
"data": {
"lines": [
{
"product_id": 1201,
"quantity": 2,
"price": 19.99
}
]
}
}
Responses
201 Created.
Created.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | array<OrderLine> |
|
|||
data[] |
no | OrderLine |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data[].id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data[].created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data[].order_id |
no | integer:int64 | null |
min: 1 | 8101 |
||
data[].product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data[].quantity |
no | number:float | null |
min: 0 | 2 |
||
data[].estimated_price |
no | number:float | null |
19.5 |
|||
data[].price |
no | number:float | null |
19.99 |
|||
data[].expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data[].batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data[].operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data[].product |
no | object | null |
|
|||
data[].product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data[].product.name |
yes | string |
"Coffee 250g" |
|||
data[].product.external_id |
no | string | null |
"EXT-10045" |
|||
data[].production_date |
no | string:date | null |
"2026-01-15" |
|||
data[].requested_lot |
no | WarehouseLot |
|
|||
data[].requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data[].requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data[].requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data[].picked_quantity |
no | number:float |
min: 0 | 2 |
||
data[].fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data[].fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data[].fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data[].fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data[].fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data[].fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data[].fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data[].fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": [
{
"id": 7001,
"order_id": 8101,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
}
],
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Update order
| operationId | replaceOrdersOffers |
|---|---|
| Tag | Orders |
| Security | bearerAuth |
Update order. The request uses the documented payload schema, validates tenant visibility, and returns a normalized API envelope.
This /offers route is a compatibility alias for /lines; use the /lines route in new integrations.
Current backend behavior is legacy partial-update semantics: omitted fields are left unchanged.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
Order offers include actual fulfillment_lots and production_date. Request include=consumables on the order list for current consumable lines; order details include them by default. These snapshots are not historical event feeds.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request PUT "${NWMS_BASE_URL}/api/v2/orders/1001/offers/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}" \
--header "Content-Type: application/json" \
--data-binary @request.jsonParameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
lineId |
path | yes | integer:int64 |
min: 1 | Document line ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
ReplaceOrderLineRequest required
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | OrderLineReplacePayload |
Legacy PUT line update payload. Current backend treats PUT as partial update. | |
||
data.quantity |
no | number:float | null |
min: 0.01 | 2 |
||
data.estimated_price |
no | number:float | null |
19.5 |
|||
data.price |
no | number:float | null |
19.99 |
|||
data.expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
Request examples
default
{
"data": {
"quantity": 3,
"batch": "LOT-2026"
}
}
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | OrderLine |
Scalar lot fields use the actual lot only when the full line is picked from one lot; partial/multiple actual lots leave scalars null. Before picking they retain the requested lot. Requested constraints are always available in requested_lot. | |
||
data.id |
yes | integer:int64 |
readOnly | min: 1 | 1001 |
|
data.created_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.updated_at |
no | string:date-time | null |
"2026-07-14T10:30:00Z" |
|||
data.order_id |
no | integer:int64 | null |
min: 1 | 8101 |
||
data.product_id |
no | integer:int64 | null |
min: 1 | 1201 |
||
data.quantity |
no | number:float | null |
min: 0 | 2 |
||
data.estimated_price |
no | number:float | null |
19.5 |
|||
data.price |
no | number:float | null |
19.99 |
|||
data.expiration_date |
no | string:date | null |
"2027-01-15" |
|||
data.batch |
no | string | null |
maxLength: 15 | "LOT-2026" |
||
data.operation_user_id |
no | integer:int64 | null |
min: 1 | 9 |
||
data.product |
no | object | null |
|
|||
data.product.id |
yes | integer:int64 |
readOnly | min: 1 | 1201 |
|
data.product.name |
yes | string |
"Coffee 250g" |
|||
data.product.external_id |
no | string | null |
"EXT-10045" |
|||
data.production_date |
no | string:date | null |
"2026-01-15" |
|||
data.requested_lot |
no | WarehouseLot |
|
|||
data.requested_lot.batch |
yes | string | null |
"LOT-2026" |
|||
data.requested_lot.production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.requested_lot.expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.picked_quantity |
no | number:float |
min: 0 | 2 |
||
data.fulfillment_lots |
no | array<OrderFulfillmentLot> |
Current active placed warehouse rows for this exact order line and product. Existing orders are included where these rows survive. This is a current picking snapshot, not a historical shipment event. | |
||
data.fulfillment_lots[] |
no | OrderFulfillmentLot |
|
|||
data.fulfillment_lots[].batch |
yes | string | null |
"LOT-2026" |
|||
data.fulfillment_lots[].production_date |
yes | string:date | null |
"2026-01-15" |
|||
data.fulfillment_lots[].expiration_date |
yes | string:date | null |
"2027-01-15" |
|||
data.fulfillment_lots[].warehouse_id |
yes | integer:int64 |
min: 1 | 734 |
||
data.fulfillment_lots[].product_id |
yes | integer:int64 |
min: 1 | 1201 |
||
data.fulfillment_lots[].quantity |
yes | number:float |
min: 0 | 2 |
||
meta |
yes | ResponseMeta |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
no | boolean |
true |
|||
meta.id |
no | integer:int64 | null |
min: 1 | 1001 |
||
meta.command_replayed |
no | boolean |
True when an idempotent cross-dock command returned the original successful result. | false |
||
meta.crossdock_configuration |
no | object | null |
|
|||
meta.crossdock_configuration.physical_warehouse_id |
yes | integer:int64 |
min: 1 | 42 |
||
meta.crossdock_configuration.enabled |
yes | boolean |
true |
|||
meta.crossdock_configuration.process_version |
yes | string |
"direct_order_v1" |
Response examples
success
{
"data": {
"id": 7001,
"order_id": 8101,
"product_id": 1201,
"quantity": 2,
"estimated_price": 19.5,
"price": 19.99,
"expiration_date": "2027-01-15",
"batch": "LOT-2026",
"operation_user_id": 9,
"product": {
"id": 1201,
"name": "Coffee 250g",
"external_id": "EXT-10045"
},
"created_at": "2026-07-14T09:00:00Z",
"updated_at": "2026-07-14T09:30:00Z"
},
"meta": {
"api_version": "v2"
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}
Delete order
| operationId | deleteOrdersOffers |
|---|---|
| Tag | Orders |
| Security | 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.
This /offers route is a compatibility alias for /lines; use the /lines route in new integrations.
HTTP request example (cURL)
Set your server and token. Replace sample IDs with accessible IDs. For requests with a body, save the applicable JSON example below as request.json and replace sample values before sending. Idempotency-Key identifies one logical operation.
curl --globoff --request DELETE "${NWMS_BASE_URL}/api/v2/orders/1001/offers/1001" \
--header "Accept: application/json" \
--header "Authorization: Bearer ${NWMS_TOKEN}" \
--header "Idempotency-Key: ${NWMS_REQUEST_KEY}"Parameters
| Name | In | Required | Type | Style | Explode | Constraints | Description | Example |
|---|---|---|---|---|---|---|---|---|
id |
path | yes | integer:int64 |
min: 1 | Order ID. | 1001 |
||
lineId |
path | yes | integer:int64 |
min: 1 | Document line ID. | 1001 |
||
Idempotency-Key |
header | no | string |
maxLength: 191 | Optional idempotency key for API v2 write requests. Successful 2xx/3xx responses are replayed for the same key and identical payload for one day. The same key with a different payload returns 409. |
"ord-create-20260714-001" |
Request body
No request body.
Responses
200 Successful response.
Successful response.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
data |
yes | object | null |
|
|||
meta |
yes | object |
|
|||
meta.api_version |
yes | enum |
enum: v2 | "v2" |
||
meta.deleted |
yes | boolean |
true |
|||
meta.id |
yes | integer:int64 |
min: 1 | 1001 |
Response examples
success
{
"data": null,
"meta": {
"api_version": "v2",
"deleted": true,
"id": 1001
}
}
400 Bad request
BadRequest
Bad request.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
BAD_REQUEST
{
"message": "Bad request.",
"error": "BAD_REQUEST"
}
401 Authentication required
Unauthorized
Authentication is required.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
AUTH_REQUIRED
{
"message": "Authentication is required.",
"error": "AUTH_REQUIRED"
}
403 Forbidden
Forbidden
The authenticated account is not allowed to perform this action.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
FORBIDDEN
{
"message": "The authenticated account is not allowed to perform this action.",
"error": "FORBIDDEN"
}
404 Not found
NotFound
The requested resource was not found or is outside the authenticated account scope.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
NOT_FOUND
{
"message": "The requested resource was not found or is outside the authenticated account scope.",
"error": "NOT_FOUND"
}
409 Conflict
Conflict
The request conflicts with the current resource state or idempotency key state.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
idempotencyConflict
{
"message": "The idempotency key is already used with a different payload.",
"error": "IDEMPOTENCY_KEY_CONFLICT"
}
422 Validation error
ValidationError
Validation failed.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The given data was invalid." |
|||
error |
no | string |
"VALIDATION_ERROR" |
|||
errors |
yes | object |
{"warehouse_id":["The selected warehouse is invalid."]} |
Response examples
validationError
{
"message": "The given data was invalid.",
"error": "VALIDATION_ERROR",
"errors": {
"warehouse_id": [
"The selected warehouse is invalid."
]
}
}
429 Rate limit exceeded
TooManyRequests
Rate limit exceeded.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"Too Many Attempts." |
|||
error |
yes | string |
"RATE_LIMITED" |
500 Internal server error
InternalServerError
An unexpected server error occurred.
| Field | Required | Type | Flags | Constraints | Description | Example |
|---|---|---|---|---|---|---|
message |
yes | string |
"The request could not be processed." |
|||
error |
yes | string |
"BAD_REQUEST" |
Response examples
INTERNAL_SERVER_ERROR
{
"message": "An unexpected server error occurred.",
"error": "INTERNAL_SERVER_ERROR"
}