@commercelayer/sdk

中文文档
8.0.4发布于 2026/11/10MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 3万

Commerce Layer Javascript SDK

原始使用文档
文档目录20 节
  1. What is Commerce Layer?
  2. Table of contents
  3. Getting started
  4. Installation
  5. Authentication
  6. Import
  7. Options
  8. API version
  9. SDK usage
  10. Create
  11. Retrieve / List
  12. Update
  13. Delete
  14. Overriding credentials
  15. Handling validation errors
  16. Using interceptors
  17. Refreshing access token
  18. Contributors guide
  19. Need help?
  20. License

Commerce Layer JS SDK

Version Downloads/week License Verify CodeQL TypeScript

A JavaScript Library wrapper that makes it quick and easy to interact with the Commerce Layer API.

This package is generated and released from the commercelayer-sdk monorepo, alongside @commercelayer/provisioning-sdk. Both are produced by the same generator from the API’s own published schema.

What is Commerce Layer?

Commerce Layer is a multi-market commerce API and order management system that lets you add global shopping capabilities to any website, mobile app, chatbot, wearable, voice, or IoT device, with ease. Compose your stack with the best-of-breed tools you already mastered and love. Make any experience shoppable, anywhere, through a blazing-fast, enterprise-grade, and secure API.

Table of contents


Getting started

To get started with Commerce Layer JS SDK you need to install it, get the credentials that will allow you to perform your API calls, and import the SDK into your application's code. The sections below explain how to achieve this.

If you want, you can also read this tutorial from Commerce Layer's blog.

Installation

Commerce Layer JS SDK is available as an npm and yarn package that you can install with the command below:

npm install @commercelayer/sdk

// or

yarn add @commercelayer/sdk

Authentication

All requests to Commerce Layer API must be authenticated with an OAuth2 bearer token. Hence, before starting to use this SDK you need to get a valid access token. Kindly check our documentation for more information about the available authorization flows.

Feel free to use Commerce Layer JS Auth, a JavaScript library that helps you wrap our authentication API.

Import

The SDK offers two import styles. The default entry is the bundled client — use it unless you have a specific reason not to. The selective (tree-shakeable) style lives on a separate subpath and carries an important caveat described below.

Bundled client (default)

import { CommerceLayer } from '@commercelayer/sdk'

const cl = CommerceLayer({
  accessToken: 'your-access-token',
  apiVersion: '2026-05'
})

const orderList = await cl.orders.list()
const skuList = await cl.skus.list()

All resource accessors are available directly on the client object. This increases your final bundle size, but every call is scoped to that specific client instance — so you can safely create and use multiple clients with different access tokens at the same time (multi-tenant apps, serverless with connection reuse, etc.):

const clUS = CommerceLayer({ accessToken: usToken, apiVersion: '2026-05' })
const clEU = CommerceLayer({ accessToken: euToken, apiVersion: '2026-05' })

const [usOrders, euOrders] = await Promise.all([
  clUS.orders.list(),
  clEU.orders.list()
]) // each request uses its own token

Selective resource imports (/single-client)

import { CommerceLayer, orders, skus } from '@commercelayer/sdk/single-client'

const cl = CommerceLayer({
  accessToken: 'your-access-token',
  apiVersion: '2026-05'
})

const orderList = await orders.list()
const skuList = await skus.list()

Only the imported resources are included in your bundle, so it produces the smallest output. The trade-off: imported resources share a single global SDK configuration. If two requests are in-flight simultaneously with different access tokens, they may silently use the wrong token — so this style supports only one active token at a time.

It is a good fit for edge/serverless functions or webhook handlers that use only a few resources and a single token. When you need multiple concurrent tokens, use the bundled client above.

Options

When instantiating a new SDK client you can pass some options to initialize it:

{
  organization?: string       // The organization slug
  accessToken: string         // A valid API access token
  apiVersion: ApiVersion      // The API version to target, e.g. '2026-05' — required, see API version below
  timeout?: number            // A custom request timout (<= 15 secs [default])
  headers?: RequestHeaders    // Custom request headers
  userAgent?: string          // Custom user-agent useful in certaing contexts but often not allowed by browsers
  fetch?: Fetch               // A specific fetch implementation 
  refreshToken?: RefreshToken // A function responsible for token refresh
}

Same options can be changed after SDK initialization or passed at runtime while executing an API call:

  const options = { ... }

  // Instantiate the client using desired options
  const cl = CommerceLayer(options)

  // Change configuration after client cteation
  cl.config(options)

  // Use runtime configuration without persisting settings
  cl.customers.list({}, options)

API version

The Core API is versioned, and every request targets a single version. apiVersion is therefore required when creating a client, and becomes part of each request URL — /api/2026-05/orders.

Only the versions this release of the SDK was generated for are accepted; any other value is a type error. Both are exported:

import { API_SCHEMA_VERSION, API_SUPPORTED_VERSIONS } from '@commercelayer/sdk'

API_SUPPORTED_VERSIONS // ['2017-08', '2026-05'] — the versions you can target
API_SCHEMA_VERSION     // '2026-05' — the version the types describe

The types are generated for API_SCHEMA_VERSION. Resources and fields that exist only in an older version are still included, marked @deprecated with the last version that has them, and newer additions carry @since — so you can keep targeting '2017-08' while migrating, and your editor shows what changes.

The version can be changed on an existing client, or overridden for a single request:

cl.config({ apiVersion: '2017-08' })

const orderList = await cl.orders.list({}, { apiVersion: '2017-08' })

[!IMPORTANT] Upgrading from 7.x: apiVersion is new and required, so every CommerceLayer(...) call needs it.

SDK usage

The JavaScript SDK is a wrapper around Commerce Layer API which means you would still be making API requests but with a different syntax. For now, we don't have comprehensive SDK documentation for every single resource our API supports (about 400+ endpoints), hence you will need to rely on our comprehensive API Reference as you go about using this SDK. So for example, if you want to create an order, take a look at the Order object or the Create an order documentation to see the required attributes and/or relationships. The same goes for every other supported resource.

To show you how things work, we will use the SKUs and Shipping Categories resource in the following examples. The code snippets below show how to use the SDK when performing the standard CRUD operations provided by our REST API. Kindly check our API reference for the complete list of available resources and their attributes.

The examples below assume a client cl, created as shown in Import.

Create

How to create an SKU
  // Select the shipping category (it's a required relationship for the SKU resource)
  const shippingCategories = await cl.shipping_categories.list({ filters: { name_eq: 'Merchandising' } })

  // Attributes passed inline, so each value is checked against the field it sets
  const newSku = await cl.skus.create({
    code: 'TSHIRTMM000000FFFFFFXL',
    name: 'Black Men T-shirt with White Logo (XL)',
    description: 'A very beautiful and cozy mens t-shirt',
    weight: 500,
    unit_of_weight: 'gr',
    shipping_category: cl.shipping_categories.relationship(shippingCategories[0].id), // assigns the relationship
  })

ℹ️ Check our API reference for more information on how to create an SKU.

Retrieve / List

How to fetch a single SKU
  // Fetch the SKU by ID
  const sku = await cl.skus.retrieve('BxAkSVqKEn')

  // Fetch all SKUs and filter by code
  const skuList = await cl.skus.list({ filters: { code_eq: 'TSHIRTMM000000FFFFFFXLXX' } })

  // Fetch the first SKU of the list
  const skuList = (await cl.skus.list()).first()

  // Fetch the last SKU of the list
  const skuList = (await cl.skus.list()).last()

ℹ️ Check our API reference for more information on how to retrieve an SKU.

How to fetch a collection of SKUs
  // Fetch all the SKUs
  const skuList = await cl.skus.list()

When fetching a collection of resources you can leverage the meta attribute to get its meta information like so:

  const skuList = await cl.skus.list()
  const meta = skuList.meta

ℹ️ Check our API reference for more information on how to list all SKUs.

How to fetch a collection of SKUs and sort the results
  // Sort the results by creation date in ascending order (default)
  const skuList = await cl.skus.list({ sort: { created_at: 'asc' } })

  // Sort the results by creation date in descending order
  const skuList = await cl.skus.list({ sort: { created_at: 'desc' } })

ℹ️ Check our API reference for more information on how to sort results.

How to fetch a collection of SKUs and include associations
  // Include an association (prices)
  const skuList = await cl.skus.list({ include: [ 'prices' ] })

  // Include an association (stock items)
  const skuList = await cl.skus.list({ include: [ 'stock_items' ] })

ℹ️ Check our API reference for more information on how to include associations.

How to fetch a collection of SKUs and return specific fields (sparse fieldsets)
  // Request the API to return only specific fields
  const skuList = await cl.skus.list({ fields: { skus: [ 'name', 'metadata' ] } })

  // Request the API to return only specific fields of the included resource
  const skuList = await cl.skus.list({ include: [ 'prices' ], fields: { prices: [ 'currency_code', 'formatted_amount' ] } })

ℹ️ Check our API reference for more information on how to use sparse fieldsets.

How to fetch a collection of SKUs and filter data
  // Filter all the SKUs fetching only the ones whose code starts with the string "TSHIRT"
  const skuList = await cl.skus.list({ filters: { code_start: 'TSHIRT' } })

  // Filter all the SKUs fetching only the ones whose code ends with the string "XLXX"
  const skuList = await cl.skus.list({ filters: { code_end: 'XLXX' } })

  // Filter all the SKUs fetching only the ones whose name contains the string "White Logo"
  const skuList = await cl.skus.list({ filters: { name_cont: 'White Logo' } })

  // Filter all the SKUs fetching only the ones created between two specific dates
  // (filters combined according to the AND logic)
  const skuList = await cl.skus.list({ filters: { created_at_gt: '2018-01-01', created_at_lt: '2018-01-31'} })

  // Filters all the SKUs fetching only the ones created or updated after a specific date
  // (attributes combined according to the OR logic)
  const skuList = await cl.skus.list({ filters: { updated_at_or_created_at_gt: '2019-10-10' } })

  // Filters all the SKUs fetching only the ones whose name contains the string "Black"
  // and whose shipping category name starts with the string "MERCH"
  const skuList = await cl.skus.list({ filters: { name_cont: 'Black', shipping_category_name_start: 'MERCH'} })

ℹ️ Check our API reference for more information on how to filter data.

How to paginate a collection of SKUs

When you fetch a collection of resources, you get paginated results. You can request specific pages or items in a page like so:

  // Fetch the SKUs, setting the page number to 3 and the page size to 5
  const skuList = await cl.skus.list({ pageNumber: 3, pageSize: 5 })

  // Get the total number of SKUs in the collection
  const skuCount = skuList.meta.recordCount

  // Get the total number of pages
  const pageCount = skuList.meta.pageCount

PS: the default page number is 1, the default page size is 10, and the maximum page size allowed is 25.

ℹ️ Check our API reference for more information on how pagination works.

How to fetch a cursor-paginated collection (e.g. event stores)

A few resources — such as event stores — use cursor-based pagination instead of page numbers. Navigate with pageAfter (and pageBefore), and read the cursor for the next page from meta.cursor, which is present only on cursor-paginated responses:

  const skuId = 'xYZkjABcde'

  // Event stores are fetched as a relationship of a resource
  let page = await cl.skus.event_stores(skuId, { pageSize: 10 })
  const events = [...page]

  // Follow the cursor until there are no more pages
  while (page.meta.cursor?.next) {
    page = await cl.skus.event_stores(skuId, { pageAfter: page.meta.cursor.next.after })
    events.push(...page)
  }

PS: the default page size is 10 and the maximum is 25. On cursor-paginated responses the offset fields (meta.pageCount/meta.recordCount) are NaN and hasNextPage() returns false, so check meta.cursor.next instead. The pageAfter/pageBefore params are always accepted at the type level; offset-paginated resources simply ignore them.

ℹ️ See the event stores pagination reference for details.

How to iterate through a collection of SKUs

To execute a function for every item of a collection, use the map() method like so:

  // Fetch the whole list of SKUs (1st page) and print their names and codes to console
  const skuList = await cl.skus.list()
  skuList.map(p => console.log('Product: ' + p.name + ' - Code: ' + p.code))
How to fetch resource relationships

Many resources have relationships with other resources and instead of including these associations as seen above, you can fetch them directly. This way, in the case of 1-to-N relationships, you can filter or sort the resulting collection as standard resources.

// Fetch 1-to-1 related resource: billing address of an order
const billingAddress = await cl.orders.billing_address('xYZkjABcde')

// Fetch 1-to-N related resources: orders associated to a customer
const customerOrders = await cl.customers.orders('XyzKjAbCDe', { fields: ['status', 'number'] })

In general:

  • An API endpoint like /api/customers or /api/customers/<customerId> translates to cl.customers.list() or cl.customers.retrieve('<customerId>') with the SDK.
  • 1-to-1 relationship API endpoints like /api/orders/<orderId>/shipping_address translates to cl.orders.shipping_address('<orderId>') with the SDK, or to cl.orders.retrieve('<orderId>', { include: ['shipping_address'] }) to get it along with the order.
  • 1-to-N relationship API endpoints like /api/customers/<customerId>?include=orders or /api/customers/<customerId>/orders translates to cl.customers.retrieve('<customerId>', { include: ['orders'] }) or cl.customers.orders('<customerId>') with the SDK.

ℹ️ Check our API reference for more information on how to fetch relationships.

How to count resources

Many times you simply need to count how many resources exist with certain characteristics. You can then call the special count function passing a filter to get as result the total number of resources.

// Get the total number of placed orders
const placedOrders = await cl.orders.count({ filters: { status_eq: 'placed' } })

Update

How to update an existing SKU
  const sku = {
    id: 'xYZkjABcde',
    description: 'Updated description...',
    image_url: 'https://img.yourdomain.com/skus/new-image.png'
  }

  cl.skus.update(sku) // updates the SKU on the server

ℹ️ Check our API reference for more information on how to update an SKU.

Delete

How to delete an existing SKU
  cl.skus.delete('xYZkjABcde') // persisted deletion

ℹ️ Check our API reference for more information on how to delete an SKU.

Overriding credentials

If needed, Commerce Layer JS SDK lets you change the client configuration and set it at a request level. To do that, just use the config() method or pass the options parameter and authenticate the API call with the desired credentials:

  // Permanently change configuration at client level
  cl.config({ organization: 'you-organization-slug', accessToken: 'your-access-token' })
  const skuList = await cl.skus.list()

  // or

  // Use configuration at request level
  cl.skus.list({}, { organization: 'you-organization-slug', accessToken: 'your-access-token' })

Handling validation errors

Commerce Layer API returns specific errors (with extra information) on each attribute of a single resource. You can inspect them to properly handle validation errors (if any). To do that, use the errors attribute of the catched error:

  // Log error messages to console:
  const attributes = { code: 'TSHIRTMM000000FFFFFFXL', name: '' }

  const newSku = await cl.skus.create(attributes).catch(error => console.log(error.errors))

  // Logged errors
  /*
  [
    {
      title: "can't be blank",
      detail: "name - can't be blank",
      code: 'VALIDATION_ERROR',
      source: { pointer: '/data/attributes/name' },
      status: '422',
      meta: { error: 'blank' }
    },
    {
      title: 'has already been taken',
      detail: 'code - has already been taken',
      code: 'VALIDATION_ERROR',
      source: { pointer: '/data/attributes/code' },
      status: '422',
      meta: { error: 'taken', value: 'TSHIRTMM000000FFFFFFXL' }
    },
    {
      title: "can't be blank",
      detail: "shipping_category - can't be blank",
      code: 'VALIDATION_ERROR',
      source: { pointer: '/data/relationships/shipping_category' },
      status: '422',
      meta: { error: 'blank' }
    }
  ]
  */

ℹ️ Check our API reference for more information about the errors returned by the API.

Using interceptors

You can use interceptors to intercept SDK messages and modify them on the fly before the request is sent to the API or before the response is parsed and returned by the client. You can also access the error object before it is thrown by the SDK.

Interceptors are special functions that are able to handle SDK messages and return a (eventually) modified version of them for use by the client.

  const requestInterceptor = (request: RequestObj): RequestObj => {
    console.log(request)
    return request
  }

  const responseInterceptor = (response: ResponseObj): ResponseObj => {
    console.log(response)
    return response
  }

  const errorInterceptor = (error: ErrorObj): ErrorObj => {
    console.log(error)
    return error
  }

Here an example of how to use them:

  // Add the interceptors (only one or all if needed)
  cl.addRequestInterceptor(requestInterceptor)
  cl.addResponseInterceptor(responseInterceptor, errorInterceptor)

  const customerList = await cl.customers.list()

  // Remove interceptors
  // Tt is possible to remove only a specific interceptor: cl.removeInterceptor('request')
  cl.removeInterceptors()

Raw Response Reader

The RawResponseReader is a special interceptor that allows to catch the original message coming frome the API before it is parsed and translated in SDK objects.

  // Add a RawResponseReader capable of capturing also response headers
  const rrr = cl.addRawResponseReader({ headers: true })
  
  const customerList = await cl.customers.list()

  cl.removeRawResponseReader()

  console.log(rrr.rawResponse)
  console.log(rrr.headers)

Refreshing access token

It is possible that you are using an access token that is about to expire especially if it has been used for many API calls. In this case you can define a special function that takes care of refreshing the token when a call fails because it has expired.

  async function myRefreshTokenFunction(espiredToken: string): Promise<string> {
    // Get a new access token using for example our js-auth library
    return (await getAccessToken()).accessToken
  }

  cl.config({ refreshToken: myRefreshTokenFunction })

  // If needed you can later retrieve the new access token
  const newToken = cl.currentAccessToken

Contributors guide

  1. Fork this repository (learn how to do this by reading the GitHub documentation).

  2. Clone the forked repository like so:

    git clone https://github.com/<your username>/commercelayer-sdk.git && cd commercelayer-sdk
    
  3. Install the workspace from the repository root:

    pnpm install
    
  4. Make your changes. Most of this package is generated from the API schema — anything you edit under gen/ will be overwritten. Change the generator or sdk.config.ts instead, then run pnpm generate and commit the result.

  5. Create a pull request (learn how to do this). Lint, types, both test suites and a check that generated output is reproducible run automatically.

  6. Someone will attend to your pull request and provide some feedback.

Need help?

License

This repository is published under the MIT license.

版本与发布记录

@commercelayer/sdk 共发布 484 个版本,首次发布于 2019/02/18;过去 12 个月发布了 41 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.0.4latest2026/11/10今天
8.0.4-beta.02026/11/09今天
8.0.32026/10/1328 天前
8.0.22026/10/081 个月前
8.0.12026/10/071 个月前
8.0.02026/10/061 个月前

其他发布通道:sdk2 → 2.5.0,node12 → 3.9.1,sdk4 → 4.57.0,sdk5 → 5.49.0,sdk6 → 6.58.0,sdk7 → 7.12.1。

关于 @commercelayer/sdk 的常见问题

@commercelayer/sdk 是什么?

Commerce Layer Javascript SDK

如何安装 @commercelayer/sdk?

在项目目录运行 npm install @commercelayer/sdk,或使用 pnpm add / yarn add / bun add。

@commercelayer/sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@commercelayer/sdk 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@commercelayer/sdk 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@commercelayer/sdk 可以商用吗?

@commercelayer/sdk 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@commercelayer/sdk 的下载量有多少?

根据 npm 官方下载统计,@commercelayer/sdk 在 2026/10/11 – 2026/11/09 这 30 天内被下载 29,563 次,日均约 985 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@commercelayer/sdk 还在维护吗?

最新版本 8.0.4 发布于 2026/11/10(今天);至今共发布 484 个版本,其中过去 12 个月发布了 41 个;首次发布于 2019/02/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。