# 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. For a guided hands-on tutorial, see [Set up the TypeScript SDK](/learning-composable-commerce-developer-essentials/prepare-your-work-environment/set-up-the-typescript-sdk.md) in the Developer Essentials learning path. ## Requirements To follow this guide you should have the following: - A commercetools Project - An [API Client](/api/projects/api-clients.md) - 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 Project or API Client, follow our [Getting started with commercetools](/api/getting-started/initial-setup.md) guides. ## Objectives of the get started guide After following this guide, you will have: - [Installed the TypeScript SDK](/dev-tooling/ts-sdk-getting-started.md#install-the-typescript-sdk) - [Created a client](/dev-tooling/ts-sdk-getting-started.md#create-the-client) - [Tested your client](/dev-tooling/ts-sdk-getting-started.md#test-the-client) - [Learned how to make API calls with the TypeScript SDK](/dev-tooling/ts-sdk-getting-started.md#structure-your-api-call) ## 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](/api/getting-started/create-api-client.md) guide. | Placeholder | Replace with | From | | --- | --- | --- | | `{projectKey}` | project\_key | your API Client | | `{clientID}` | client\_id | your API Client | | `{clientSecret}` | secret | your API Client | | `{scope}` | scope | your API Client | | `{region}` | your Region | [Hosts](/api/general-concepts.md#hosts) | ## Install the TypeScript SDK Use the following command to install the SDK Client: ```sh npm install @commercetools/ts-client # or yarn add @commercetools/ts-client ``` To access the [HTTP API](/api/), [Import API](/api/import-export/overview.md), [Audit Log API](/api/history/overview.md), or [Checkout API](/checkout), install the following packages as needed: ```sh npm install @commercetools/platform-sdk # or yarn add @commercetools/platform-sdk ``` ```sh npm install @commercetools/importapi-sdk # or yarn add @commercetools/importapi-sdk ``` ```sh npm install @commercetools/history-sdk # or yarn add @commercetools/history-sdk ``` ```sh 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. ```ts 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(); ``` ```ts 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(); ``` ```ts 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(); ``` ```ts 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`](/dev-tooling/ts-sdk-middleware.md#withclientcredentialsflow)) and [HttpMiddleware](/dev-tooling/ts-sdk-middleware.md#httpmiddleware) `authMiddlewareOptions`, `httpMiddlewareOptions`, and `withLoggerMiddleware` to handle auth, API requests, and logging respectively. For details on the OAuth 2.0 flows that underlie these middleware options, see [Authorization](/api/authorization.md). 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](https://docs.commercetools.com/dev-tooling/images/ts-sdk/ts-sdk-middleware.png) You can learn more about configuring and using middleware on the [Middleware](/dev-tooling/ts-sdk-middleware.md) 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. ```ts 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 { 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. ```ts 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 { 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. ```ts 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. ```ts 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 { 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`. ```ts 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. ```ts 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. You can find a full list of available resources in the [TypeScript SDK reference](https://commercetools.github.io/commercetools-sdk-typescript/). ### 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. ```ts 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](/api/), [Import API](/api/import-export/overview.md), [Audit Log API](/api/history/overview.md), and [Checkout API](/checkout) 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: ```ts 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](/api/projects/project.md). ### Retrieve data #### Get a single resource When targeting a specific resource, include its ID or key followed by `.get()` and `.execute()`. ```ts async function getShoppingListById(ID: string): Promise { const response = await httpApiRoot .shoppingLists() .withId({ ID }) .get() .execute(); return response.body; } await getShoppingListById('a-shoppinglist-id') .then(console.log) .catch(console.error); ``` ```ts async function getShoppingListByKey(key: string): Promise { 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](/api/errors.md#404-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](/api/general-concepts.md#pagedqueryresult) in the HTTP API. ```ts async function getShoppingLists(): Promise { 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`](/api/predicates/query.md), [`sort`](/api/general-concepts.md#sorting), [`expand`](/api/general-concepts.md#reference-expansion), [`limit`](/api/general-concepts.md#limit), and/or [`offset`](/api/general-concepts.md#offset) ```ts async function getShoppingLists(): Promise { 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. ```ts 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](/urn?urn=ctp%3Aapi%3Atype%3AShoppingListDraft). ```ts 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 { 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. ```ts /**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 { 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()`. ```ts 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: ```html TypeScript SDK Examples

Click the above button to display the Project information.

``` 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. ```tsx 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 (

Project details for {PROJECT_KEY}:

{JSON.stringify(projectDetails, null, 2)}
); } ``` ## Next steps Continue learning about the TypeScript SDK by checking our [SDK code examples](/dev-tooling/sdk-example-code?activePath=ts). You will find example code for creating, querying, and updating Customers and Products. The [Me Endpoint Checkout app](/dev-tooling/sdk-example-applications.md#me-endpoint-checkout-app) also demonstrates how to use the [Me endpoints](/api/me-endpoints-overview.md) to create an example web store. ## Related pages - [Area overview page with navigation](/dev-tooling.md) - [Previous page: Overview](/dev-tooling/typescript-sdk.md) - [Next page: Middleware](/dev-tooling/ts-sdk-middleware.md)