Get started with the TypeScript SDK

Learn how to set up and use the TypeScript SDK.

This step-by-step guide leads you through setting up and making API calls using the TypeScript SDK.

Requirements

To follow this guide you should have the following:

  • A commercetools Composable Commerce Project
  • An API Client
  • Node v18.17.x (or later)
  • Either npm v9.6.x (or later) or yarn v3.2.x (or later)
For more information on setting up a commercetools Composable Commerce Project or API Client, follow our Getting started with commercetools Composable Commerce guides.

Objectives of the get started guide

After following this guide, you will have:

Placeholder values

Example code in this guide uses the following placeholder values. You should replace these placeholders with the following values.

If you do not have an API Client, follow our Get your API Client guide.
PlaceholderReplace withFrom
{projectKey}project_keyyour API Client
{clientID}client_idyour API Client
{clientSecret}secretyour API Client
{scope}scopeyour API Client
{region}your RegionHosts

Install the TypeScript SDK

Use the following command to install the SDK Client:

npm install @commercetools/ts-client
# or
yarn add @commercetools/ts-client
To access the HTTP API, Import API, Audit Log API, or Checkout API, install the following packages as needed:

For HTTP API

For Import API

For Audit Log API

For Checkout API

npm install @commercetools/platform-sdk
# or
yarn add @commercetools/platform-sdk
npm install @commercetools/importapi-sdk
# or
yarn add @commercetools/importapi-sdk
npm install @commercetools/history-sdk
# or
yarn add @commercetools/history-sdk
npm install @commercetools/checkout-sdk
# or
yarn add @commercetools/checkout-sdk

Create the client

Create a file called BuildClient.ts and insert the following code. This code contains your API Client configuration, API-specific HttpMiddlewareOptions configuration, and then exports the ClientBuilder with the specified middleware.

For HTTP API

For Import API

For Audit Log API

For Checkout API

import {
  ClientBuilder,

  // Import middlewares
  type AuthMiddlewareOptions, // Required for auth
  type HttpMiddlewareOptions, // Required for sending HTTP requests
} from '@commercetools/ts-client';

export const projectKey = '{projectKey}';
const scopes = ['{scope}'];

// Configure authMiddlewareOptions
const authMiddlewareOptions: AuthMiddlewareOptions = {
  host: 'https://auth.{region}.commercetools.com',
  projectKey,
  credentials: {
    clientId: '{clientID}',
    clientSecret: '{clientSecret}',
  },
  scopes,
  httpClient: fetch,
};

// Configure HTTP API httpMiddlewareOptions
const httpAPIHTTPMiddlewareOptions: HttpMiddlewareOptions = {
  host: 'https://api.{region}.commercetools.com',
  httpClient: fetch,
};

// Export the ClientBuilder for the HTTP API
export const ctpClientHTTPAPI = new ClientBuilder()
  .withProjectKey(projectKey)
  .withClientCredentialsFlow(authMiddlewareOptions)
  .withHttpMiddleware(httpAPIHTTPMiddlewareOptions)
  .withLoggerMiddleware() // Include middleware for logging
  .build();
import {
  ClientBuilder,

  // Import middlewares
  type AuthMiddlewareOptions, // Required for auth
  type HttpMiddlewareOptions, // Required for sending HTTP requests
} from '@commercetools/ts-client';

export const projectKey = '{projectKey}';
const scopes = ['{scope}'];

// Configure authMiddlewareOptions
const authMiddlewareOptions: AuthMiddlewareOptions = {
  host: 'https://auth.{region}.commercetools.com',
  projectKey,
  credentials: {
    clientId: '{clientID}',
    clientSecret: '{clientSecret}',
  },
  scopes,
  httpClient: fetch,
};

// Configure Import API httpMiddlewareOptions
const importAPIHTTPMiddlewareOptions: HttpMiddlewareOptions = {
  host: 'https://import.{region}.commercetools.com',
  httpClient: fetch,
};

// Export the ClientBuilder for the Import API
export const ctpClientImportAPI = new ClientBuilder()
  .withProjectKey(projectKey)
  .withClientCredentialsFlow(authMiddlewareOptions)
  .withHttpMiddleware(importAPIHTTPMiddlewareOptions)
  .withLoggerMiddleware() // Include middleware for logging
  .build();
import {
  ClientBuilder,

  // Import middlewares
  type AuthMiddlewareOptions, // Required for auth
  type HttpMiddlewareOptions, // Required for sending HTTP requests
} from '@commercetools/ts-client';

export const projectKey = '{projectKey}';
const scopes = ['{scope}'];

// Configure authMiddlewareOptions
const authMiddlewareOptions: AuthMiddlewareOptions = {
  host: 'https://auth.{region}.commercetools.com',
  projectKey,
  credentials: {
    clientId: '{clientID}',
    clientSecret: '{clientSecret}',
  },
  scopes,
  httpClient: fetch,
};

// Configure History API httpMiddlewareOptions
const historyAPIHTTPMiddlewareOptions: HttpMiddlewareOptions = {
  host: 'https://history.{region}.commercetools.com',
  httpClient: fetch,
};

// Export the ClientBuilder for the History API
export const ctpClientHistoryAPI = new ClientBuilder()
  .withProjectKey(projectKey)
  .withClientCredentialsFlow(authMiddlewareOptions)
  .withHttpMiddleware(historyAPIHTTPMiddlewareOptions)
  .withLoggerMiddleware() // Include middleware for logging
  .build();
import {
  ClientBuilder,

  // Import middlewares
  type AuthMiddlewareOptions, // Required for auth
  type HttpMiddlewareOptions, // Required for sending HTTP requests
} from '@commercetools/ts-client';

export const projectKey = '{projectKey}';
const scopes = ['{scope}'];

// Configure authMiddlewareOptions
const authMiddlewareOptions: AuthMiddlewareOptions = {
  host: 'https://auth.{region}.commercetools.com',
  projectKey,
  credentials: {
    clientId: '{clientID}',
    clientSecret: '{clientSecret}',
  },
  scopes,
  httpClient: fetch,
};

// Configure Checkout API httpMiddlewareOptions
const checkoutAPIHTTPMiddlewareOptions: HttpMiddlewareOptions = {
  host: 'https://checkout.{region}.commercetools.com',
  httpClient: fetch,
};

// Export the ClientBuilder for the Checkout API
export const ctpClientCheckoutAPI = new ClientBuilder()
  .withProjectKey(projectKey)
  .withClientCredentialsFlow(authMiddlewareOptions)
  .withHttpMiddleware(checkoutAPIHTTPMiddlewareOptions)
  .withLoggerMiddleware() // Include middleware for logging
  .build();

Add middleware

This example code configures the authentication used (withClientCredentialsFlow) and HttpMiddleware authMiddlewareOptions, httpMiddlewareOptions, and withLoggerMiddleware to handle auth, API requests, and logging respectively.
You can configure and use other middleware based on your requirements and add them to ClientBuilder with method chaining.
Screenshot of autocomplete for including middleware
You can learn more about configuring and using middleware on the Middleware page.

Test the client

The following code demonstrates how to create an ApiRoot from the client. The code also contains test calls which outputs to the log.

For HTTP API

For Import API

For Audit Log API

For Checkout API

import { ctpClientHTTPAPI, projectKey } from './BuildClient';
import {
  createApiBuilderFromCtpClient,
  Project,
} from '@commercetools/platform-sdk';

const httpApiRoot = createApiBuilderFromCtpClient(
  ctpClientHTTPAPI
).withProjectKey({
  projectKey,
});

// Example call to return Project information
// This code has the same effect as sending a GET request to the commercetools Composable Commerce API without any endpoints.
async function getProject(): Promise<Project> {
  const response = await httpApiRoot.get().execute();
  return response.body;
}

// Retrieve Project information and output the result to the log
await getProject().then(console.log).catch(console.error);

You can now use the httpApiRoot to build requests to the HTTP API.
import { ctpClientImportAPI, projectKey } from './BuildClient';
import {
  ImportContainer,
  createApiBuilderFromCtpClient as createImportApiBuilderFromCtpClient,
} from '@commercetools/importapi-sdk';

// Create importApiRoot from the imported ClientBuilder and include your Project key
const importApiRoot = createImportApiBuilderFromCtpClient(
  ctpClientImportAPI
).withProjectKeyValue({ projectKey });

// Example call to return ImportContainers
async function getImportContainers(): Promise<ImportContainer[]> {
  const response = await importApiRoot.importContainers().get().execute();

  return response.body.results;
}

// Retrieve ImportContainers and output the result to the log
await getImportContainers().then(console.log).catch(console.error);

You can now use the importApiRoot to build requests to the Import API.
import { ctpClientHistoryAPI, projectKey } from './BuildClient';
import { createApiBuilderFromCtpClient as createHistoryApiBuilderFromCtpClient } from '@commercetools/history-sdk';

// Create historyApiRoot from the imported ClientBuilder and include your Project key
const historyApiRoot = createHistoryApiBuilderFromCtpClient(
  ctpClientHistoryAPI
).withProjectKeyValue({ projectKey });

// Example call to return recent Category history
async function getCategoryHistory() {
  const response = await historyApiRoot
    .withResourceTypeValue({ resourceType: 'categories' })
    .get()
    .execute();

  return response.body;
}

// Retrieve Category history and output the result to the log
await getCategoryHistory().then(console.log).catch(console.error);

You can now use the historyApiRoot to build requests to the Audit Log API.
import { ctpClientHTTPAPI, projectKey } from './BuildClient';
import {
  Transaction,
  createApiBuilderFromCtpClient as createCheckoutApiBuilderFromCtpClient,
} from '@commercetools/checkout-sdk';

// Create checkoutApiRoot from the imported ClientBuilder and include your Project key
const checkoutApiRoot = createCheckoutApiBuilderFromCtpClient(
  ctpClientHTTPAPI
).withProjectKey({
  projectKey,
});

// Example call to return a Transaction by key
async function getTransactionById(key: string): Promise<Transaction> {
  const response = await checkoutApiRoot
    .transactions()
    .withKey({ key })
    .get()
    .execute();
  return response.body;
}

// Retrieve a Transaction and output the result to the log
await getTransactionById('a-transaction-key')
  .then(console.log)
  .catch(console.error);

You can now use the checkoutApiRoot to build requests to the Checkout API.
The createApiBuilderFromCtpClient function accepts an optional second argument called baseUri, which is of type string. You can use this argument to override the host parameters in httpMiddlewareOptions.
createApiBuilderFromCtpClient(client: Client, baseUri?: string): ApiRoot;

Use the TypeScript SDK

Imports

Without importing resource-specific packages and interfaces you cannot use/access specific objects and methods.

For example, to use or create a Shopping List, you must import the ShoppingList and ShoppingListDraft interfaces from the @commercetools/platform-sdk package.
import { ShoppingList, ShoppingListDraft } from '@commercetools/platform-sdk';
When using the Import API, Audit Log API, or Checkout API, take care when importing resources as some resources share names in different packages. For example, the HTTP API, Import API, and Audit Log API all have an Asset interface. Always use API-specific resources to avoid errors and conflicts.

Create objects

Unlike other SDKs which use builders to construct drafts, update actions, and other objects/types that contain multiple fields, the TypeScript SDK uses standard TypeScript objects.

import {
  LocalizedString,
  Money,
  CategoryDraft,
} from '@commercetools/platform-sdk';

// Create a LocalizedString
const multiLanguageString: LocalizedString = {
  en: 'English value',
  de: 'German value',
};

// Create US$100.00
const money: Money = {
  currencyCode: 'USD',
  centAmount: 10000,
  type: 'centPrecision',
};

// Create a CategoryDraft
const categoryDraft: CategoryDraft = {
  name: { en: 'English name' },
  slug: { en: 'english-slug' },
  key: 'category-key',
};
Consult the API reference for the HTTP API, Import API, Audit Log API, and Checkout API to ensure that you include all required fields.

Structure your API call

The following examples demonstrate how to structure calls to the HTTP API using the TypeScript SDK. The examples use the Shopping Lists endpoint, but the structure is identical for most other endpoints in the HTTP API.

Using the Import API, Audit Log API, or Checkout API may differ slightly, but the structure of building requests remains the same.

Add an endpoint

Add an endpoint to httpApiRoot. The following targets the Shopping Lists endpoint:
const shoppingListsRequest = await httpApiRoot.shoppingLists();
You can change shoppingLists() to any other endpoint, for example products(), categories(), or customers(). If you do not specify an endpoint when using httpApiRoot, the SDK references the Project.

Retrieve data

Get a single resource

When targeting a specific resource, include its ID or key followed by .get() and .execute().
Get a specific Shopping List by its IDts
async function getShoppingListById(ID: string): Promise<ShoppingList> {
  const response = await httpApiRoot
    .shoppingLists()
    .withId({ ID })
    .get()
    .execute();
  return response.body;
}

await getShoppingListById('a-shoppinglist-id')
  .then(console.log)
  .catch(console.error);
Get a specific Shopping List by its Keyts
async function getShoppingListByKey(key: string): Promise<ShoppingList> {
  const response = await httpApiRoot
    .shoppingLists()
    .withKey({ key })
    .get()
    .execute();
  return response.body;
}

await getShoppingListByKey('a-shoppinglist-key')
  .then(console.log)
  .catch(console.error);
If you query a resource with an id or key that does not exist, the API returns a Not Found error.

Get multiple resources

If you do not include an ID or key within get(), the endpoint returns a PagedQueryResponse, which is identical to PagedQueryResult in the HTTP API.
Return a ShoppingListPagedQueryResponsets
async function getShoppingLists(): Promise<ShoppingListPagedQueryResponse> {
  const response = await httpApiRoot.shoppingLists().get().execute();
  return response.body;
}

await getShoppingLists().then(console.log).catch(console.error);
You can filter the results of these calls by including query arguments within the get() method. Within queryArgs you can define where, sort, expand, limit, and/or offset
Return a filtered ShoppingListPagedQueryResponsets
async function getShoppingLists(): Promise<ShoppingListPagedQueryResponse> {
  const response = await httpApiRoot
    .shoppingLists()
    .get({
      queryArgs: {
        where: ['lineItems is not empty'],
        sort: 'name.en-US desc',
        expand: ['customer'],
        limit: 5,
        offset: 0,
      },
    })
    .execute();
  return response.body;
}

View results

PagedQueryResponse has a property called results, which contains an array of the returned resources. In this case, Shopping Lists.
The results within ShoppingListPagedQueryResponsets
const shoppingLists = await getShoppingLists();

shoppingLists.results.forEach((sl) => {
  console.log(`Shopping List Name: ${sl.name['en-US']}`);
  console.log(`Shopping List ID: ${sl.id}`);
});

Write a resource

Create a new resource

Creating a new resource requires a draft of the resource to create. For Shopping Lists this is a ShoppingListDraft.
Create a Shopping Listts
const newShoppingListDetails: ShoppingListDraft = {
  key: 'shopping-list-key',
  name: { 'en-US': 'English name of Shopping List' },
  description: { 'en-US': 'Description of Shopping List' },
  //customer: { typeId: 'customer', id: 'customer-id' }, // Optional association with a customer
};

/**Post the ShoppingListDraft and get the new Shopping List*/
async function createShoppingList(
  body: ShoppingListDraft
): Promise<ShoppingList> {
  const response = await httpApiRoot.shoppingLists().post({ body }).execute();
  return response.body;
}

await createShoppingList(newShoppingListDetails)
  .then(console.log)
  .catch(console.error);

Update an existing resource

Updating an existing resource requires posting an update payload. This payload (in the case of Shopping Lists, a ShoppingListUpdate) contains a collection of update actions and the last seen version of the resource.
Update a Shopping Listts
/**The `setKey` update action for Shopping Lists */
const setShoppingListKey: ShoppingListSetKeyAction = {
  action: 'setKey',
  key: 'a-new-shoppinglist-key',
};

/**A ShoppingListUpdate containing the `setKey` action */
const shoppingListUpdate: ShoppingListUpdate = {
  version: 1,
  actions: [setShoppingListKey], // You can add more actions to this array to perform multiple updates in one request
};

/**Update an existing Shopping List by its ID */
async function updateShoppingList(
  ID: string,
  body: ShoppingListUpdate
): Promise<ShoppingList> {
  const response = await httpApiRoot
    .shoppingLists()
    .withId({ ID })
    .post({ body })
    .execute();
  return response.body;
}

await updateShoppingList('{shoppingListID}', shoppingListUpdate)
  .then(console.log)
  .catch(console.error);

Delete a resource

Deleting a resource requires using the .delete() method with the last seen version of the resource. You must identify the resource to delete using withId() or withKey().
Delete a Shopping Listts
async function deleteShoppingList(ID: string, version: number) {
  const response = await httpApiRoot
    .shoppingLists()
    .withId({ ID })
    .delete({ queryArgs: { version } })
    .execute();
  return response.body;
}

await deleteShoppingList('{shoppingListID}', 1)
  .then(console.log)
  .catch(console.error);

Use the TypeScript SDK in the browser

You can use the TypeScript SDK as an embedded Universal Module Definition (UMD) module or an imported package in a frontend framework/library such as React.

As an embedded UMD module

Create an HTML file and insert the following code:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>TypeScript SDK Examples</title>
    <script src="https://unpkg.com/browse/@commercetools/ts-client@latest/dist/commercetools-ts-client.umd.js"></script>
    <script src="https://unpkg.com/@commercetools/platform-sdk@latest/dist/commercetools-platform-sdk.umd.js"></script>
  </head>

  <body>
    <!-- Click this button to return the Project details -->
    <p>
      <button onclick="getProjectDetails()">Get Project Information</button>
    </p>

    <!-- This text is overwritten when getProjectDetails() finishes -->
    <p id="details">
      Click the above button to display the Project information.
    </p>
  </body>

  <script>
    // Enter your API client configuration
    var oauthUri = 'https://auth.{region}.commercetools.com';
    var baseUri = 'https://api.{region}.commercetools.com';
    var credentials = {
      clientId: '{clientID}',
      clientSecret: '{clientSecret}',
    };
    var projectKey = '{projectKey}';

    // Builds the client
    var { ClientBuilder } = window['@commercetools/ts-client'];
    var client = new ClientBuilder()
      .defaultClient(baseUri, credentials, oauthUri, projectKey)
      .build();
    var { createApiBuilderFromCtpClient } =
      window['@commercetools/platform-sdk'];
    var httpApiRoot = createApiBuilderFromCtpClient(client).withProjectKey({
      projectKey,
    });

    // Returns the Project details
    function getProjectDetails() {
      httpApiRoot
        .get()
        .execute()
        .then(function ({ body }) {
          window.document.getElementById('details').innerHTML =
            JSON.stringify(body);
        });
    }
  </script>
</html>

When loaded in your web browser this page displays a button that, when clicked, returns your Project information.

The getProjectDetails() function is similar to code examples within this get started guide. Consult the previous code examples to add further functionality to the HTML document.

As an imported package

The following code example is for React TypeScript. Use the following code in the App.tsx file.
import React, { useState, useEffect } from 'react';
import { ClientBuilder, type Client } from '@commercetools/ts-client';
import {
  createApiBuilderFromCtpClient,
  ApiRoot,
} from '@commercetools/platform-sdk';

const BASE_URI = 'https://api.{region}.commercetools.com';
const OAUTH_URI = 'https://auth.{region}.commercetools.com';
const PROJECT_KEY = '{projectKey}';
const CREDENTIALS = {
  clientId: '{clientID}',
  clientSecret: '{clientSecret}',
};

export function App() {
  const [projectDetails, setProjectDetails] = useState({});

  // Create client
  const getClient = (): Client => {
    return new ClientBuilder()
      .defaultClient(BASE_URI, CREDENTIALS, OAUTH_URI, PROJECT_KEY)
      .build();
  };

  // Get apiRoot
  const getApiRoot = (client: Client): ApiRoot => {
    return createApiBuilderFromCtpClient(client);
  };

  useEffect(function () {
    const client = getClient();
    const httpApiRoot = getApiRoot(client);

    httpApiRoot
      .withProjectKey({ projectKey: PROJECT_KEY })
      .get()
      .execute()
      .then(({ body }) => {
        setProjectDetails(body);
      })
      .catch(console.error);
  }, []);

  return (
    <div>
      <h2>Project details for {PROJECT_KEY}:</h2>
      <pre>{JSON.stringify(projectDetails, null, 2)}</pre>
    </div>
  );
}

Next steps

Continue learning about the TypeScript SDK by checking our SDK code examples. You will find example code for creating, querying, and updating Customers and Products.
The Me Endpoint Checkout app also demonstrates how to use the Me endpoints to create an example web store.