Skip to main content

SDK Methods

The Medusa JavaScript SDK provides a comprehensive set of methods organized by domain. This guide covers the core patterns, client usage, and available methods.

Client Architecture

The SDK is structured around four main namespaces:
import Medusa from "@medusajs/js-sdk"

const sdk = new Medusa({ baseUrl: "http://localhost:9000" })

// Admin API - Administrative operations
sdk.admin.product.list()
sdk.admin.order.retrieve("order_123")

// Store API - Customer-facing operations
sdk.store.cart.create({ region_id: "reg_123" })
sdk.store.product.list()

// Auth API - Authentication flows
await sdk.auth.login("customer", "emailpass", { email, password })

// Client - Low-level HTTP client
await sdk.client.fetch("/custom/endpoint")

Method Patterns

All SDK methods follow consistent patterns:

Standard CRUD Methods

Most resources support these standard operations:
// List (paginated)
const { products, count, offset, limit } = await sdk.admin.product.list({
  limit: 20,
  offset: 0,
  fields: "id,title,thumbnail",
  q: "shirt" // Search query
})

// Retrieve (single resource)
const { product } = await sdk.admin.product.retrieve("prod_123", {
  fields: "id,title,*variants"
})

// Create
const { product } = await sdk.admin.product.create({
  title: "New Product",
  // ... other fields
})

// Update
const { product } = await sdk.admin.product.update("prod_123", {
  title: "Updated Title"
})

// Delete
const { id, deleted } = await sdk.admin.product.delete("prod_123")

Query Parameters

All list and retrieve methods support query parameters:
query
object

Custom Headers

Pass headers to individual requests:
const { products } = await sdk.store.product.list(
  { fields: "id,title" },
  {
    "x-custom-header": "value",
    "cache-control": {
      tags: ["products"] // Next.js cache tags
    },
    "Authorization": "Bearer custom_token"
  }
)

Admin API Methods

The admin namespace provides access to all administrative operations.

Product Management

// List products with filters
const { products } = await sdk.admin.product.list({
  q: "shirt",
  status: ["published"],
  collection_id: ["pcol_123"],
  fields: "id,title,*variants"
})

// Create a product
const { product } = await sdk.admin.product.create({
  title: "Cotton T-Shirt",
  description: "Comfortable cotton t-shirt",
  status: "published",
  options: [
    { title: "Size", values: ["S", "M", "L", "XL"] },
    { title: "Color", values: ["Black", "White", "Gray"] }
  ],
  variants: [
    {
      title: "S / Black",
      sku: "SHIRT-S-BLK",
      options: { Size: "S", Color: "Black" },
      prices: [{ amount: 2999, currency_code: "usd" }]
    }
  ]
})

// Update product
const { product: updated } = await sdk.admin.product.update("prod_123", {
  title: "Updated Title"
})

// Delete product
await sdk.admin.product.delete("prod_123")

// Import products from CSV
const { transaction_id } = await sdk.admin.product.createImport({
  file // File instance from <input type="file">
})

// Confirm import
await sdk.admin.product.confirmImport(transaction_id)

Product Variants

// List variants
const { product_variants } = await sdk.admin.productVariant.list({
  product_id: ["prod_123"]
})

// Create variant
const { product_variant } = await sdk.admin.productVariant.create("prod_123", {
  title: "XL / Blue",
  sku: "SHIRT-XL-BLU",
  options: { Size: "XL", Color: "Blue" },
  prices: [{ amount: 3499, currency_code: "usd" }]
})

// Update variant inventory
const { product_variant: updated } = await sdk.admin.productVariant.update(
  "prod_123",
  "variant_123",
  {
    inventory_quantity: 100,
    manage_inventory: true
  }
)

Order Management

// List orders with filters
const { orders } = await sdk.admin.order.list({
  status: ["pending", "completed"],
  created_at: {
    gte: "2024-01-01"
  },
  fields: "id,display_id,status,*items"
})

// Retrieve order details
const { order } = await sdk.admin.order.retrieve("order_123", {
  fields: "id,*items,*shipping_address,*customer"
})

// Update order
const { order: updated } = await sdk.admin.order.update("order_123", {
  email: "[email protected]"
})

// Cancel order
await sdk.admin.order.cancel("order_123")

// Archive order
await sdk.admin.order.archive("order_123")

// Create fulfillment
const { order: fulfilled } = await sdk.admin.order.createFulfillment(
  "order_123",
  {
    items: [
      { id: "item_123", quantity: 2 }
    ]
  }
)

// Create shipment
await sdk.admin.order.createShipment("order_123", "ful_123", {
  tracking_numbers: ["TRACK123"]
})

Customer Management

// List customers
const { customers } = await sdk.admin.customer.list({
  q: "john",
  has_account: true
})

// Create customer
const { customer } = await sdk.admin.customer.create({
  email: "[email protected]",
  first_name: "John",
  last_name: "Doe",
  phone: "+1234567890"
})

// Update customer
const { customer: updated } = await sdk.admin.customer.update("cus_123", {
  first_name: "Jane"
})

// Add customer to group
await sdk.admin.customer.addCustomerGroup("cus_123", {
  customer_group_id: "cg_123"
})

Inventory Management

// List inventory items
const { inventory_items } = await sdk.admin.inventoryItem.list({
  sku: ["SHIRT-001"]
})

// Update inventory levels
const { inventory_item } = await sdk.admin.inventoryItem.updateLevel(
  "inv_123",
  "loc_123",
  {
    stocked_quantity: 100
  }
)

// List stock locations
const { stock_locations } = await sdk.admin.stockLocation.list()

// Create reservation
const { reservation } = await sdk.admin.reservation.create({
  inventory_item_id: "inv_123",
  location_id: "loc_123",
  quantity: 5
})

Region & Currency

// List regions
const { regions } = await sdk.admin.region.list()

// Create region
const { region } = await sdk.admin.region.create({
  name: "Europe",
  currency_code: "eur",
  countries: ["fr", "de", "it"],
  payment_providers: ["stripe"],
  fulfillment_providers: ["manual"]
})

// List currencies
const { currencies } = await sdk.admin.currency.list()

Store API Methods

The store namespace provides customer-facing operations.

Product Browsing

// List products
const { products, count } = await sdk.store.product.list({
  limit: 12,
  offset: 0,
  region_id: "reg_123", // Calculate prices for region
  collection_id: ["pcol_123"],
  category_id: ["pcat_123"],
  fields: "id,title,thumbnail,*variants,*variants.prices"
})

// Get product details
const { product } = await sdk.store.product.retrieve("prod_123", {
  region_id: "reg_123",
  fields: "id,title,description,*variants,*images"
})

// List collections
const { collections } = await sdk.store.collection.list()

// Get collection
const { collection } = await sdk.store.collection.retrieve("pcol_123")

// List categories
const { product_categories } = await sdk.store.category.list({
  parent_category_id: "null" // Get root categories
})

// Get category with children
const { product_category } = await sdk.store.category.retrieve("pcat_123", {
  fields: "id,name,*category_children"
})

Cart Management

// Create cart
const { cart } = await sdk.store.cart.create({
  region_id: "reg_123",
  country_code: "us"
})

// Add line item
const { cart: updated } = await sdk.store.cart.createLineItem(cart.id, {
  variant_id: "variant_123",
  quantity: 2
})

// Update line item
const { cart: cartWithUpdated } = await sdk.store.cart.updateLineItem(
  cart.id,
  "item_123",
  { quantity: 3 }
)

// Remove line item
const { deleted, parent: cartAfterDelete } = await sdk.store.cart.deleteLineItem(
  cart.id,
  "item_123"
)

// Update cart
const { cart: cartUpdated } = await sdk.store.cart.update(cart.id, {
  email: "[email protected]",
  shipping_address: {
    first_name: "John",
    last_name: "Doe",
    address_1: "123 Main St",
    city: "New York",
    country_code: "us",
    postal_code: "10001"
  },
  billing_address: {
    // ... billing address
  }
})

// Retrieve cart
const { cart: retrieved } = await sdk.store.cart.retrieve(cart.id, {
  fields: "id,*items,*shipping_address,total"
})

// Transfer cart to logged-in customer
const { cart: transferred } = await sdk.store.cart.transferCart(cart.id)

Checkout Flow

// 1. Get available shipping options
const { shipping_options } = await sdk.store.fulfillment.listCartOptions({
  cart_id: cart.id
})

// 2. Calculate shipping option price
const { shipping_option } = await sdk.store.fulfillment.calculate(
  shipping_options[0].id,
  { cart_id: cart.id }
)

// 3. Add shipping method to cart
const { cart: withShipping } = await sdk.store.cart.addShippingMethod(
  cart.id,
  {
    option_id: shipping_option.id,
    data: {} // Provider-specific data
  }
)

// 4. Get payment providers
const { payment_providers } = await sdk.store.payment.listPaymentProviders({
  region_id: cart.region_id
})

// 5. Initialize payment session
const { payment_collection } = await sdk.store.payment.initiatePaymentSession(
  cart,
  {
    provider_id: payment_providers[0].id,
    data: {
      // Provider-specific payment data
    }
  }
)

// 6. Complete cart and create order
const result = await sdk.store.cart.complete(cart.id)

if (result.type === "order") {
  console.log("Order placed:", result.order)
} else {
  console.error("Cart completion failed:", result.error)
  console.log("Cart state:", result.cart)
}

Customer Account

// Note: Customer must be authenticated first

// Get customer profile
const { customer } = await sdk.store.customer.retrieve()

// Update profile
const { customer: updated } = await sdk.store.customer.update({
  first_name: "Jane",
  phone: "+1234567890"
})

// List customer addresses
const { addresses } = await sdk.store.customer.listAddress()

// Add address
const { customer: withAddress } = await sdk.store.customer.createAddress({
  address_name: "Home",
  first_name: "John",
  last_name: "Doe",
  address_1: "123 Main St",
  city: "New York",
  country_code: "us",
  postal_code: "10001"
})

// Update address
const { customer: addressUpdated } = await sdk.store.customer.updateAddress(
  "addr_123",
  { address_name: "Office" }
)

// Delete address
await sdk.store.customer.deleteAddress("addr_123")

// List orders
const { orders } = await sdk.store.order.list()

// Get order details
const { order } = await sdk.store.order.retrieve("order_123")

Authentication Methods

The auth namespace handles authentication flows.

Customer Registration & Login

// 1. Register new customer
const registrationToken = await sdk.auth.register(
  "customer",
  "emailpass",
  {
    email: "[email protected]",
    password: "securePassword123"
  }
)

// 2. Complete registration
const { customer } = await sdk.store.customer.create(
  {
    email: "[email protected]",
    first_name: "John",
    last_name: "Doe"
  },
  {},
  {
    Authorization: `Bearer ${registrationToken}`
  }
)

// 3. Login customer
const token = await sdk.auth.login(
  "customer",
  "emailpass",
  {
    email: "[email protected]",
    password: "securePassword123"
  }
)

// Customer is now authenticated
// All subsequent requests include auth headers automatically
const { customer: profile } = await sdk.store.customer.retrieve()

Admin User Login

const token = await sdk.auth.login(
  "user",
  "emailpass",
  {
    email: "[email protected]",
    password: "adminPassword"
  }
)

// Admin is now authenticated
const { users } = await sdk.admin.user.list()

OAuth / Third-Party Login

// 1. Initiate OAuth flow
const result = await sdk.auth.login("customer", "google", {})

if (typeof result !== "string") {
  // Redirect to OAuth provider
  window.location.href = result.location
}

// 2. Handle OAuth callback (after redirect back)
// In your callback route handler:
const urlParams = new URLSearchParams(window.location.search)
const token = await sdk.auth.callback(
  "customer",
  "google",
  Object.fromEntries(urlParams)
)

// 3. Refresh token to get full session
await sdk.auth.refresh()

// Customer is now authenticated
const { customer } = await sdk.store.customer.retrieve()

Password Reset

// 1. Request password reset
await sdk.auth.resetPassword(
  "customer",
  "emailpass",
  {
    identifier: "[email protected]"
  }
)

// Customer receives email with reset token

// 2. Update password with token
await sdk.auth.updateProvider(
  "customer",
  "emailpass",
  {
    password: "newSecurePassword123"
  },
  resetToken // From email link
)

Logout

await sdk.auth.logout()

// User is now logged out
// Stored tokens/sessions are cleared

Low-Level Client

The client property provides direct access to the HTTP client.

Custom Requests

// GET request
const data = await sdk.client.fetch<{ custom: any }>(
  "/custom/endpoint",
  {
    query: { param: "value" },
    headers: { "x-custom": "header" }
  }
)

// POST request
const result = await sdk.client.fetch<{ result: any }>(
  "/custom/endpoint",
  {
    method: "POST",
    body: { data: "value" },
    headers: { "content-type": "application/json" }
  }
)

Server-Sent Events (SSE)

// Stream server-sent events
const { stream, abort } = await sdk.client.fetchStream(
  "/admin/batch-jobs/batch_123/events"
)

if (stream) {
  for await (const event of stream) {
    console.log("Event:", event.event)
    console.log("Data:", JSON.parse(event.data || "{}"))
    
    if (event.event === "completed") {
      abort() // Stop streaming
      break
    }
  }
}

Locale Management

// Set active locale
sdk.setLocale("fr")

// Get current locale
const locale = sdk.getLocale() // "fr"

// All subsequent requests include x-medusa-locale header
const { products } = await sdk.store.product.list()
// Products returned with French translations

Token Management

// Manually set token
await sdk.client.setToken("jwt_token_string")

// Get current token
const token = await sdk.client.getToken()

// Clear token
await sdk.client.clearToken()

Error Handling

Handle errors using try-catch with FetchError:
import { FetchError } from "@medusajs/js-sdk"

try {
  const { product } = await sdk.store.product.retrieve("invalid_id")
} catch (error) {
  if (error instanceof FetchError) {
    // HTTP error from API
    console.error(`Error ${error.status}: ${error.message}`)
    console.error(`Status text: ${error.statusText}`)
    
    if (error.status === 404) {
      // Handle not found
    } else if (error.status === 401) {
      // Handle unauthorized
    }
  } else {
    // Network or other error
    console.error("Unexpected error:", error)
  }
}

TypeScript Support

The SDK is fully typed using types from @medusajs/types:
import type { HttpTypes } from "@medusajs/types"
import sdk from "./lib/medusa"

// Return types are fully typed
const { products }: HttpTypes.StoreProductListResponse = 
  await sdk.store.product.list()

// Input types are validated
const { cart }: HttpTypes.StoreCartResponse = 
  await sdk.store.cart.create({
    region_id: "reg_123" // TypeScript ensures correct structure
  })

// Use types in your application
function ProductCard({ product }: { product: HttpTypes.StoreProduct }) {
  return <div>{product.title}</div>
}

Next Steps

Overview

Learn about SDK features and use cases

API Reference

Explore complete API documentation

Build docs developers (and LLMs) love