Manage Products with the API

Learn how to create and manage Products using the HTTP API

Objectives of this guide

By the end of this guide you will have:

Placeholder values

Example code in this getting started guide uses placeholders that should be replaced with these values:

PlaceholderReplace withFrom
{projectKey}project_keyyour API Client
{region}your RegionHosts
${BEARER_TOKEN}your access tokenMake your first API call

How commercetools Composable Commerce models Products

Creating Products requires more steps than creating Customers. This is due to how Products are modeled in commercetools.

Create a Product Type

Product Types are a set of attributes which acts as a template for a group of similar Products.

Your Project must have a ProductType before Products can be created.

ProductTypes are created by posting a ProductTypeDraft to the Product Types endpoint.

Create a ProductTypeDraft

The ProductTypeDraft has two required fields: name and description.

ProductTypeDraft to create a ProductType with a name and descriptionjson
{
"name": "Our ProductType",
"description": "Our ProductType description"
}

Post the ProductTypeDraft

Post the ProductTypeDraft to the Product Types endpoint and a new ProductType is created with the specified name and description.

Below is an example API call with the returned new ProductType resource:

Example request to create a Product Type
POST https://api.{region}.commercetools.com/{projectKey}/product-types
Authorization: Bearer ${BEARER_TOKEN}
{
"name": "Our ProductType",
"description": "Our ProductType description"
}
Returned ProductType resourcejson
{
"id": "{productTypeID}",
"version": 1,
"createdAt": "2023-10-20T15:38:10.934Z",
"lastModifiedAt": "2023-10-20T15:38:10.934Z",
"lastModifiedBy": {
"isPlatformClient": true,
"user": {
"typeId": "user",
"id": "{clientID}"
}
},
"createdBy": {
"isPlatformClient": true,
"user": {
"typeId": "user",
"id": "{clientID}"
}
},
"name": "Our ProductType",
"description": "Our ProductType description",
"classifier": "Complex",
"attributes": []
}

Take note of the highlighted {productTypeID} in your response as it is used as a placeholder in following examples.

Get your new ProductType

Your new Product Type can be retrieved by using the {productTypeID} as a path parameter.

When you make a GET call to this endpoint, you retrieve all the data of this Product Type.

Example request to query a Product Type
GET https://api.{region}.commercetools.com/{projectKey}/product-types/{productTypeID}
Authorization: Bearer ${BEARER_TOKEN}
Returned ProductType resourcejson
{
"id": "{productTypeID}",
"version": 1,
"createdAt": "2023-10-20T15:38:10.934Z",
"lastModifiedAt": "2023-10-20T15:38:10.934Z",
"lastModifiedBy": {
"isPlatformClient": true,
"user": {
"typeId": "user",
"id": "{clientID}"
}
},
"createdBy": {
"isPlatformClient": true,
"user": {
"typeId": "user",
"id": "{clientID}"
}
},
"name": "Our ProductType",
"description": "Our ProductType description",
"classifier": "Complex",
"attributes": []
}

Create a Product

Now that you have a ProductType, you can create your first Product.

Products are created by posting a ProductDraft to the Products endpoint.

Create a ProductDraft

The ProductDraft has three required object literals: name, productType, and slug that have their own key/value pairs.

ProductDraft to create a Product with name, productType, and slugjson
{
"name": {
"de": "German name for new product",
"en": "English name for new product"
},
"productType": {
"id": "{productTypeID}"
},
"slug": {
"de": "human-readable-url-for-german-name",
"en": "human-readable-url-for-english-name"
}
}

name is a LocalizedString, which uses key-value pairs where the key is a two-character IETF language tag. In this case de is German and en is English.

productType is the ResourceIdentifier of the Product Type this Product uses.

slug is a LocalizedString that contains human-readable identifiers used in online shops as deep-link URLs to the related product. They must be unique across your Project.

Post the ProductDraft

Post the ProductDraft to the Products endpoint, and a new Product is created with the specified name, productType, and slug.

Below is an example API call with the returned new Product resource:

Example request to create a Product
POST https://api.{region}.commercetools.com/{projectKey}/products
Authorization: Bearer ${BEARER_TOKEN}
{ "name": { "de": "German name for new product", "en": "English name for new product" }, "productType": { "id": "{productTypeID}" }, "slug": { "de": "human-readable-url-for-german-name", "en": "human-readable-url-for-english-name" } }
Returned Product resourcejson
{
"id": "{productID}",
"version": 1,
"createdAt": "2023-10-23T13:10:58.776Z",
"lastModifiedAt": "2023-10-23T13:10:58.776Z",
"lastModifiedBy": {
"clientId": "{clientID}",
"isPlatformClient": false
},
"createdBy": {
"clientId": "{clientID}",
"isPlatformClient": false
},
"productType": {
"typeId": "product-type",
"id": "{productTypeID}"
},
"masterData": {
"current": {
"name": {
"de": "German name for new product",
"en": "English name for new product"
},
"categories": [],
"categoryOrderHints": {},
"slug": {
"de": "human-readable-url-for-german-name",
"en": "human-readable-url-for-english-name"
},
"masterVariant": {
"id": 1,
"prices": [],
"images": [],
"attributes": [],
"assets": []
},
"variants": [],
"searchKeywords": {}
},
"staged": {
"name": {
"de": "German name for new product",
"en": "English name for new product"
},
"categories": [],
"categoryOrderHints": {},
"slug": {
"de": "human-readable-url-for-german-name",
"en": "human-readable-url-for-english-name"
},
"masterVariant": {
"id": 1,
"prices": [],
"images": [],
"attributes": [],
"assets": []
},
"variants": [],
"searchKeywords": {}
},
"published": false,
"hasStagedChanges": false
},
"lastVariantId": 1
}

Take note of the highlighted {productID} in your response as it is used as a placeholder in following examples.

Get your new Product

Your new Product can be retrieved by using the {productID} as a path parameter.

When you make a GET call to this endpoint, you will retrieve all the data of this Product.

Example request to query a Product
GET https://api.{region}.commercetools.com/{projectKey}/products/{productID}
Authorization: Bearer ${BEARER_TOKEN}
Returned Product resourcejson
{
"id": "{productID}",
"version": 1,
"createdAt": "2023-10-23T13:10:58.776Z",
"lastModifiedAt": "2023-10-23T13:10:58.776Z",
"lastModifiedBy": {
"clientId": "{clientID}",
"isPlatformClient": false
},
"createdBy": {
"clientId": "{clientID}",
"isPlatformClient": false
},
"productType": {
"typeId": "product-type",
"id": "{productTypeID}"
},
"masterData": {
"current": {
"name": {
"de": "German name for new product",
"en": "English name for new product"
},
"categories": [],
"categoryOrderHints": {},
"slug": {
"de": "human-readable-url-for-german-name",
"en": "human-readable-url-for-english-name"
},
"masterVariant": {
"id": 1,
"prices": [],
"images": [],
"attributes": [],
"assets": []
},
"variants": [],
"searchKeywords": {}
},
"staged": {
"name": {
"de": "German name for new product",
"en": "English name for new product"
},
"categories": [],
"categoryOrderHints": {},
"slug": {
"de": "human-readable-url-for-german-name",
"en": "human-readable-url-for-english-name"
},
"masterVariant": {
"id": 1,
"prices": [],
"images": [],
"attributes": [],
"assets": []
},
"variants": [],
"searchKeywords": {}
},
"published": false,
"hasStagedChanges": false
},
"lastVariantId": 1
}

Create a Product Variant

Products contain Product Variants that represent single sellable products (usually an individual SKU).

The Composable Commerce API uses update actions to add Product Variants.

Create an update action array to add a Product Variant

The required update action is Add ProductVariant.

The current version of the Product is also required.

The version of a new Product is 1. This value is incremented every time an update action is applied to the Product.

If the specified version does not match the current version, the request returns an error.

Product version and update actions array to add a Product Variantjson
{
"version": 1,
"actions": [
{
"action": "addVariant",
"sku": "myProductVariantSKU",
"key": "my-product-variant-key"
}
]
}

Post the update action array

Post this update action array with the current Product version to the {productID} endpoint and the Product is updated with a new Variant and its sku and key.

Below is an example API call with the updated Product resource:

Example request to create a Product
POST https://api.{region}.commercetools.com/{projectKey}/products/{productID}/
Authorization: Bearer ${BEARER_TOKEN}
{
"version": 1,
"actions": [
{
"action": "addVariant",
"sku": "myProductVariantSKU",
"key": "my-product-variant-key"
}
]
}
Returned Product resource with new Variantjson
{
"id": "{productID}",
"version": 3,
"createdAt": "2023-10-23T13:10:58.776Z",
"lastModifiedAt": "2023-10-23T13:13:00.874Z",
"lastModifiedBy": {
"clientId": "{clientID}",
"isPlatformClient": false
},
"createdBy": {
"clientId": "{clientID}",
"isPlatformClient": false
},
"productType": {
"typeId": "product-type",
"id": "{productTypeID}"
},
"masterData": {
"current": {
"name": {
"de": "German name for new product",
"en": "English name for new product"
},
"categories": [],
"categoryOrderHints": {},
"slug": {
"de": "human-readable-url-for-german-name",
"en": "human-readable-url-for-english-name"
},
"masterVariant": {
"id": 1,
"prices": [],
"images": [],
"attributes": [],
"assets": []
},
"variants": [],
"searchKeywords": {}
},
"staged": {
"name": {
"de": "German name for new product",
"en": "English name for new product"
},
"categories": [],
"categoryOrderHints": {},
"slug": {
"de": "human-readable-url-for-german-name",
"en": "human-readable-url-for-english-name"
},
"masterVariant": {
"id": 1,
"prices": [],
"images": [],
"attributes": [],
"assets": []
},
"variants": [
{
"id": 2,
"sku": "myProductVariantSKU",
"key": "my-product-variant-key",
"prices": [],
"images": [],
"attributes": [],
"assets": []
}
],
"searchKeywords": {}
},
"published": false,
"hasStagedChanges": true
},
"lastVariantId": 2
}

Next steps

To learn more about managing Products you can consult the HTTP API reference.

For further practice in managing Products, you could also try further update actions such as adding a description or changing the master Product Variant.