Skip to main content

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.
id
string
required
Unique stock location identifier (prefix: sloc_)
name
string
required
Location name (e.g., “Main Warehouse”, “NYC Store”)
address_id
string
ID of the associated address
address
StockLocationAddress
Full location address
metadata
object
Additional custom data

StockLocationAddress

Address details for a stock location.
id
string
required
Unique address identifier
address_1
string
required
Address line 1
address_2
string
Address line 2
city
string
City
country_code
string
required
Two-letter ISO country code
province
string
State or province
postal_code
string
Postal/ZIP code
phone
string
Phone number
metadata
object
Additional custom data

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 data
name
string
required
Location name
address
CreateStockLocationAddressDTO
Location address
metadata
object
Custom metadata
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"
stockLocationId
string
required
The ID of the stock location to retrieve
config
FindConfig
Configuration for the query
relations
string[]
Relations to load (e.g., ["address"])
stockLocation
StockLocationDTO
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 apply
id
string | string[]
Filter by stock location IDs
name
string | string[]
Filter by name
stockLocations
StockLocationDTO[]
Array of stock locations

Update Stock Location

Modify a stock location.
const stockLocation = await stockLocationService.updateStockLocations(
  "sloc_warehouse",
  {
    name: "Main Distribution Center",
    address: {
      phone: "+1-555-0200",
    },
  }
)
stockLocationId
string
required
ID of the stock location to update
data
UpdateStockLocationDTO
required
Fields to update
name
string
Location name
address
UpdateStockLocationAddressDTO
Address updates
metadata
object
Metadata 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

  1. Location Naming: Use clear, descriptive names that include:
    • Location type (warehouse, store, supplier)
    • Geographic identifier (city, region)
    • Purpose if applicable (returns center, outlet)
  2. 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
  3. Metadata Usage: Store location-specific settings in metadata:
    • Operating hours
    • Capacity limits
    • Location type
    • Special handling instructions
    • Ship-from-store capability
    • Regional identifiers
  4. Location Strategy: Plan your location structure based on:
    • Fulfillment speed requirements
    • Shipping cost optimization
    • Inventory distribution
    • Returns handling
  5. Integration: Link stock locations with:
    • Inventory levels (required)
    • Fulfillment providers
    • Service zones
    • Return locations
  6. Soft Deletes: Consider using metadata flags to “deactivate” locations instead of deleting them to preserve historical data.

Build docs developers (and LLMs) love