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).
Unique inventory item identifier
Stock keeping unit identifier
Country of origin (two-letter ISO code)
Harmonized System code for customs
Item material composition
Whether item requires shipping
InventoryLevel
Tracks stock quantity for an inventory item at a specific location.
Unique inventory level identifier
Quantity physically stocked at location
Quantity reserved (calculated from reservations)
Quantity expected to arrive
Available quantity (calculated: stocked - reserved)
ReservationItem
Reserves inventory for orders, carts, or other purposes.
Unique reservation identifier
ID of the associated line item
Reservation description or reason
User ID who created the reservation
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 dataWhether item requires shipping
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 dataQuantity 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
Retrieve Inventory Level
Get inventory level for item at location.
const inventoryLevel = await inventoryModuleService.retrieveInventoryLevel(
"iitem_123",
"sloc_warehouse"
)
console.log(inventoryLevel.available_quantity)
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
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")
}
IDs of stock locations to check
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
-
Reserved Quantity: The
reserved_quantity field is calculated automatically from reservation items. Never update it directly - always create/delete reservations.
-
Inventory Adjustments: Use
adjustInventory for relative changes (add/subtract), updateInventoryLevels for absolute values.
-
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
-
Multi-Location: When checking availability, always specify which locations to check. This is crucial for multi-warehouse scenarios.
-
Backorders: Set appropriate thresholds for when to allow backorders. Check
available_quantity and compare with incoming_quantity.
-
Bulk Operations: Use array input for bulk operations to improve performance when creating multiple inventory items or levels.