Overview
The Stock Location Module manages physical warehouse and store locations where inventory is stocked. It provides location management capabilities essential for multi-location inventory tracking and fulfillment.
Key Features:
- Multiple stock location management
- Location addresses with full details
- Location metadata for customization
- Integration with inventory tracking
- Integration with fulfillment
When to Use
Use the Stock Location Module when you need to:
- Manage multiple warehouses or stores
- Track inventory at different locations
- Support multi-location fulfillment
- Store location addresses and contact info
- Implement ship-from-store functionality
- Handle distributed inventory
- Configure location-specific settings
Data Models
StockLocation
Represents a physical location where inventory is stored.
Unique stock location identifier (prefix: sloc_)
Location name (e.g., “Main Warehouse”, “NYC Store”)
ID of the associated address
StockLocationAddress
Address details for a stock location.
Unique address identifier
Two-letter ISO country code
Service Interface
The Stock Location Module service is available at @medusajs/medusa/stock-location.
Create Stock Location
Create a new stock location.
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IStockLocationService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
export async function POST(
req: MedusaRequest,
res: MedusaResponse
) {
const stockLocationService: IStockLocationService = req.scope.resolve(
Modules.STOCK_LOCATION
)
const stockLocation = await stockLocationService.createStockLocations({
name: "Main Warehouse",
address: {
address_1: "123 Warehouse Blvd",
city: "San Francisco",
country_code: "us",
province: "CA",
postal_code: "94102",
phone: "+1-555-0100",
},
})
res.json({ stock_location: stockLocation })
}
data
CreateStockLocationDTO | CreateStockLocationDTO[]
required
Stock location dataaddress
CreateStockLocationAddressDTO
Location address
stockLocation
StockLocationDTO | StockLocationDTO[]
The created stock location(s)
Retrieve Stock Location
Get a stock location with its address.
const stockLocation = await stockLocationService.retrieveStockLocation(
"sloc_warehouse",
{
relations: ["address"],
}
)
console.log(stockLocation.name) // "Main Warehouse"
console.log(stockLocation.address.city) // "San Francisco"
The ID of the stock location to retrieve
Configuration for the queryRelations to load (e.g., ["address"])
The retrieved stock location
List Stock Locations
List all stock locations.
const stockLocations = await stockLocationService.listStockLocations(
{},
{
relations: ["address"],
}
)
for (const location of stockLocations) {
console.log(`${location.name} - ${location.address?.city}`)
}
filters
FilterableStockLocationProps
Filters to applyFilter by stock location IDs
Update Stock Location
Modify a stock location.
const stockLocation = await stockLocationService.updateStockLocations(
"sloc_warehouse",
{
name: "Main Distribution Center",
address: {
phone: "+1-555-0200",
},
}
)
ID of the stock location to update
data
UpdateStockLocationDTO
required
Fields to updateaddress
UpdateStockLocationAddressDTO
Address updates
Delete Stock Location
Remove a stock location.
await stockLocationService.deleteStockLocations(["sloc_old"])
Integration Examples
With Inventory Module
Manage inventory at stock locations.
import { Modules } from "@medusajs/framework/utils"
const stockLocationModule = container.resolve(Modules.STOCK_LOCATION)
const inventoryModule = container.resolve(Modules.INVENTORY)
// Create stock locations
const warehouse = await stockLocationModule.createStockLocations({
name: "Main Warehouse",
address: {
address_1: "123 Warehouse Blvd",
city: "San Francisco",
country_code: "us",
postal_code: "94102",
},
})
const store = await stockLocationModule.createStockLocations({
name: "NYC Retail Store",
address: {
address_1: "456 5th Avenue",
city: "New York",
country_code: "us",
postal_code: "10001",
},
})
// Set inventory levels at each location
await inventoryModule.createInventoryLevels([
{
inventory_item_id: "iitem_123",
location_id: warehouse.id,
stocked_quantity: 100,
},
{
inventory_item_id: "iitem_123",
location_id: store.id,
stocked_quantity: 20,
},
])
// Check total available across locations
const totalAvailable = await inventoryModule.retrieveAvailableQuantity(
"iitem_123",
[warehouse.id, store.id]
)
With Fulfillment Module
Create fulfillments from stock locations.
import { Modules } from "@medusajs/framework/utils"
const stockLocationModule = container.resolve(Modules.STOCK_LOCATION)
const fulfillmentModule = container.resolve(Modules.FULFILLMENT)
// Get nearest stock location
const locations = await stockLocationModule.listStockLocations()
const nearestLocation = locations[0] // Implement distance logic
// Create fulfillment from location
const fulfillment = await fulfillmentModule.createFulfillment({
location_id: nearestLocation.id,
provider_id: "manual",
items: [
{ line_item_id: "item_123", quantity: 1 },
],
})
With Order Module
Fulfill orders from specific locations.
import { Modules } from "@medusajs/framework/utils"
const orderModule = container.resolve(Modules.ORDER)
const stockLocationModule = container.resolve(Modules.STOCK_LOCATION)
const inventoryModule = container.resolve(Modules.INVENTORY)
// Get order
const order = await orderModule.retrieveOrder("order_123", {
relations: ["items", "shipping_address"],
})
// Find locations with inventory
const locations = await stockLocationModule.listStockLocations()
for (const location of locations) {
// Check if location has inventory for order items
const hasInventory = await inventoryModule.confirmInventory(
order.items[0].inventory_item_id,
[location.id],
order.items[0].quantity
)
if (hasInventory) {
// Use this location for fulfillment
console.log(`Fulfill from ${location.name}`)
break
}
}
Common Scenarios
Multi-Warehouse Setup
// West Coast Warehouse
const westWarehouse = await stockLocationService.createStockLocations({
name: "West Coast DC",
address: {
address_1: "100 Logistics Way",
city: "Los Angeles",
country_code: "us",
province: "CA",
postal_code: "90001",
},
metadata: {
region: "west",
capacity: 10000,
},
})
// East Coast Warehouse
const eastWarehouse = await stockLocationService.createStockLocations({
name: "East Coast DC",
address: {
address_1: "200 Distribution Ave",
city: "Atlanta",
country_code: "us",
province: "GA",
postal_code: "30301",
},
metadata: {
region: "east",
capacity: 8000,
},
})
Retail Store Locations
// Flagship Store
const flagship = await stockLocationService.createStockLocations({
name: "Flagship Store - NYC",
address: {
address_1: "123 5th Avenue",
city: "New York",
country_code: "us",
province: "NY",
postal_code: "10001",
phone: "+1-212-555-0100",
},
metadata: {
type: "retail",
store_hours: "9AM-9PM",
ship_from_store: true,
},
})
// Outlet Store
const outlet = await stockLocationService.createStockLocations({
name: "Outlet Store - Jersey",
address: {
address_1: "456 Mall Drive",
city: "Jersey City",
country_code: "us",
province: "NJ",
postal_code: "07302",
},
metadata: {
type: "outlet",
ship_from_store: false,
},
})
Drop Ship Locations
// Supplier location for drop shipping
const supplier = await stockLocationService.createStockLocations({
name: "Supplier A - Drop Ship",
address: {
address_1: "789 Supplier Road",
city: "Chicago",
country_code: "us",
province: "IL",
postal_code: "60601",
},
metadata: {
type: "dropship",
supplier_id: "SUP-001",
lead_time_days: 7,
},
})
Best Practices
-
Location Naming: Use clear, descriptive names that include:
- Location type (warehouse, store, supplier)
- Geographic identifier (city, region)
- Purpose if applicable (returns center, outlet)
-
Complete Addresses: Always provide complete address information including:
- Full street address
- City and province/state
- Country code (two-letter ISO)
- Postal code
- Contact phone number
-
Metadata Usage: Store location-specific settings in metadata:
- Operating hours
- Capacity limits
- Location type
- Special handling instructions
- Ship-from-store capability
- Regional identifiers
-
Location Strategy: Plan your location structure based on:
- Fulfillment speed requirements
- Shipping cost optimization
- Inventory distribution
- Returns handling
-
Integration: Link stock locations with:
- Inventory levels (required)
- Fulfillment providers
- Service zones
- Return locations
-
Soft Deletes: Consider using metadata flags to “deactivate” locations instead of deleting them to preserve historical data.