Utilize the latest features of the Import API
After completing this page, you should be able to:
- Be aware of the new way Embedded Prices and Product Variants are imported and published.
- Demonstrate how Discount Codes can be imported using the new Import API endpoint.
Time to complete page: 15 minutes
You probably already know that the Import API is a simple way for asynchronously importing large quantities of resources to your Composable Commerce project.
Key benefits of the Import API include:
- Asynchronous Processing: You can send large datasets without blocking your application, improving performance and user experience.
- Resource Specific: Import different resource types independently, allowing for focused data management.
- Automatic Dependency Handling: The API automatically resolves dependencies between resources, simplifying the import process.
- API-First Approach: Integrates seamlessly with modern application infrastructure, offering flexibility and automation possibilities.
Importing Discount Codes
In 2024 we have extended the list of resources supported by the Import API by adding the possibility for importing Discount Codes. This gives our customers even more flexibility in how they can manage Discount Codes in their Project.
The example below will show you how to:
- Create an Import Container
- Submit a DiscountCodeImportRequest:
The following examples do not include instructions for creating the Import API client. To do that please follow the instructions provided in the Developer Essentials Learning Path.
// Ensure all necessary imports are included
String importContainerKey = "renewal_container_2025";
// Create an Import Container
importApiRoot
.importContainers()
.post(ImportContainerDraftBuilder.of().key(importContainerKey).build())
.executeBlocking();
// Import Discount Code
System.out.println(
"Cart Discount import operation status: " +
importApiRoot
.discountCodes()
.importContainers()
.withImportContainerKeyValue(importContainerKey)
.post(
DiscountCodeImportRequestBuilder
.of()
.resources(
DiscountCodeImportBuilder
.of()
.code("VIPBOGO")
.key("bogo_vip")
.name(
LocalizedStringBuilder
.of()
.addValue("en-GB", "VIP BOGO")
.addValue("en-US", "VIP BOGO")
.addValue("de-DE", "VIP BOGO")
.build()
)
.cartDiscounts(
CartDiscountKeyReferenceBuilder.of().key("FurnitureBOGO").build()
)
.isActive(true)
.build()
)
.build()
)
.executeBlocking()
.getBody()
.getOperationStatus()
);
importApiRoot.close();
As always you can see the status of your Import operations by making an API request to the /import-operations
endpoint or in the Merchant Center by going to Operations ➜ Import and selecting your Import Container.
You may have also noticed Discount Codes now have a key
field available. Previously, you could identify them only by their auto-generated ID
s. Using keys in commercetools simplifies development by providing clear, human-readable identifiers, replacing complex UUIDs, and improving code readability. Keys reduce errors, streamline data management, and enable seamless integration with external systems, making workflows more efficient and organized. Not to mention that, keys are persistent when migrating resources between Projects!
Importing Product Variants and Embedded Prices
While importing Product Variants and Embedded Prices was available since the introduction of the Import API, some changes were made to better indicate which projection should be considered.
To simplify the import process for Embedded Prices and Product Variants, we have introduced the staged
field to both EmbeddedPriceImport
and ProductVariantImport
. This new field allows you to specify whether the imported data should apply to the current
or staged
representation of the Product being updated.
The staged
field replaces the deprecated publish
field, which was removed on 1 August 2024.
This update aligns the Import API with the HTTP API by standardizing the fields used for the same purpose. If you were previously using the publish
field for importing Embedded Prices and Product Variants, you should now use the staged
field and adjust its value according to your specific requirements.
Let’s import a new variant for the Travel Coffee Mug Product to see how this works:
// Ensure all necessary imports are included
// We will reuse the container from the previous example
String importContainerKey = "renewal_container_2025";
// Import Product Variant
System.out.println(
"Product Variant import operation status: " +
importApiRoot
.productVariants()
.importContainers()
.withImportContainerKeyValue(importContainerKey)
.post(
ProductVariantImportRequestBuilder
.of()
.resources(
ProductVariantImportBuilder
.of()
.key("TCM-04")
.sku("TCM-04")
.isMasterVariant(false)
.staged(false) // true (default) only updates the Staged projection, false updates both Staged and Current
.attributes(
AttributeBuilder
.of()
.booleanBuilder()
.name("new-arrival")
.value(true)
.build(),
AttributeBuilder
.of()
.ltextBuilder()
.name("color")
.value(
LocalizedStringBuilder
.of()
.addValue("en-GB", "Beige:#F5F5DC")
.addValue("en-US", "Beige:#F5F5DC")
.addValue("de-DE", "Beige:#F5F5DC")
.build()
)
.build()
)
.product(
ProductKeyReferenceBuilder.of().key("travel-coffee-mug").build()
)
.build()
)
.build()
)
.executeBlocking()
.getBody()
.getOperationStatus()
);
importApiRoot.close();