This document is intended for merchants and their SI (System Integrator) partners who want to set up inventory. It describes the rules and procedures to set up inventory as per the business need.

To set up inventory:

  1. Create Location
  2. Update Product Information
  3. Create a Network
  4. Create or Update Inventory

Refer to the following sections for additional information:

General Rules:

  • If you are using a third-party product information management system other than fabric’s Product Catalog, you must provide product details to fabric in a .csv file. For details, see the Update Product Information section. If you are already using fabric’s Product Catalog to maintain product information, ignore this step.
  • To create or update inventory, you must provide sku, itemId, location, channelId, and counters. You can provide other details to configure the inventory based on your requirements. For details, see the Create Inventory section.
    • If you are using only the Inventory service of fabric (not the entire OMS service), you must mention allocated and shipped counter quantities to update inventory. If you are using fabric’s OMS to manage inventory and order fulfillment, allocated and shipped counter quantities will be taken care of automatically.
  • Use the onHand counter to represent the inventory quantity that’s currently in stock for selling. Per the onHand counter value passed in the request body, availableToPurchase (the virtual counter) quantity is calculated, based on the formula onHand - allocated - shipped - safetyStock. safetyStock is also subtracted if you include safetyStock value while creating inventory.
  • Subscribe to any of the inventory webhook events to get a notification for inventory updates. For sample curl and other details, see List of Webhook Events.

Create location

API Mapping: POST/v3/locations

Using the POST/v3/locations endpoint, you can create records for your stores, with details including postal code, hours of operation, BOPIS enabled, and other custom attributes that are applicable to your business.

Request Sample:

{
  "locationNumber": 23,
  "name": "Seattle Store",
  "isActive": true,
  "address": {
    "addressLine1": "123 Main St.",
    "addressLine2": "Suite 100",
    "addressLine3": "Seventh floor",
    "addressLine4": "Attention: Pat E. Kake",
    "city": "Seattle",
    "region": "WA",
    "postalCode": "98121",
    "countryCode": "US",
    "type": "Home",
    "contacts": [
      {
        "type": "OFFICE",
        "email": "[[email protected]](/cdn-cgi/l/email-protection)",
        "phone": [
          {
            "number": "0281923712",
            "type": "MOBILE"
          }
        ],
        "name": {
          "firstName": "Pat",
          "middleName": "E",
          "lastName": "Kake"
        }
      }
    ]
  },
  "type": "DC",
  "services": {
    "brand": "WHBM",
    "channel": "Frontline"
  },
  "operatingHours": [
    {
      "day": "SUNDAY",
      "hours": [
        {
          "open": "10",
          "close": "20",
          "type": "PICK_UP"
        }
      ]
    }
  ],
  "coordinates": {
    "type": "Point",
    "coordinates": [
      -122.3493,
      47.6205
    ]
  },
  "attributes": {
    "isReturns": "true"
  }
}

Response Sample:

{
  "locationId": "9372919a8219e8",
  "locationNumber": 23,
  "name": "Seattle Store",
  "isActive": true,
  "address": {
    "addressLine1": "123 Main St.",
    "addressLine2": "Suite 100",
    "addressLine3": "Seventh floor",
    "addressLine4": "Attention: Pat E. Kake",
    "city": "Seattle",
    "region": "WA",
    "postalCode": "98121",
    "countryCode": "US",
    "type": "Home",
    "contacts": [
      {
        "type": "OFFICE",
        "email": "[[email protected]](/cdn-cgi/l/email-protection)",
        "phone": [
          {
            "number": "0281923712",
            "type": "MOBILE"
          }
        ],
        "name": {
          "firstName": "Pat",
          "middleName": "E",
          "lastName": "Kake"
        }
      }
    ]
  },
  "type": "DC",
  "createdAt": "2022-05-25T07:58:30.996Z",
  "updatedAt": "2022-05-25T07:58:30.996Z",
  "operatingHours": [
    {
      "day": "SUNDAY",
      "hours": [
        {
          "open": "10",
          "close": "20",
          "type": "PICK_UP"
        }
      ]
    }
  ],
  "coordinates": {
    "type": "Point",
    "coordinates": [
      -122.3493,
      47.6205
    ]
  }
}

Update Product Information (Optional)

Note: This step is required if you are using product management software other than fabric’s Product Catalog. If you are using fabric’s Product Catalog to maintain your product data, this step isn’t required as product data will automatically be imported to the Catalog Connector.

API Mapping:

  • Use the PUT/products/{id} endpoint for updating a single product by ID.
  • Use the PUT/products endpoint for updating multiple products.

Sample request to update a single product:

{
  "sku": "XP-123345",
  "categoryId": "QWE1234CCVFDDERW21",
  "type": "ITEM",
  "attributes": [
    {
      "id": "6d7329dfd5288b0011332311",
      "value": "blue"
    }
  ],
  "parentProduct": {
    "id": "AASSBCC12334FCD12334V"
  },
  "bundleProducts": [
    {
      "sku": "XP-123345",
      "quantity": 2
    }
  ],
  "variants": [
    {
      "id": "AASSBCC12334FCD12334V"
    }
  ],
  "localizedProperties": {
    "en-US": {
      "attributes": [
        {
          "id": "W123333RRTT555y1",
          "value": "blue"
        }
      ]
    },
    "en-IN": {
      "attributes": [
        {
          "id": "W123333RRTT555AA",
          "value": "blue"
        }
      ]
    }
  }
}

Sample response for updating a single product:

{
  "id": "5g7329dfd5288b00113323p7",
  "sku": "QWERTTY56DDFFVVV",
  "type": "ITEM",
  "isActive": true,
  "hasDraft": true,
  "hasLive": true,
  "status": "LIVE",
  "attributes": [
    {
      "id": "227329dfd5288b0011332315",
      "name": "Color",
      "type": "string",
      "isDeleted": false,
      "value": "blue",
      "isInherited": true
    }
  ],
  "localizedProperties": {
    "en-US": {
      "attributes": [
        {
          "id": "637329dfd5288b0011332354",
          "name": "Color",
          "type": "string",
          "isDeleted": false,
          "value": "blue",
          "isInherited": true
        }
      ]
    },
    "en-IN": {
      "attributes": [
        {
          "id": "8f7329dfd5288b0011332334",
          "name": "Colour",
          "type": "string",
          "isDeleted": false,
          "value": "blue",
          "isInherited": true
        }
      ]
    }
  },
  "variants": [
    {
      "id": "967329dfd5288b0011332356"
    }
  ],
  "categoryId": "7f7329dfd5288b0011332378",
  "createdAt": "2021-09-14T22:10:30.618Z",
  "updatedAt": "2021-09-14T22:10:30.618Z"
}

Create a network

API Mapping: POST/v3/inventory-networks

  • Network refers to a group of locations with a group of SKUs in each location.
  • You can create a network to map inventories for the created networks. A network code is generated for the created network. You can mention the network code while creating or updating inventories for a specific network.
  • You can configure safety stock quantities for a network while creating a network. Additionally, you can configure safety stock and low stock quantities while creating or updating inventories for a specific network.

Request Sample:

{
  "code": "DC",
  "name": "Distribution Center",
  "safetyStock": 10,
  "description": "network-mar6th",
  "lowStock": 10,
  "rule": {
    "locationData.type": "Store",
    "locationData.attributes.safetyStock": 10,
    "locationData.isActive": true,
    "productData.attributes.brand": "ABC",
    "productData.attributes.isSoldOnline": true
  }
}

Response Sample:

  "code": "DC",
  "name": "Distribution Center",
  "safetyStock": 10,
  "description": "network-mar6th",
  "lowStock": 10,
  "rule": {
    "locationData.type": "Store",
    "locationData.attributes.safetyStock": 10,
    "locationData.isActive": true,
    "productData.attributes.brand": "ABC",
    "productData.attributes.isSoldOnline": true
  },
  "createdAt": "2022-08-01T18:03:28.483971941Z",
  "updatedAt": "2022-08-01T18:03:28.483971941Z"
}

Create or update inventory

API Mapping:

  • POST/v3/inventories: Create inventory
  • Post/v3/inventories/action/find-and-update: Update inventory either by replacing existing property value or by adding a new value to an existing property.
  1. Set the infiniteInventory parameter to true to configure unlimited quantities of inventory.
  2. Use customAttributes to define any custom attribute that suit your business use case. For example, you can set BOPIS (Buy Online Pickup In Store) to true if you are willing to allow shoppers to buy online and pick up an item from the store (based on location number).
  3. If you provide values for backOrderLimit and preOrderLimit while creating inventory, availableBackorder and availablePreorder virtual-counters are displayed in the response object with the same values as provided in the request body.
  4. Configure values for safetyStock and lowStock fields while creating or updating inventory for better inventory management.

Rules for updating counter quantity:

  • Use the onHand counter to represent the inventory quantity that’s currently in stock for selling. Based on the onHand counter value as passed in the request body, availableToPurchase quantity is calculated based on the formula onHand - allocated - shipped and displayed in the response object.
  • (Not required if you are using the Order module of fabric OMS) Use the “allocated” counter to represent inventory that’s sent to warehouses for fulfillment (only the warehouse can cancel the order at this point).
  • (Not required if you are using the Order module of fabric OMS) Use the “shipped” counter to represent inventory that’s marked as shipped by the warehouse (at this stage in the life-cycle the order can only be returned).
  • Use “backorderReserve” and “preOrderReserve” counters (under counter object) to represent inventory quantity that’s permitted for backorder (reserve for restock) or pre-order (inventory quantity on launch date).

Sample request to create or update inventory:

{
  "sku": "SKU123",
  "itemId": 12345,
  "locationNum": 999,
  "channelId": "channel1",
  "vendorId": "vendor1",
 "counters": {
    "onHand": 100,
    "allocated": 20,
    "shipped": 10
  },
  "infiniteInventory": true,
  "backOrderDate": "2022-10-21T14:28:06.968Z",
  "preOrderDate": "2022-10-21T14:28:06.968Z",
  "backOrderLimit": 50,
  "preOrderLimit": 40,
  "safetyStock": 10,
  "lowStock": 0,
  "networkCode": "ShipToHome",(get inventory by network)
  "customAttributes": {
    "isRetrun": true,
    "isBopis": true
  },
  "networkCounters": {
    "softReserve": 10
  },
}

Response sample for creating or updating inventory:

{
  "sku": "SKU123",
  "itemId": 12345,
  "locationNum": 999,
  "channelId": "channel1",
  "vendorId": "vendor1",
 "counters": {
    "onHand": 100,
    "allocated": 20,
    "shipped": 10
  },
  "infiniteInventory": true,
  "backOrderDate": "2022-10-21T14:28:06.968Z",
  "preOrderDate": "2022-10-21T14:28:06.968Z",
  "backOrderLimit": 50,
  "preOrderLimit": 40,
  "safetyStock": 10,
  "lowStock": 0,
  "networkCode": "ShipToHome",(get inventory by network)
  "customAttributes": {
    "isRetrun": true,
    "isBopis": true
  },
  "networkCounters": {
    "softReserve": 10
  },
"virtualCounters": {
    "availableToPurchase": 60,
    "availableBackorder": 50,
    "availablePreorder": 40
  }
}

Query inventory

After you successfully create an inventory, you can query for inventory information either using the Copilot user interface or using the POST/v3/inventories/actions/find endpoint.

  • While searching for inventory information, you must include SKU and network code (if you have created a network) as query parameters to get the “Available to Purchase” information.
  • While searching for an inventory of type BOPIS (Buy Online Pickup In Store), you must include SKU, locationNum, and channelId to get information for BOPIS.

Sample request:

{
  "skus": [
    "SKU1"
  ],
  "itemIds": [
    127122871
  ],
  "locationNumbers": [
    12
  ],
  "locationTypes": [
    "DC"
  ],
  "segments": [
    "B2B_Special"
  ],
  "region": "North America",
  "networkCodes": [
    "4"
  ]
}

Sample response:

{
  "pagination": {
    "limit": 10,
    "offset": 1,
    "count": 1000
  },
  "data": [
    {
      "inventoryId": "723910d81723",
      "sku": "SKU1",
      "itemId": 12345,
      "locationNumber": 12345,
      "region": "North America",
      "channelId": "channel_xyz",
      "vendorId": "vendor1",
      "createdAt": "2022-08-01T18:03:28.483971941Z",
      "updatedAt": "2022-08-01T20:03:28.483971941Z",
      "leadTime": "5 days",
      "type": "primary",
      "hasInfiniteInventory": false,
      "backorderShipmentAt": "2022-08-01T20:03:28.483971941Z",
      "preorderShipmentAt": "2022-08-01T20:03:28.483971941Z",
      "backorderLimit": 50,
      "preorderLimit": 40,
      "safetyStock": 10,
      "lowStock": 10,
      "networkCode": "ShipToHome",
      "counters": {
        "onHand": 100,
        "allocated": 10,
        "shipped": 20
      },
      "customAttributes": {
        "isBopis": true
      },
      "networkCounters": {
        "softReserve": 10
      },
      "virtualCounters": {
        "availableToPurchase": 60
      }
    }
  ]
}

Rules for updating counter quantity

  • In stock: Use the onHand counter in the request body to represent inventory that’s currently available in the location to sell.
  • In Stock for BOPIS (Buy Online Pickup In Store) for an SKU in a specified radius of zip code or postal code:
    • Use the onHand counter to represent in-stock inventory.
    • Define BOPIS using the customAttribute field while creating or updating inventory.
    • Zip code or postal code is identified based on the location number. A location number is generated for a location for which you provide all details such as name, address, type, zip or postal code, and more information while creating the location using the create location endpoint.
  • In Stock for BOPIS in a specified store:
    • Use the onHand counter to represent in-stock inventory.
    • Define BOPIS using the customAttribute field while creating or updating inventory. A specific store is identified by the location number.
  • Adjust inventory records by increasing or decreasing counter quantity:
    • Use the onHand counter to represent in-stock inventory.
    • Use the POST/v3/inventories/actions/find-and-adjust-inventory-counters endpoint to adjust counter quantity. You can provide the SKU, location, and counter quantity in the request payload to adjust the onHand counter quantity. Counter quantity accepts both positive and negative values. Based on the value you specify in the request payload for the counter quantity, the original counter quantity is either decreased or increased. For example, if the original counter quantity is 100, and you specify the counter quantity as “-10” in the request payload, then the updated onHand counter becomes 90.
  • Displaying Backorder, Preorder, Safety Stock, and Low Stock on Website:
    • If the availableToPurchase value is greater than zero, then calculate if the availabletoPurchase quantity is greater than the safetyStock value.
      • If availableToPurchase quantity is greater than 0, then display the item as in-stock.
      • If availableToPurchase quantity is equal to 0 and availableBackorder is greater than 0, then display the item as in-stock-for-backorder.
      • If Available and Backorder are both out of stock, and availableToPreorder is greater than 0, then display the item as in-stock-for-preorder, else display the item as out-of-stock.
      • If the item is a Backorder or Preorder item, then display the expected restock date (backorderDate) or expected product launch date (preOrderDate)