AWS Marketplace

Streamlining AWS Marketplace Catalog API Integration

Using AWS Marketplace Catalog API, AWS Marketplace sellers can programmatically manage their AWS Marketplace products, offers, and other entities. Previously, when using the Catalog API, sellers had to deal with freeform JSON payloads, which required manually constructing JSON data to convert it to strings before sending API requests. This added complexity and increased the potential for errors, especially in automated development pipelines. Mistakes made in the JSON data or during string creation were detected after the request was submitted, resulting in delays. In this post, we show developers two new features to remove complexity when using the Catalog API.

To simplify the integration experience, we are excited to announce two key enhancements:

  1. DetailsDocument – This attribute allows sellers to use native JSON objects in their API requests and responses, eliminating the need for manual data conversion.
  2. Catalog API Shape Library – This open-source library for Java and Python provides predefined, strongly-typed shapes that can be used with the AWS SDK, further streamlining the onboarding and integration process for sellers’ technical teams.

Using the DetailsDocument attribute

With the introduction of the DetailsDocument attribute, AWS Marketplace sellers can now create a JSON object in their code and send it directly in the API request without converting it into a string. Previously, sellers would need to send a string like "[{\"ProductTitle\":\"My new title\"}]". Now they can send a payload like {"ProductTitle":"My new title"}, which the Catalog API can seamlessly process.

The new DetailsDocument attribute functionality will exist alongside the current experience of sending and receiving a string object in the Details attribute of the StartChangeSet and DescribeEntity APIs. Sellers who have integrated with these APIs can continue using the Details attribute. We recommend the schema library for new sellers, and we recommend that existing sellers take advantage of the new API features. Responses from the DescribeEntity and DescribeChangeSet actions include both attributes, making it easier to retrieve details from the Catalog API.

Using the Catalog API Shape Library

The open-source Catalog API Shape Library for Java and Python provides predefined, strongly-typed shapes that can be used with the AWS SDK to work with the DetailsDocument attribute. AWS Marketplace sellers can use the Catalog API Shape Library with the AWS SDK to use the strongly-typed JSON shapes in their code. This will help reduce the manual effort required to construct and parse JSON data.

The Catalog API Shape Library is available on GitHub for Java and for Python and includes reference examples to help sellers get started with the DetailsDocument functionality.

Examples

The GitHub repositories contain reference examples for using the Catalog API Shape Library. Here are a few additional examples for demonstration purposes:

1. StartChangeSet

StartChangeSet allows you to request changes for your entities. The following Python sample code makes a StartChangeSet call with UpdateInformation change on a software as a service (SaaS) product using the Catalog API strongly-typed Shape Library.

import boto3
import json

client = boto3.client('marketplace-catalog', region_name='us-east-1')

def update_information():
    from aws_marketplace_catalog_shapes_saasproduct_1_0_changetypes.models.update_information_change_detail import UpdateInformationChangeDetail

    detail = UpdateInformationChangeDetail(
        ProductTitle="SaaS Test product",
        ShortDescription="Short description",
        LongDescription="This is a Long description for test product",
        Sku="sku108"
    )

    entity = {
        "Type": "SaaSProduct@1.0",
        "Identifier": "sample-dc06372f-471f-9731-b50f0fde3ab8"
    }

    response = client.start_change_set(
        Catalog='AWSMarketplace',
        ChangeSet=[{
            'ChangeType': 'UpdateInformation',
            'Entity': entity,
            'DetailsDocument': detail.to_dict()
        }]
    )

    print("Details of the response: ", response)

The following Java sample code makes a StartChangeSet call with UpdateInformation change on a SaaS product using the Catalog API strongly-typed Shape Library.

// import CAPI strongly-typed shape library and AWS SDK for Java

private static Document getUpdateInfoDetailsDoc() {
    UpdateInformationChangeDetail updateInformation = new UpdateInformationChangeDetail()
            .sku("sku19090123123")
            .productTitle("New Test Product")
            .shortDescription("Short description")
            .longDescription("This is a long description for the test product.");

    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    Document detailsDoc = null;
    try {
        detailsDoc = DocumentConverter.jsonToDocument(mapper.writeValueAsString(updateInformation));
        System.out.println(mapper.writeValueAsString(updateInformation));
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }

    return detailsDoc;
}

private static List<Change> createChangeSet() {
    List<Change> changeSet = new ArrayList<>();

    Entity entity = Entity.builder()
            .type("SaaSProduct@1.0")
            .identifier("sample-dc06372f-471f-9731-b50f0fde3ab8")
            .build();

    Document detailsDoc = getUpdateInfoDetailsDoc();

    Change changeRequest = Change.builder()
            .changeName("UpdateProduct")
            .changeType("UpdateInformation")
            .entity(entity)
            .detailsDocument(detailsDoc)
            .build();

    changeSet.add(changeRequest);

    return changeSet;
}

public static void main(String[] args) {
    StartChangeSetRequest.Builder requestBuilder = StartChangeSetRequest.builder();
    requestBuilder.catalog("AWSMarketplace");
    requestBuilder.changeSetName("Update product information");
    requestBuilder.changeSet(createChangeSet());

    StartChangeSetRequest request = requestBuilder.build();
    MarketplaceCatalogClient marketplaceCatalogClient = MarketplaceCatalogClient.builder()
            .region(Region.US_EAST_1)
            .endpointOverride(URI.create("https://catalog.marketplace.us-east-1.amazonaws.com"))
            .build();
    StartChangeSetResponse response = marketplaceCatalogClient.startChangeSet(request);

    System.out.println(request);
    System.out.print(response);
}

2. DescribeChangeSet

DescribeChangeSet provides information about a given change set. In the following Python example, we request the status of the change set sample-dl2oc4xwoiksisp7izzvpxhd2 by calling DescribeChangeSet with the ChangeSetId ID using the Catalog API strongly-typed Shape Library for a container-based product.

from aws_marketplace_catalog_shapes_containerproduct_1_0_changetypes.models.update_information_change_detail import UpdateInformationChangeDetail

def describe_change_set():
    response = client.describe_change_set(
        Catalog='AWSMarketplace',
        ChangeSetId='sample-dl2oc4xwoiksisp7izzvpxhd2'
    )

    print("Change Set ID: ", response['ChangeSetId'])
    print("Change Set ARN: ", response['ChangeSetArn'])
    print("Change Set Status:", response['Status'])

    change_set = response['ChangeSet']
    filtered_change_set = list(filter(is_product, change_set))
    details_doc = filtered_change_set[0]['DetailsDocument']
    update_info = UpdateInformationChangeDetail.from_json(json.dumps(details_doc))

    # additional steps to process the shape object.
    print(update_info['logo_url'])

def is_product(change):
    if change['ChangeType'] == 'UpdateInformation' and change['Entity']['Type'] != 'Offer@1.0':
        return True
    else:
        return False

In this Java sample code, we make a DescribeChangeSet call using the Catalog API strongly-typed Shape Library for a container-based product.

DescribeChangeSetRequest request = DescribeChangeSetRequest.builder()
    .catalog("AWSMarketplace")
    .changeSetId("sample-dl2oc4xwoiksisp7izzvpxhd2")
    .build();

DescribeChangeSetResponse response = client.describeChangeSet(request);

System.out.println("Change Set ID: " + response.changeSetId());
System.out.println("Change Set Arn: " + response.changeSetArn());
System.out.println("Status: " + response.status());

response.changeSet()
    .stream()
    .filter(c -> c.changeType().equals("UpdateInformation"))
    .filter(c -> !c.entity().type().equals("Offer@1.0"))
    .forEach(c -> {
        Document detailsDoc = c.detailsDocument();
        String details = detailsDoc.toString();
        try {
            ObjectMapper mapper = new ObjectMapper();
            UpdateInformationChangeDetail updateInformationDetails = mapper.readValue(details, UpdateInformationChangeDetail.class);
            // additional steps to process updateInformationDetails shape object...
            System.out.println("Product Logo URL: " + updateInformationDetails.getLogoUrl());
        } catch (Exception e) {
            System.out.println(e);
        }
    });

3. DescribeEntity

DescribeEntity returns the metadata and content of the entity. In the following Python sample code, we make a DescribeEntity call on a SaaS product using the Catalog API strongly-typed Shape Library.

def describe_entity():
    from aws_marketplace_catalog_shapes_saasproduct_1_0_entitytype.models.saa_s_product_entity_detail import SaaSProductEntityDetail

    response = client.describe_entity(
        Catalog='AWSMarketplace',
        EntityId='sample-dc06372f-471f-9731-b50f0fde3ab8'
    )

    entity_detail = SaaSProductEntityDetail.from_json(json.dumps(response['DetailsDocument']))
    print("Details Document of the response: ", entity_detail)

In the following Java sample code, we make a DescribeEntity call on an offer using the Catalog API strongly-typed Shape Library.

DescribeEntityRequest request = DescribeEntityShape.builder()
    .entityId("offer-test-pucac2hl5zm5i")
    .catalog("AWSMarketplace")
    .build();

DescribeEntityResponse response = client.describeEntity(request);

String details = response.detailsDocument().toString();
ObjectMapper mapper = new ObjectMapper();
OfferEntityDetail offerEntityDetails = mapper.readValue(details, OfferEntityDetail.class);

List<Term> terms = offerEntityDetails.getTerms();
terms.stream()
    .filter(term -> term != null && term.getType().equals("LegalTerm"))
    .forEach(term -> {
        List<DocumentItem> docItems = term.getDocuments();
        DocumentItem docItem = docItems.get(0);
        System.out.println("Document Type : " + docItem.getType());
        // additional steps on using the document.
    });

Strongly-typed JSON supports Catalog API actions DescribeEntity, StartChangeSet, and DescribeChangeSet. With the AWS Marketplace Catalog API Shape Library for Java and Python, developers can simplify automated AWS Marketplace listing actions in their pipelines.

Conclusion

With the AWS Marketplace Catalog API, sellers can programmatically manage their products, offers, and other entities. To further help our sellers, we’ve enhanced the API predefined, strongly-typed shapes that eliminate the need for manual JSON conversion.

By simplifying the integration process, sellers can focus on delivering great customer experiences rather than getting encumbered by API complexities. The DetailsDocument attribute and the open-source AWS Marketplace Catalog API Shape Library for Java and Python significantly streamlines the integration experience, particularly for technical teams.

We encourage AWS Marketplace seller development teams to explore these new enhancements and use the Catalog API Shape Library to streamline their product management workflows and accelerate their time-to-market.

The AWS Marketplace Catalog API Shape Library is available on GitHub for Java and Python.

To learn more about the Catalog API, see Working with single-AMI products and Working with container-based products in the AWS Marketplace Catalog API Reference.

About the author

Jonathan is a Principal Partner Solutions Architect focused on Media & Entertainment Media Supply Chain & Archive. He has over 25 years’ experience in Media and Broadcast operations and engineering. By leveraging his broad expertise in broadcast and cloud, he seamlessly integrates the two domains, encompassing high-speed file transfer, asset management, orchestration, and production design and engineering. Notable career successes include transmitting live HD video over internet from Cuba, architecting WWE OTT Network, and overseeing multi-million dollar broadcast facilities and dark fiber networks.
Chandrashekar Vishweshwara is a Specialist Solutions Architect with AWS Marketplace. In this role, Chandrashekar helps sellers with onboarding products to AWS Marketplace. Outside of work, he spends time with his family and puppy, goes out for walks, or watches movies.
Tasrin Amin is a Technical Business Developer with APN Delivery. She helps AWS Marketplace sellers and buyers integrating with AWS Services and bringing in more adoption to businesses. In her free time, she likes to explore US National and State Parks, binge watches TV shows, and travels around with her friends and family.