Fluent Commerce Logo
Docs

Inventory Batch API

Essential knowledge

Intended Audience:

Technical User

Author:

Fluent Commerce

Changed on:

24 Mar 2025

Overview

The Inventory Batch is designed to send large volumes of inventory data, primarily to update the Last On Hand inventory quantities for inventory positions. While its primary purpose is to handle large-scale inventory updates and ensure the OMS reflects the latest inventory levels after a few days of operations, it is flexible enough to support other inventory types as needed, providing adaptability for diverse inventory management scenarios.

Key points

  • Create new Inventory Batches using the Job API 
  • Sample Inventory batch payload 
  • Inventory batch details

Inventory Batch Submission

In order to create/update inventory data,  one can submit an inventory batch using the `/job/{jobId}/batch` endpoint (see link). Multiple Inventory can be updated in a single batch by providing multiple `entities`.

Inventory Batch Model

The Inventory Batch Model consists of:
  • Batch-Level Fields: Define overall batch properties
  • Entities Array: Contains individual inventory items to process
FieldTypeMandatory?Possible ValuesDefault ValueDescriptionNotes
`action``String``UPSERT`N/ASpecifies the operation on inventory entities (e.g., `UPSERT` to insert/update).Must be a valid action type for inventory operations
`entityType``String``INVENTORY`N/ADefines the type of entity being processedMust be `INVENTORY`
`source``String`Any valid source identifier`batch`Identifies the origin of the batch data (e.g., `ERP`, `POS`)Defaults to `batch` if not provided
`event``String`Any valid event name`InventoryChanged`Custom event name associated with the batch operationDefaults to `InventoryChanged` if not provided
`catalogueRef``String`Any valid catalog reference`DEFAULT:<retailerId>`References the catalog associated with the inventory batchInfluences `catalogueType` in `ref` construction
`conditions`ObjectConfiguration objectUses default transient settingsConfigurations like transient types and statuses are used in de-duplication checks
`entities`ArrayList of inventory itemsN/AList of inventory items
  • Follows the entities object model
  • Nonconforming inputs are ignored 
The `conditions` object has the following fields:
FieldTypeMandatory?Possible ValuesDefault ValueDescription
`hasRelatedInventoryQuantities`ArrayList of transient IQ types and statusesDefault transient types and statusesDefines custom transient types and statuses for checking during de-duplication, e.g.: `"hasRelatedInventoryQuantities": ``[`` {"type": "SALE", "status": "ACTIVE"}, ``{"type": "SALE", "status": "CREATED"}, ``{"type": "CORRECTION", "status": "ACTIVE"} ``]`

Each object within the `entities` array should follow this structure:
FieldTypeMandatory?Possible ValuesConstraintsDescriptionNotes
`locationRef``String`Any valid location referenceN/AThe location reference used to match the inventory
`skuRef``String`Any valid SKU referenceN/AThe SKU reference of the inventory item
`qty``Integer`Any non-negative integerN/AThe quantity to match the on-hand inventory
`retailerId``String`Any valid retailer IDN/AThe retailer ID for which the inventory is uploading
`correctedQty``Integer`Any non-negative integerDefaults to 0 if not providedThe current outstanding correction quantity to be saved
`type``String`Any valid type identifierN/ASpecifies the type of inventory operation, e.g., `LAST_ON_HAND`Defaults to `LAST_ON_HAND` if not provided
`ref``String`Any valid referenceMust follow `<skuRef>:<locationRef>:<catalogueType>:<type>`A reference identifier for the inventory entityIf not provided, constructed using:
  • `skuRef`
  • `locationRef`
  • `catalogueType`
  • `type`
`status``String`Any valid status valueN/AThe status of the inventory entity, e.g., `ACTIVE`
  • The status can be provided in the payload and is used during Batch Pre-Processing for change detection. However, it is not applied or updated by reference `UpsertInventoryQuantity` rule:
    • New Inventory Quantities are created in `CREATED` status and then moved to `ACTIVE` by the `CREATE` ruleset (`SetState` rule)
    • Existing Inventory Quantities keep their current status unless another ruleset/rule changes it
`attributes`ObjectAny complex key-value pairs
  • Keys must be strings
  • Values can be any valid JSON type
Additional attributes for flexible metadata storage
The following describes the fields which can be submitted as part of an inventory batch record. 

Example Request Payload :

1{
2  "action": "UPSERT",
3  "entityType": "INVENTORY",
4  "source": "ERP",
5  "event" :"InventoryChanged",
6  "catalogueRef": "DEFAULT:1",
7  "conditions": {
8    "hasRelatedInventoryQuantities": [
9      {"type": "SALE", "status": "ACTIVE"},
10      {"type": "SALE", "status": "CREATED"},
11      {"type": "CORRECTION", "status": "ACTIVE"}
12    ]
13  },
14  "entities": [
15    {
16      "retailerId": 1,      
17      "skuRef": "PRDREF1",
18      "locationRef": "LOCREF1",      
19      "ref": "PRDREF1:LOCREF1:DEFAULT:LAST_ON_HAND:1",
20      "qty": 100,
21      "attributes": {
22        "countryOfOrigin": "AU",
23        "manufacturerBatchNumber": "MBN1",        
24        "expiresOn": "2026-09-30T23:59:59Z"
25      }
26    },
27    {
28      "retailerId": 1,
29      "skuRef": "PRDREF1",
30      "locationRef": "LOCREF1",              
31      "ref": "PRDREF1:LOCREF1:DEFAULT:LAST_ON_HAND:2",
32      "qty": 50,
33      "attributes": {
34        "countryOfOrigin": "US",
35        "manufacturerBatchNumber": "MBN2",        
36        "expiresOn": "2026-12-31T23:59:59Z"
37      }
38    },    
39    {
40      "retailerId": 1,        
41      "skuRef": "PRDREF1",
42      "locationRef": "LOCREF1",
43      "type": "ON_ORDER",            
44      "ref": "PRDREF1:LOCREF1:DEFAULT:ON_ORDER:1",
45      "qty": 300,
46      "attributes": {
47        "associationType": "PURCHASE_ORDER",
48        "associationRef": "POREF1",
49        "expectedOn": "2026-06-01T00:00:00Z"
50      }
51    },
52    {
53      "retailerId": 1,        
54      "skuRef": "PRDREF1",
55      "locationRef": "LOCREF1",
56      "type": "ON_ORDER",      
57      "ref": "PRDREF1:LOCREF1:DEFAULT:ON_ORDER:2",      
58      "qty": 150,
59      "attributes": {
60        "parentRef": "PRDREF1:LOCREF1:DEFAULT:ON_ORDER:1",
61        "associationType": "IN_TRANSIT",
62        "associationRef": "ITREF1",
63        "expectedOn": "2026-03-01T00:00:00Z",
64        "countryOfOrigin": "US",
65        "manufacturerBatchNumber": "MBN3",        
66        "expiresOn": "2027-12-31T23:59:59Z"
67      }
68    }     
69  ]
70}

Example Response

1{
2  "id": "331"
3}


Examples of Incorrect Entries


1. Null Entry
An entry that is `null` does not conform to the model structure and will be ignored. 
1"entities": [
2  null,
3  {
4    "locationRef": "LOC_MEL",
5    "skuRef": "D45",
6    "qty": 350,
7    "correctedQty": 0,
8    "retailerId": 2,
9    "type": "FUTURE",
10    "ref": "24-MG02:LOC_MELB_RET2:FUTURE",
11    "status": "ACTIVE",
12    "attributes": { /* valid attributes */ }
13  }
14]
2. String Instead of Object
A string value in the array is not a valid entity object and is thus ignored. 
1"entities": [
2  "Invalid Entry",
3  {
4    "locationRef": "LOC_MEL",
5    "skuRef": "D45",
6    "qty": 350,
7    "correctedQty": 0,
8    "retailerId": 2,
9    "type": "FUTURE",
10    "ref": "24-MG02:LOC_MELB_RET2:FUTURE",
11    "status": "ACTIVE",
12    "attributes": { /* valid attributes */ }
13  }
14]
3. Number Instead of Object
Similarly, a numeric entry does not meet the required structure and is ignored. 
1"entities": [
2  12345,
3  {
4    "locationRef": "LOC_MEL",
5    "skuRef": "D45",
6    "qty": 350,
7    "correctedQty": 0,
8    "retailerId": 2,
9    "type": "FUTURE",
10    "ref": "24-MG02:LOC_MELB_RET2:FUTURE",
11    "status": "ACTIVE",
12    "attributes": { /* valid attributes */ }
13  }
14]