Skip to main content
Skip to main content

Medusa JS Client

The Medusa JS Client provides easy access to the Medusa backend's REST APIs within TypeScript or JavaScript frontend projects.

For example, if you're creating a storefront with frameworks like Nuxt, you can send requests to the backend using this client.

This reference provides details on the available methods including examples of each.

Installation

To install the Medusa JS Client run the following command:

npm install @medusajs/medusa-js

Usage

To use the Medusa client, import Medusa and initialize the client:

import Medusa from "@medusajs/medusa-js"

const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
})

Where MEDUSA_BACKEND_URL is the URL to your Medusa backend. If the baseUrl option is not provided, the default backend URL used is http://localhost:9000.

After initialization, you can use the client's properties and methods to send requests to the Medusa backend.

Troubleshooting: Could not find a declaration file for module '@medusajs/medusa-js'

How to Use this Reference

You'll find in the sidebar of this reference names of different resources. These resources are properties in the Medusa client instance you initialize. You can access the methods or nested resources of each of the properties to send requests to the backend.

For example, to create a new customer you can access the create method under the customers property of your client:

import Medusa from "@medusajs/medusa-js"

const medusa = new Medusa()

// use method
medusa.customers.create({
// data
})

The customers resource also has another resource addresses nested inside it with its own method that you can access similarly:

medusa.customers.addresses.addAddress({
// data
})

Client Options

The client accepts the following options on initialization:

OptionDefaultDescription
maxRetries0The amount of times a request is retried.
baseUrl'http://localhost:9000'The url to which requests are made to.
apiKey''Optional API key used for authenticating admin requests.
publishableApiKey''Optional publishable API key used for storefront requests. You can create a publishable API key either using the admin APIs or the Medusa Admin.
customHeaders{}Optional headers to attach to every request.

For example:

const medusa = new Medusa({
maxRetries: 3,
baseUrl: "https://api.example.com",
})

Authentication

JWT Token

You can use a JWT token to authenticate both admin users and customers. Authentication state is managed by the client, which is ideal for Jamstack and mobile applications.

You can authenticate the admin user using the admin.auth.getToken method, and the customer using the auth.getToken method.

Once the user or customer is authenticated successfully, the Medusa client automatically attaches an Authorization Bearer header to all subsequent requests.

For example:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
await medusa.admin.auth.getToken({
email: "user@example.com",
password: "supersecret",
})
// send authenticated requests now

You can authenticate admin users or customers using cookie session ID.

You can authenticate the admin user using the admin.auth.createSession method, and the customer using the auth.authenticate method.

Once the user or customer is authenticated successfully, the Medusa client sets and attached the session ID in the cookie for all subsequent requests.

For example:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
await medusa.admin.AdminAuthResource.createSession({
email: "user@example.com",
password: "supersecret",
})
// send authenticated requests now

API Key

You can authenticate admin users with a personal API Token.

If a user doesn't have a personal API token, create one with the admin.users.update method or the Update User API route:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.users.update(userId, {
api_token,
})
.then(({ user }) => {
console.log(user.api_token)
})

Then, initialize the Medusa client passing it the apiKey option:

const medusa = new Medusa({ 
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
apiKey: "{api_token}",
})

Publishable API Key

Publishable API Keys allow you to send a request to Store API routes with a pre-defined scope. You can associate the publishable API key with one or more resources, such as sales channels, then include the publishable API key in the header of your requests.

The Medusa backend will infer the scope of the current request based on the publishable API key. At the moment, publishable API keys only work with sales channels.

It's highly recommended to create a publishable API key and pass it as an initialization option of the Medusa client.

You can learn more about publishable API keys and how to use them in this documentation.

Create a Publishable API Key

You can create a publishable API key either using the admin REST APIs, or using the Medusa Admin dashboard.

Use a Publishable API Key

To use the publishable API key, pass it as an option to the Medusa client:

const medusa = new Medusa({
maxRetries: 3,
baseUrl: "https://api.example.com",
publishableApiKey,
})

HTTP Compression

If you've enabled HTTP Compression in your Medusa configurations, and you want to disable it for some requests, you can pass the x-no-compression header in the customHeaders parameter which is available in all methods.

For example:

medusa.products.list({}, {
"x-no-compression": true,
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

Expanding Fields

In many methods you'll find an expand property that can be accepted within one of the method's parameters. You can use the expand property to unpack an entity's relations and return them in the response.

Warning

The relations you pass to expand replace any relations that are expanded by default in the request.

Expanding One Relation

For example, when you retrieve products, you can retrieve their collection by passing to the expand query parameter the value collection:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
expand: "collection",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

Expanding Multiple Relations

You can expand more than one relation by separating the relations in the expand query parameter with a comma.

For example, to retrieve both the variants and the collection of products, pass to the expand query parameter the value variants,collection:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
expand: "variants,collection",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

Prevent Expanding Relations

Some requests expand relations by default. You can prevent that by passing an empty expand value to retrieve an entity without any extra relations.

For example:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
expand: "",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

This would retrieve each product with only its properties, without any relations like collection.


Selecting Fields

In many methods you'll find a fields property that can be accepted within one of the method's parameters. You can use the fields property to specify which fields in the entity should be returned in the response.

Warning

If you pass a fields query parameter, only the fields you pass in the value along with the id of the entity will be returned in the response.

The fields query parameter does not affect the expanded relations. You'll have to use the Expand parameter instead.

Selecting One Field

For example, when you retrieve a list of products, you can retrieve only the titles of the products by passing title as a value to the fields query parameter:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
fields: "title",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

As mentioned above, the expanded relations such as variants will still be returned as they're not affected by the fields parameter.

You can ensure that only the title field is returned by passing an empty value to the expand query parameter. For example:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
fields: "title",
expand: "",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

Selecting Multiple Fields

You can pass more than one field by separating the field names in the fields query parameter with a comma.

For example, to select the title and handle of products:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
fields: "title,handle",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

Retrieve Only the ID

You can pass an empty fields query parameter to return only the ID of an entity.

For example:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
fields: "",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

You can also pair with an empty expand query parameter to ensure that the relations aren't retrieved as well. For example:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
fields: "",
expand: "",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

Pagination

Query Parameters

In listing methods, such as list customers or list products, you can control the pagination using the query parameters limit and offset.

limit is used to specify the maximum number of items that can be return in the response. offset is used to specify how many items to skip before returning the resulting entities.

You can use the offset query parameter to change between pages. For example, if the limit is 50, at page one the offset should be 0; at page two the offset should be 50, and so on.

For example, to limit the number of products returned in the list products method:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
limit: 5,
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

Response Fields

In the response of listing methods, aside from the entities retrieved, there are three pagination-related fields returned:

  • limit: the maximum number of items that can be returned in the response.
  • offset: the number of items that were skipped before the entities in the result.
  • count: the total number of available items of this entity. It can be used to determine how many pages are there.

For example, if the count is 100 and the limit is 50, you can divide the count by the limit to get the number of pages: 100/50 = 2 pages.

Sort Order

The order field available on methods supporting pagination allows you to sort the retrieved items by an attribute of that item. For example, you can sort products by their created_at attribute by setting order to created_at:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
order: "created_at",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

By default, the sort direction will be ascending. To change it to descending, pass a dash (-) before the attribute name. For example:

import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({
baseUrl: MEDUSA_BACKEND_URL,
maxRetries: 3,
})
// must be previously logged in or use api token
medusa.admin.products.list({
order: "-created_at",
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})

This sorts the products by their created_at attribute in the descending order.

Was this section helpful?