HomeGuidesAPI Reference
ChangelogHelp CenterCommunityContact Us
API Reference

Catalogs API overview

Before you begin

Check out our general API overview to make sure you’re ready to get started with specific endpoints.

Catalogs are used to represent products that can be referenced in message templates. Our Catalogs API populates catalog information via API to power product recommendations, back in stock, and dynamic catalog lookups.

📘

Note that you can only use either the API or custom catalog feed to import catalog products.

Use cases

The Catalogs API supports the following use cases:

  • Get, create, and manage catalog resources (items, variants, and categories), including creating new catalog resources in bulk.
  • Fetch bulk creation jobs to monitor status.
  • Subscribe a profile to receive back in stock subscriptions.

Data model

You can create the following resources with the Catalogs API:

  • Items

    The products that make up your catalog.

  • Variants

    The different options or versions of a catalog item.

  • Categories

    The groupings of catalog items based on shared characteristics.

  • Back in stock subscriptions

    Subscribe a profile to receive back in stock notifications.

In the sections below, learn about each resource type and the data model that defines them.

Items and variants

Catalog items are the individual products your catalog lists (e.g., a t-shirt). Each item represents a single product in your store.

Variants represent the different options or versions of a catalog item. For example, a single catalog item (a t-shirt) might have multiple variants for size, color, and material.

Catalog items and variants have similar data models that represent their fundamental properties. These shared properties include:

  • id

    The catalog item or variant ID.

  • attributes

    • external_id (required)

      The ID of the catalog item or variant in an external system.

    • integration_type

      The integration type (e.g., $custom). Currently, only custom integrations are supported.

    • title (required)

      The title of the catalog item or variant.

    • price

      The price of the catalog item or variant. This is displayed when you include an item or variant in an email. Use price to trigger price-drop flows.

    • catalog_type

      The type of catalog (e.g., $default). Currently, default is the only supported catalog type.

    • description (required)

      A description of the catalog item or variant.

    • url (required)

      The URL pointing to the location of the catalog item or variant on your website.

    • image_full_url

      The URL pointing to the location of a full image of the catalog item or variant.

    • image_thumbnail_url

      The URL pointing to the location of an image thumbnail of the catalog item or variant.

    • images

      List of URLs pointing to the locations of images of the catalog item or variant.

    • custom_metadata

      A flat JSON blob to provide custom metadata about the catalog item or variant. May not exceed 100kb.

    • published

      Whether the catalog item or variant is published.

  • relationships (required)

    This object contains related resources. For a catalog item, this object contains the categories object that holds an array of objects representing categories associated with the catalog item (e.g., “Home Decor”). For a catalog variant, this object contains the catalog item for which it is a variant (items object). Learn more about relationships.

🚧

Note if you update the price for a catalog item (Update Catalog Item), you have to update the price on any child variants using the Update Catalog Variant endpoint and vice versa.

Unique fields for variants

In addition to the attributes detailed above, variants hold inventory data. This is critical for back in stock or low inventory flows:

  • sku (required)

    The SKU of the catalog item variant.

  • inventory_policy

    A field that controls the visibility of this catalog item variant in product feeds/blocks. Defaults to 0; the product can appear in dynamic product recommendation feeds and blocks regardless of inventory quantity.

  • inventory_quantity (required)

    The quantity of the catalog item variant currently in stock.

Categories

Categories are used in marketing campaigns to create personalized recommendations based on a customer’s preferences or browsing behavior. A category consists of the following:

  • id

    The category ID.

  • attributes

    • external_id (required)

      The ID of the catalog category in an external system.

    • name (required)

      The name of the catalog category.

    • integration_type

      The integration type (e.g., $custom). Currently, only custom integrations are supported.

    • catalog_type

      The type of catalog (e.g., $default). Currently, default is the only supported catalog type.

  • relationships (required)

    • items

      An object that contains an array of objects representing the catalog item IDs that are in a given category.

Back in stock subscriptions

You can use Create Back In Stock Subscription to subscribe a profile to back in stock notifications. Check out our Back in Stock API guide for more details.

Create catalog resources

The sections below contain examples on creating catalog items, variants, and categories.

📘

Make sure that your create payload contains all required fields, otherwise the request will immediately return a 400 error.

Create catalog item

To create a catalog item, you’ll need an external ID, item title, description, product URL, and the catalog category it belongs to.

You may also include optional information for your item such as image URLs, as shown in this request payload for Create Catalog Item:

{
   "data": {
       "type": "catalog-item",
       "attributes": {
           "external_id": "3829918373-TShirt-1",
           "title": "T-Shirt",
           "description": "This is the description of the t-shirt.",
           "url": "https://via.placeholder.com/150",
           "integration_type": "$custom",
           "catalog_type": "$default",
           "image_full_url": "https://via.placeholder.com/300",
           "image_thumbnail_url": "https://via.placeholder.com/200",
           "images": [
               "https://via.placeholder.com/150",
               "https://via.placeholder.com/150"
           ],
           "published": true
       },
       "relationships": {
           "categories": {
               "data": [
                   {
                       "type": "catalog-category",
                       "id": "$custom:::$default:::SummerApparel"
                   }
               ]
           }
       }
   }
}
{
    "data": {
        "type": "catalog-item",
        "id": "$custom:::$default:::3829918373-TShirt-1",
        "attributes": {
            "external_id": "3829918373-TShirt-1",
            "title": "T-Shirt",
            "description": "This is the description of the t-shirt.",
            "price": null,
            "url": "https://via.placeholder.com/150",
            "image_full_url": "https://via.placeholder.com/300",
            "image_thumbnail_url": "https://via.placeholder.com/200",
            "images": [
                "https://via.placeholder.com/150",
                "https://via.placeholder.com/150"
            ],
            "custom_metadata": {},
            "published": true,
            "created": "2025-01-09T18:52:14.425000+00:00",
            "updated": "2025-01-09T18:52:14.425000+00:00"
        },
        "relationships": {
            "variants": {
                "links": {
                    "self": "https://a.klaviyo.com/api/catalog-items/$custom:::$default:::3829918373-TShirt-1/relationships/variants/",
                    "related": "https://a.klaviyo.com/api/catalog-items/$custom:::$default:::3829918373-TShirt-1/variants/"
                }
            }
        },
        "links": {
            "self": "https://a.klaviyo.com/api/catalog-items/$custom:::$default:::3829918373-TShirt-1/"
        }
    },
    "links": {
        "self": "https://a.klaviyo.com/api/catalog-items"
    }
}

Create catalog variant

After creating a catalog item, you need to associate a variant with the item using the relationships attribute. To create a catalog variant for a catalog item you’ll need its external ID, variant title, description, product URL, SKU, inventory quantity, and the catalog item it falls under. Typically, the price field is used for catalog variants.

This payload for Create Catalog Variant creates a blue variant of the T-shirt item created in the previous example:

{
  "data": {
      "type": "catalog-variant",
      "attributes": {
          "external_id": "3829918373-Blue-TShirt-1",
          "title": "Blue T-Shirt",
          "description": "Classic Blue T-Shirt.",
          "sku": "classic-blue-tee-99970742258",
          "inventory_quantity": 50,
          "price": 24.99,
          "url": "https://via.placeholder.com/150",
          "published": true
      },
      "relationships": {
          "item": {
              "data": {
                  "type": "catalog-item",
                  "id": "$custom:::$default:::3829918373-TShirt-1"
              }
          }
      }
  }
}
{
    "data": {
        "type": "catalog-variant",
        "id": "$custom:::$default:::3829918373-Blue-TShirt-1",
        "attributes": {
            "external_id": "3829918373-Blue-TShirt-1",
            "title": "Blue T-Shirt",
            "description": "Classic Blue T-Shirt.",
            "sku": "classic-blue-tee-99970742258",
            "inventory_policy": 1,
            "inventory_quantity": 50.0,
            "price": 24.99,
            "url": "https://via.placeholder.com/150",
            "image_full_url": "",
            "image_thumbnail_url": "",
            "images": [],
            "custom_metadata": {},
            "published": true,
            "created": "2025-01-09T19:03:00.577000+00:00",
            "updated": "2025-01-09T19:03:00.577000+00:00"
        },
        "relationships": {
            "item": {
                "links": {
                    "self": "https://a.klaviyo.com/api/catalog-variants/$custom:::$default:::3829918373-Blue-TShirt-1/relationships/item/",
                    "related": "https://a.klaviyo.com/api/catalog-variants/$custom:::$default:::3829918373-Blue-TShirt-1/item/"
                }
            }
        },
        "links": {
            "self": "https://a.klaviyo.com/api/catalog-variants/$custom:::$default:::3829918373-Blue-TShirt-1/"
        }
    },
    "links": {
        "self": "https://a.klaviyo.com/api/catalog-variants"
    }
}

🚧

Due to how Klaviyo’s catalog lookup tag works, we recommend using different external IDs for the parent item and variants. If there are duplicate external IDs across items and variants, the catalog tag will default to returning the item without the variant.

Create catalog category

To create a catalog category, you’ll need its external ID, name, and a list of catalog item IDs for items that fit under the category.

❗️

Special characters in category external IDs

When creating a category, any special characters (including spaces) in the external ID are stripped. For example, an external ID like Winter-Apparel-2025 will be processed internally as WinterApparel2025. Creating another category with an external ID such as Winter_Apparel_2025 will result in the same processed value, causing a 409 error (duplicate_category).

The request payload and response for Create Catalog Category below will create another category "Gym Apparel" that is used to categorize the T-Shirt item that was created earlier:

{
   "data": {
       "type": "catalog-category",
       "attributes": {
           "external_id": "GymApparel12345",
           "name": "Gym Apparel",
           "integration_type": "$custom",
           "catalog_type": "$default"
       },
       "relationships": {
           "items": {
               "data": [
                   {
                       "type": "catalog-item",
                       "id": "$custom:::$default:::3829918373-TShirt-1"
                   }
               ]
           }
       }
   }
}
{
    "data": {
        "type": "catalog-category",
        "id": "$custom:::$default:::GymApparel12345",
        "attributes": {
            "external_id": "GymApparel12345",
            "name": "Gym Apparel",
            "updated": "2025-01-09T19:11:58.547000+00:00"
        },
        "relationships": {
            "items": {
                "links": {
                    "self": "https://a.klaviyo.com/api/catalog-categories/$custom:::$default:::GymApparel12345/relationships/items/",
                    "related": "https://a.klaviyo.com/api/catalog-categories/$custom:::$default:::GymApparel12345"
                }
            }
        },
        "links": {
            "self": "https://a.klaviyo.com/api/catalog-categories/$custom:::$default:::GymApparel12345/"
        }
    },
    "links": {
        "self": "https://a.klaviyo.com/api/catalog-categories"
    }
}

When the category IDs are fetched for T-Shirt, the ID for the newly created "Gym Apparel" category is listed:

curl --request GET \
     --url https://a.klaviyo.com/api/catalog-items/$custom:::$default:::3829918373-TShirt-1/relationships/categories \
     --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
     --header 'accept: application/vnd.api+json' \
     --header 'revision: 2025-01-15'
{
    "data": [
        {
            "type": "catalog-category",
            "id": "$custom:::$default:::SummerApparel"
        },
        {
            "type": "catalog-category",
            "id": "$custom:::$default:::GymApparel12345"
        }
    ],
    "links": {
        "self": "https://a.klaviyo.com/api/catalog-items/$custom:::$default:::3829918373-TShirt-1/relationships/categories",
        "next": null,
        "prev": null
    }
}

Catalog resource IDs

As you may have noticed in the examples above, the ID generated for each catalog resource is a compound ID (string) with the following format:

{integration type}:::{catalog type}:::{external_id}

Currently, the only supported integration type is $custom, and the only supported catalog type is $default. An ID for a catalog resource should look something like this:

{$custom}:::{$default}:::{external_id}

Catalog external IDs

Since the resource ID generated uses the external ID you provide for your catalog resources, adhere to the following rules for special characters:

  • An external ID must not contain / since it alters the request URL.
  • For categories, the external ID must not contain any of the following special characters: !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~

Bulk create and manage catalog resources

The Catalogs API includes endpoints that support bulk operations (Create, Update, and Delete) for catalog resources (e.g. Bulk Create Catalog Variants). Each operation returns an ID for the respective bulk job in the response. (up to 100 resources per request).

Here is an example request payload and response for Bulk Create Catalog Items:

{
   "data": {
       "type": "catalog-item-bulk-create-job",
       "attributes": {
           "items": {
               "data": [
                   {
                       "type": "catalog-item",
                       "attributes": {
                           "external_id": "1238479-TShirt-2",
                           "title": "T-Shirt",
                           "description": "This is a description of the t-shirt.",
                           "url": "https://via.placeholder.com/300"
                       },
                       "relationships": {
                           "categories": {
                               "data": [
                                   {
                                       "type": "catalog-category",
                                       "id": "$custom:::$default:::328402843203SummerWear1"
                                   }
                               ]
                           }
                       }
                   },
                   {
                       "type": "catalog-item",
                       "attributes": {
                           "external_id": "1238478-Baseball-Hat-1",
                           "title": "Baseball Cap",
                           "description": "This is a description of the baseball cap.",
                           "url": "https://via.placeholder.com/534"
                       },
                       "relationships": {
                           "categories": {
                               "data": [
                                   {
                                       "type": "catalog-category",
                                       "id": "$custom:::$default:::328402843203SummerWear1"
                                   }
                               ]
                           }
                       }
                   }
               ]
           }
       }
   }
}
{
   "data": {
       "type": "catalog-item-bulk-create-job",
       "id": "01JHGRSSRCD16H6739GQKPPK4F",
       "attributes": {
           "status": "processing",
           "created_at": "2025-01-13T21:23:31.725186+00:00",
           "total_count": 2,
           "completed_count": 0,
           "failed_count": 0,
           "completed_at": null,
           "errors": [],
           "expires_at": "2025-01-20T21:23:31.725186+00:00"
       },
       "links": {
           "self": "https://a.klaviyo.com/api/catalog-item-bulk-create-jobs/01JHGRSSRCD16H6739GQKPPK4F/"
       }
   },
   "links": {
       "self": "https://a.klaviyo.com/api/catalog-item-bulk-create-jobs"
   }
}

Note that a bulk create catalog item job is returned in the response. Use its ID to fetch job status, which will be needed to check if there are any errors creating any catalog items.

Fetch bulk job status

The example call to Get Bulk Create Catalog Items Job uses the ID returned in the previous example to check on the bulk create catalog item job:

curl --request GET \
     --url https://a.klaviyo.com/api/catalog-item-bulk-create-jobs/01JHGRSSRCD16H6739GQKPPK4F \
     --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
     --header 'accept: application/vnd.api+json' \
     --header 'revision: 2025-01-15'
{
    "data": {
        "type": "catalog-item-bulk-create-job",
        "id": "01JHGRSSRCD16H6739GQKPPK4F",
        "attributes": {
            "status": "complete",
            "created_at": "2025-01-13T21:23:31.725186+00:00",
            "total_count": 2,
            "completed_count": 2,
            "failed_count": 0,
            "completed_at": "2025-01-13T21:23:42.293912+00:00",
            "errors": [],
            "expires_at": "2025-01-20T21:23:31.725186+00:00"
        },
        "relationships": {
            "items": {
                "data": [
                    {
                        "type": "catalog-item",
                        "id": "$custom:::$default:::1238479-TShirt-2"
                    },
                    {
                        "type": "catalog-item",
                        "id": "$custom:::$default:::1238478-Baseball-Hat-1"
                    }
                ]
            }
        },
        "links": {
            "self": "https://a.klaviyo.com/api/catalog-item-bulk-create-jobs/01JHGRSSRCD16H6739GQKPPK4F/"
        }
    },
    "links": {
        "self": "https://a.klaviyo.com/api/catalog-item-bulk-create-jobs/01JHGRSSRCD16H6739GQKPPK4F"
    }
}

We can see that the status of the fetched job is complete with a failed_count of 0, so the job was completed successfully.

To check on multiple bulk create jobs, use the Get Bulk [Operation] Catalog [Resource]s Jobs endpoint (e.g., Get Bulk Create Catalog Items Jobs). You can filter jobs by status, e.g., ?filter=equals(status,complete). A job can have a status of queued, processing, complete, or cancelled.

🚧

Errors in bulk operations will only be reported in the response of the endpoints for fetching bulk jobs. See the Bulk job errors section below for more information.

Bulk job errors

If a bulk job contains errors, each resource that failed to be created, updated, or deleted is detailed within the errors array. Details include the erroring field(s) of each failed resource (meta), a detail describing the error, and the source.

The example call to Get Bulk Create Catalog Items Job below indicates that the requested job contains errors due to existing external IDs:

curl --request GET \
     --url https://a.klaviyo.com/api/catalog-item-bulk-create-jobs/01JHNA53KHWBVBKEHV2YE0TRWG \
     --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
     --header 'accept: application/vnd.api+json' \
     --header 'revision: 2025-01-15'
{
   "data": {
       "type": "catalog-item-bulk-create-job",
       "id": "01JHNA53KHWBVBKEHV2YE0TRWG",
       "attributes": {
           "status": "complete",
           "created_at": "2025-01-15T15:43:45.778058+00:00",
           "total_count": 2,
           "completed_count": 0,
           "failed_count": 2,
           "completed_at": "2025-01-15T15:44:00.597687+00:00",
           "errors": [
               {
                   "meta": {
                       "external_id": "1238479-item"
                   },
                   "detail": "An item with the external id `1238479-item` already exists.",
                   "source": {
                       "pointer": "/data/attributes/items/data/attributes/external_id"
                   }
               },
               {
                   "meta": {
                       "external_id": "1238478-item"
                   },
                   "detail": "An item with the external id `1238478-item` already exists.",
                   "source": {
                       "pointer": "/data/attributes/items/data/attributes/external_id"
                   }
               }
           ],
           "expires_at": "2025-01-22T15:43:45.778058+00:00"
       },
       "links": {
           "self": "https://a.klaviyo.com/api/catalog-item-bulk-create-jobs/01JHNA53KHWBVBKEHV2YE0TRWG/"
       }
   },
   "links": {
       "self": "https://a.klaviyo.com/api/catalog-item-bulk-create-jobs/01JHNA53KHWBVBKEHV2YE0TRWG"
   }
}

If a job contains errors, the erroring items will not be created. To handle errors:

  • Retrieve erroring items from the error list. Common errors include:
    • Duplicates caused by existing external IDs.
    • Invalid or missing details, such as category information.
  • Retrieve the data for those items (e.g., re-read from the source database or CSV).
  • Correct the data as needed by:
    • Updating incorrect or incomplete data.
    • Managing duplicates through merging or assigning unique identifiers.
    • Applying error-specific fixes in the source to prevent recurrence.
  • Resend the previously failed items and monitor the new bulk job for successful completion.

Querying catalog resources

Querying catalog resources with the Catalogs API can help you achieve many use cases such as populating a list of catalog items that belong to a specific category.id. Check out the supported query parameters below and test them out with our latest Postman collection. Note that support for given operators and fields is endpoint-specific. Review the API reference documentation for more information on allowed fields and query operators.

ParameterDescriptionQuery example
filterRetrieve a subset of catalog resources, e.g., catalog items for a specific category.id. Learn about the filter query parameter.GET /api/catalog-items?filter=equals(category.id,"$custom:::$default:::328402843203SummerApparel")
sortSort catalog items, e.g., by date created in ascending order (oldest to newest). Learn about the sort query parameter.GET /api/profiles?sort=-created
fieldsRequest for only specified catalog data, e.g., product URL. You can also request for only specified related resource data. Learn more about sparse fieldsets.GET /api/catalog-items?fields[catalog-item]=description,url

GET /api/catalog-items?include=variants&fields[catalog-variant]=title
includeInclude related resources in the response, e.g., variants for a catalog item. Learn about the include query parameter.GET /api/catalog-items?include=variants

Additional resources