Skip to main content

Overview

The Inventory Module manages inventory tracking across multiple stock locations. It handles inventory items, stock levels per location, and inventory reservations for orders and carts. Key Features:
  • Inventory item management
  • Multi-location stock levels
  • Inventory reservations
  • Available quantity calculations
  • Backorder support
  • Stock adjustments and tracking

When to Use

Use the Inventory Module when you need to:
  • Track inventory across multiple warehouses
  • Reserve inventory for orders and carts
  • Check product availability
  • Manage stock levels per location
  • Support backorders
  • Adjust inventory quantities
  • Track incoming and stocked quantities

Data Models

InventoryItem

Represents a trackable inventory item (usually linked to product variants).
id
string
required
Unique inventory item identifier
sku
string
Stock keeping unit identifier
origin_country
string
Country of origin (two-letter ISO code)
hs_code
string
Harmonized System code for customs
mid_code
string
Manufacturer item number
material
string
Item material composition
weight
number
Item weight
length
number
Item length
height
number
Item height
width
number
Item width
requires_shipping
boolean
Whether item requires shipping
metadata
object
Additional custom data

InventoryLevel

Tracks stock quantity for an inventory item at a specific location.
id
string
required
Unique inventory level identifier
inventory_item_id
string
required
ID of the inventory item
location_id
string
required
ID of the stock location
stocked_quantity
BigNumber
required
Quantity physically stocked at location
reserved_quantity
BigNumber
required
Quantity reserved (calculated from reservations)
incoming_quantity
BigNumber
required
Quantity expected to arrive
available_quantity
BigNumber
Available quantity (calculated: stocked - reserved)
metadata
object
Additional custom data

ReservationItem

Reserves inventory for orders, carts, or other purposes.
id
string
required
Unique reservation identifier
inventory_item_id
string
required
ID of the inventory item
location_id
string
required
ID of the stock location
quantity
BigNumber
required
Reserved quantity
line_item_id
string
ID of the associated line item
description
string
Reservation description or reason
created_by
string
User ID who created the reservation
metadata
object
Additional custom data

Service Interface

The Inventory Module service is available at @medusajs/medusa/inventory.

Create Inventory Item

Create a new inventory item.
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IInventoryService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"

export async function POST(
  req: MedusaRequest,
  res: MedusaResponse
) {
  const inventoryModuleService: IInventoryService = req.scope.resolve(
    Modules.INVENTORY
  )

  const inventoryItem = await inventoryModuleService.createInventoryItems({
    sku: "TSHIRT-M-BLACK",
    requires_shipping: true,
    weight: 200,
  })

  res.json({ inventory_item: inventoryItem })
}
data
CreateInventoryItemDTO | CreateInventoryItemDTO[]
required
Inventory item data
sku
string
Stock keeping unit
requires_shipping
boolean
Whether item requires shipping
weight
number
Item weight
length
number
Item length
height
number
Item height
width
number
Item width
inventoryItem
InventoryItemDTO | InventoryItemDTO[]
The created inventory item(s)

Create Inventory Level

Set stock quantity at a location.
const inventoryLevel = await inventoryModuleService.createInventoryLevels({
  inventory_item_id: "iitem_123",
  location_id: "sloc_warehouse",
  stocked_quantity: 100,
  incoming_quantity: 50,
})
data
CreateInventoryLevelDTO | CreateInventoryLevelDTO[]
required
Inventory level data
inventory_item_id
string
required
ID of the inventory item
location_id
string
required
ID of the stock location
stocked_quantity
number
required
Quantity in stock
incoming_quantity
number
Quantity expected to arrive

Update Inventory Level

Adjust stock quantities.
const inventoryLevel = await inventoryModuleService.updateInventoryLevels({
  inventory_item_id: "iitem_123",
  location_id: "sloc_warehouse",
  stocked_quantity: 150, // New total quantity
})
data
UpdateInventoryLevelDTO
required
Update data
inventory_item_id
string
required
ID of the inventory item
location_id
string
required
ID of the stock location
stocked_quantity
number
New stocked quantity
incoming_quantity
number
New incoming quantity

Retrieve Inventory Level

Get inventory level for item at location.
const inventoryLevel = await inventoryModuleService.retrieveInventoryLevel(
  "iitem_123",
  "sloc_warehouse"
)

console.log(inventoryLevel.available_quantity)
inventoryItemId
string
required
ID of the inventory item
locationId
string
required
ID of the stock location
inventoryLevel
InventoryLevelDTO
The inventory level with available quantity

Create Reservation

Reserve inventory for an order or cart.
const reservation = await inventoryModuleService.createReservationItems({
  inventory_item_id: "iitem_123",
  location_id: "sloc_warehouse",
  quantity: 2,
  line_item_id: "item_456",
  description: "Order reservation",
})
data
CreateReservationItemDTO | CreateReservationItemDTO[]
required
Reservation data
inventory_item_id
string
required
ID of the inventory item
location_id
string
required
ID of the stock location
quantity
number
required
Quantity to reserve
line_item_id
string
ID of the line item
description
string
Reservation description
reservation
ReservationItemDTO | ReservationItemDTO[]
The created reservation(s)

Update Reservation

Modify reservation quantity.
const reservation = await inventoryModuleService.updateReservationItems(
  "res_123",
  {
    quantity: 3, // Update to 3 items
  }
)

Delete Reservation

Release reserved inventory.
await inventoryModuleService.deleteReservationItems(["res_123", "res_456"])

Confirm Inventory

Check if sufficient inventory is available.
const isAvailable = await inventoryModuleService.confirmInventory(
  "iitem_123",
  ["sloc_warehouse"],
  5 // Quantity needed
)

if (!isAvailable) {
  throw new Error("Insufficient inventory")
}
inventoryItemId
string
required
ID of the inventory item
locationIds
string[]
required
IDs of stock locations to check
quantity
number
required
Required quantity
isAvailable
boolean
Whether sufficient inventory is available

Retrieve Available Quantity

Get available quantity across locations.
const availableQuantity = await inventoryModuleService.retrieveAvailableQuantity(
  "iitem_123",
  ["sloc_warehouse", "sloc_store"]
)

Retrieve Stocked Quantity

Get total stocked quantity across locations.
const stockedQuantity = await inventoryModuleService.retrieveStockedQuantity(
  "iitem_123",
  ["sloc_warehouse", "sloc_store"]
)

Retrieve Reserved Quantity

Get total reserved quantity.
const reservedQuantity = await inventoryModuleService.retrieveReservedQuantity(
  "iitem_123",
  ["sloc_warehouse"]
)

Integration Examples

With Product Module

Create inventory for product variants.
import { Modules } from "@medusajs/framework/utils"

const productModule = container.resolve(Modules.PRODUCT)
const inventoryModule = container.resolve(Modules.INVENTORY)

// Create product with variants
const product = await productModule.createProducts({
  title: "T-Shirt",
  variants: [
    { title: "Small", sku: "TSHIRT-S" },
    { title: "Medium", sku: "TSHIRT-M" },
  ],
})

// Create inventory items for variants
for (const variant of product.variants) {
  const inventoryItem = await inventoryModule.createInventoryItems({
    sku: variant.sku,
  })
  
  // Link variant to inventory (via workflows)
  
  // Set stock level
  await inventoryModule.createInventoryLevels({
    inventory_item_id: inventoryItem.id,
    location_id: "sloc_warehouse",
    stocked_quantity: 100,
  })
}

With Cart Module

Check availability and reserve inventory.
import { Modules } from "@medusajs/framework/utils"

const cartModule = container.resolve(Modules.CART)
const inventoryModule = container.resolve(Modules.INVENTORY)

// Get cart with items
const cart = await cartModule.retrieveCart("cart_123", {
  relations: ["items"],
})

// Check availability for each item
for (const item of cart.items) {
  const isAvailable = await inventoryModule.confirmInventory(
    item.inventory_item_id,
    ["sloc_warehouse"],
    item.quantity
  )
  
  if (!isAvailable) {
    throw new Error(`Item ${item.title} is out of stock`)
  }
  
  // Reserve inventory
  await inventoryModule.createReservationItems({
    inventory_item_id: item.inventory_item_id,
    location_id: "sloc_warehouse",
    quantity: item.quantity,
    line_item_id: item.id,
    description: "Cart reservation",
  })
}

With Order Module

Adjust inventory on order completion.
import { Modules } from "@medusajs/framework/utils"

const orderModule = container.resolve(Modules.ORDER)
const inventoryModule = container.resolve(Modules.INVENTORY)

// Order completed - adjust inventory
const order = await orderModule.retrieveOrder("order_123", {
  relations: ["items"],
})

// Convert reservations to actual deductions
for (const item of order.items) {
  // Delete reservation
  await inventoryModule.deleteReservationItems([item.reservation_id])
  
  // Adjust stocked quantity
  await inventoryModule.adjustInventory(
    item.inventory_item_id,
    "sloc_warehouse",
    -item.quantity // Subtract from stock
  )
}

With Stock Location Module

Manage inventory across multiple locations.
import { Modules } from "@medusajs/framework/utils"

const stockLocationModule = container.resolve(Modules.STOCK_LOCATION)
const inventoryModule = container.resolve(Modules.INVENTORY)

// Get all stock locations
const locations = await stockLocationModule.listStockLocations()

// Set inventory levels at each location
for (const location of locations) {
  await inventoryModule.createInventoryLevels({
    inventory_item_id: "iitem_123",
    location_id: location.id,
    stocked_quantity: 50,
  })
}

// Check total available quantity across all locations
const totalAvailable = await inventoryModule.retrieveAvailableQuantity(
  "iitem_123",
  locations.map(l => l.id)
)

With Fulfillment Module

Reserve inventory for fulfillment.
import { Modules } from "@medusajs/framework/utils"

const fulfillmentModule = container.resolve(Modules.FULFILLMENT)
const inventoryModule = container.resolve(Modules.INVENTORY)

// Create fulfillment
const fulfillment = await fulfillmentModule.createFulfillment({
  location_id: "sloc_warehouse",
  provider_id: "manual",
  items: [
    { line_item_id: "item_123", quantity: 2 },
  ],
})

// Deduct from inventory
await inventoryModule.adjustInventory(
  "iitem_123",
  "sloc_warehouse",
  -2
)

Best Practices

  1. Reserved Quantity: The reserved_quantity field is calculated automatically from reservation items. Never update it directly - always create/delete reservations.
  2. Inventory Adjustments: Use adjustInventory for relative changes (add/subtract), updateInventoryLevels for absolute values.
  3. Reservation Lifecycle:
    • Create reservation when adding to cart
    • Update reservation when cart quantity changes
    • Delete reservation when:
      • Cart is completed (order created)
      • Cart item is removed
      • Cart expires
  4. Multi-Location: When checking availability, always specify which locations to check. This is crucial for multi-warehouse scenarios.
  5. Backorders: Set appropriate thresholds for when to allow backorders. Check available_quantity and compare with incoming_quantity.
  6. Bulk Operations: Use array input for bulk operations to improve performance when creating multiple inventory items or levels.

Build docs developers (and LLMs) love