HomeGuidesAPI Reference
ChangelogHelp CenterCommunityContact Us
Guides

Integrate a subscription ecommerce platform

Learn how to integrate a subscription ecommerce platform with Klaviyo.

If you’ve built your own custom cart solution with subscription options, or the data you would like to track is not currently supported by one of Klaviyo’s pre-built integrations or partner integrations, you can integrate with Klaviyo using our APIs.

Key integration components

The key components of integrating a subscription ecommerce platform are:

  • Customer data
    Tracking information such as name, email, phone number, or other profile attributes.
  • Email subscribers
    Tracking who is subscribed to your newsletter, for example.
  • Website activity
    Tracking who is active on your site, what products they view, etc.
  • Order activity
    Tracking when a customer places an order, what products are ordered, etc.
  • Subscription orders
    Tracking who has a subscription and the details of that subscription.

Creating events via API

This guide focuses on how to sync important metrics, or key customer activities, to Klaviyo. We recommend using the setup in the following checklist.

  • Use our JavaScript API for the following metrics:

    • Active on Site
      When someone visits your website.
    • Viewed Product
      When someone views a product.
    • Added to Cart
      When someone adds an item to their cart.
    • Started Checkout
      When someone lands on the checkout page.
  • Use our server-side Events API for the following metrics:

    • Placed Order
      When an order successfully processes in your system, including recurring subscription orders.
    • Placed Non-Recurring Order
      When a one-time purchase is made or when a new subscription is started, for event filtering/performance reporting purposes.
    • Ordered Product
      An event for each item in a processed order.
    • Started Subscription
      When a customer starts a new subscription.
    • Updated Subscription
      When a customer updates their subscription details.
    • Canceled Subscription
      When a customer cancels their subscription.
    • Fulfilled Order
      When an order is sent to the customer.
    • Canceled Order
      When an order is canceled.
    • Refunded Order
      When an order is refunded. 
  • Use our Client API to create and update the following profile properties:

    • Active Subscriber
      Boolean (true/false) value for whether or not someone has any active subscriptions.
    • Active Subscriptions
      List of names of a customer’s active subscriptions.
    • Active Subscription IDs
      List of IDs of a customer’s active subscriptions.
    • Next Replenishment Date
      Date on which the subscriber's subscription will next renew.
    • Subscription Frequency
      Numeric interval of time between subscription fulfillments.
  • Use either our Catalogs API or our custom catalog feed feature to sync your catalog.

Filtering and segmenting on these events and profile properties is based on the level of detail in the event data sent to Klaviyo. For example, if you want to filter customers based on those who ordered products in a specific category, you’ll want to include item categories for your Ordered Product events. If the event is lacking the Category property, you won’t be able to filter users by it. To understand how data must be structured so that key event details are available for segmentation, check out our articles on segment conditions and how to structure your data for segment and flow filters.

🚧

The code snippets in this guide use example data. You will need to update the values of the JSON properties in these snippets so that they dynamically pull the relevant information needed for that property.

Check out our custom integration FAQ for any questions about custom integrations.

JavaScript API for onsite metrics

Active on Site tracking snippet

To publish forms directly from Klaviyo to your site, add the following JavaScript snippet so it appears on every page on your website (the end of the footer is often a good place to add it). Make sure to replace PUBLIC_API_KEY with your Klaviyo account's six character public API key:

<script type="text/javascript" async
src="https://static.klaviyo.com/onsite/js/PUBLIC_API_KEY/klaviyo.js"></script>

Once you’ve added the snippet above, an Active on Site metric will trigger for any person who is cookied. A browser can be cookied in any of the ways listed in our article on Klaviyo onsite tracking.

Initialize the klaviyo object

Ensure that you have initialized the klaviyo object on your page before executing any of the following code snippets.

Viewed Product tracking snippet

If you'd like to set up a browse abandonment flow or build segments based on product browsing activity, you'll need to add JavaScript event tracking for the Viewed Product metric. All Viewed Product metrics are tied to user profiles. Add the following snippet to your product page template or associated JavaScript:

📘

Make sure to replace item.___ in the below code snippet with whatever item object your platform uses for product properties.

<script type="text/javascript">
   var item = {
     "ProductName": item.ProductName,
     "ProductID": item.ProductID,
     "SKU": item.SKU,
     "Categories": item.Categories,
     "ImageURL": item.ImageURL,
     "URL": item.URL,
     "Brand": item.Brand,
     "Price": item.Price,
     "CompareAtPrice": item.CompareAtPrice
   };
   klaviyo.push(["track", "Viewed Product", item]);
</script>

Make sure to update the values of the JSON properties in the snippet so that they dynamically pull from the relevant information needed for that property.

Additionally, there is another snippet that allows entries to be added to a “Recently Viewed Items” table for a profile. Calling the Klaviyo object's trackViewedItem function below will populate a product feed of recently viewed products that can be included in emails. For more information on how to use the “Recently Viewed Items” feature in a template, check out our article on inserting recently viewed items into an email.

The following snippet can be added directly below the Viewed Product snippet:

<script type="text/javascript">
   klaviyo.push(["trackViewedItem", {
     "Title": item.ProductName,
     "ItemId": item.ProductID,
     "Categories": item.Categories,
     "ImageUrl": item.ImageURL,
     "Url": item.URL,
     "Metadata": {
       "Brand": item.Brand,
       "Price": item.Price,
       "CompareAtPrice": item.CompareAtPrice
     }
   }]);
</script>

Added to Cart tracking snippet

If you’d like to send abandoned cart emails to visitors who add items to their cart, but don’t make it to the checkout page, you’ll need to track an Added to Cart metric. A customer must be identified, (i.e., cookied), to track this event. For the payload, you should include all of the cart information (like Started Checkout below) and information about the item that was just added (like Viewed Product above).

You can add as many key/value pairs as you’d like to the JSON payload, with one restriction: you can only use top-level properties in the JSON when adding filters to segments based on this event (Added to Cart in this case). That is why there is a top-level property AddedItemCategories in the below example that is the union of unique ProductCategories values of each of the products in the Items array. With this top-level property, you can create a segment of profiles who have viewed products in specific categories.

Here's an example Track request where the cart already contained one item (Winnie the Pooh) and another item was just added to the cart (A Tale of Two Cities):

<script type="text/javascript">
   klaviyo.push(["track", "Added to Cart", {
     "$value": 29.98,
     "AddedItemProductName": "A Tale of Two Cities",
     "AddedItemProductID": "1112",
     "AddedItemSKU": "TALEOFTWO",
     "AddedItemCategories": ["Fiction", "Classics", "Children"],
     "AddedItemImageURL": "http://www.example.com/path/to/product/image2.png",
     "AddedItemURL": "http://www.example.com/path/to/product2",
     "AddedItemPrice": 19.99,
     "AddedItemQuantity": 1,
     "ItemNames": ["Winnie the Pooh", "A Tale of Two Cities"],
     "CheckoutURL": "http://www.example.com/path/to/checkout",
     "Items": [{
         "ProductID": "1111",
         "SKU": "WINNIEPOOH",
         "ProductName": "Winnie the Pooh",
         "Quantity": 1,
         "ItemPrice": 9.99,
         "RowTotal": 9.99,
         "ProductURL": "http://www.example.com/path/to/product",
         "ImageURL": "http://www.example.com/path/to/product/image.png",
         "ProductCategories": ["Fiction", "Children"]
       },
       {
         "ProductID": "1112",
         "SKU": "TALEOFTWO",
         "ProductName": "A Tale of Two Cities",
         "Quantity": 1,
         "ItemPrice": 19.99,
         "RowTotal": 19.99,
         "ProductURL": "http://www.example.com/path/to/product2",
         "ImageURL": "http://www.example.com/path/to/product/image2.png",
         "ProductCategories": ["Fiction", "Classics"]
       }
     ]
   }]);
 </script>

Started Checkout

Checkout data is important if you'd like to send abandoned cart emails once a person makes it to the checkout page. Abandoned cart emails based on Started Checkout, as opposed to Added to Cart, will target shoppers who are potentially more serious about completing their purchase. When someone starts the checkout process, you'll send Klaviyo a metric indicating they’ve started checking out. The best place to trigger this event is either:

  • When someone visits the checkout page after they’ve been identified.
  • When they enter their email address on the checkout page if they have not already been identified.

Include all line item details so your abandoned checkout emails can be customized to include pictures, links, and other information about the products in someone’s cart. Here’s an example call to track a the Started Checkout event:

<script type="text/javascript">
   klaviyo.push(["track", "Started Checkout", {
     "$event_id": "1000123_1387299423",
     "$value": 29.98,
     "ItemNames": ["Winnie the Pooh", "A Tale of Two Cities"],
     "CheckoutURL": "http://www.example.com/path/to/checkout",
     "Categories": ["Fiction", "Children", "Classics"],
     "Items": [{
         "ProductID": "1111",
         "SKU": "WINNIEPOOH",
         "ProductName": "Winnie the Pooh",
         "Quantity": 1,
         "ItemPrice": 9.99,
         "RowTotal": 9.99,
         "ProductURL": "http://www.example.com/path/to/product",
         "ImageURL": "http://www.example.com/path/to/product/image.png",
         "ProductCategories": ["Fiction", "Children"]
       },
       {
         "ProductID": "1112",
         "SKU": "TALEOFTWO",
         "ProductName": "A Tale of Two Cities",
         "Quantity": 1,
         "ItemPrice": 19.99,
         "RowTotal": 19.99,
         "ProductURL": "http://www.example.com/path/to/product2",
         "ImageURL": "http://www.example.com/path/to/product/image2.png",
         "ProductCategories": ["Fiction", "Classics"]
       }
     ]
   }]);
 </script>

The $event_id should be a unique identifier for the cart combined with the UNIX formatted time when the event was triggered. This allows someone to trigger Started Checkout more than once when they return after adding additional items.

Server-side metrics

We recommend tracking certain metrics on the server side due to potential limitations of frontend code, security concerns, and general availability of data on the server side versus the frontend. For example, if someone has a slow connection or a JavaScript-blocking plugin on their browser, the JavaScript requests might not fire. In the case of more crucial metrics (e.g., transactional events and properties) or ones that may contain sensitive data, use our Client API.

Klaviyo has libraries in several server-side languages. Generally, the API requires making an HTTP GET request with a base64 encoded JSON payload. For general information about our server-side Events API, check out our Events API overview.

Key things to be aware of when tracking server-side events:

  • Make sure to replace PUBLIC_API_KEY with your public API key
  • The unqiue_id should be a unique identifier for the order (e.g., Order ID)
  • If the same combination of event and unique_id are sent more than once, we will skip all tracked events after the first with the same combination
  • value is a special property that allows Klaviyo to track revenue; this should be the total numeric (not a string), monetary value of the event it’s associated with, in your Klaviyo account’s currency
  • The "Items" array should contain one JSON block/dictionary for each line item.
  • time is a special property that should be a UNIX timestamp of the order date and time

Syncing historical data

Along with your ongoing data, it is best practice to send your historical order data, which will enhance your ability to segment off past data and improve historical accuracy in revenue tracking and predictive analytics. Historical data can be sent to Klaviyo by iterating through your historical orders and generating Placed Order, Placed Non-Recurring Order and Ordered Product Track API requests for each event as needed. The special “time” property for these events should be the UNIX timestamp of when that order occurred. 

Placed Order and Placed Non-Recurring Order

After an order is placed, make a Create Event request to our Events API. In order to effectively take advantage of our reporting and data analytics, this metric should be split into two separate, but overlapping metrics based on the type of order. Whenever any order is processed by your system, a Placed Order event should be tracked. This metric will be used for customer lifetime value (CLV) calculations and predictive analytics in order to get an accurate scope of a customer’s lifetime value and their predicted next order date. This metric will represent:

  • All one-time orders
  • All newly started subscriptions
  • All renewal or recurring orders for pre-existing subscriptions.

Whenever non-renewal/recurring orders are processed in your system, track a Placed Non-Recurring Order event. This event should be used for more accurate email performance reporting so you can see who is placing one-time purchases and starting new subscriptions based on your emails. This metric will represent:

  • All one-time orders
  • All newly-started subscriptions

For ongoing data, you can send order data to Klaviyo in one of two ways: real-time or batch.

  • Real-time
    Make requests as soon as an order is placed
  • Batch
    Write some code that will run (for example) at least every 30 minutes (e.g., on a cron) to send all order events that occurred in that past 30 minutes

If you plan to send abandoned cart messages, you'll need to send order data at a frequency that falls within your flow time delay (at least) in order to stop the flow email from sending to people who have completed their order. For example, if you have a one hour time delay between when someone triggers the abandoned cart flow and when they receive the first email, make sure that you send data at least once every hour to fall within that window and filter those who complete their order out of the flow before the email sends.

For Placed Order and Placed Non-Recurring Order events, include the following:

  • A value property that represents the total value of an entire order including shipping, tax, discounts, etc.
  • An Order Type property that represents the type of order this event represents. This property can be used for filtering types of orders people are placing and grouping revenue by certain purchase types. Some examples are:
    • One-time Purchase (for one-time orders)
    • New Subscription (for newly started subscriptions)
    • Recurring Subscription Payment (for renewal or recurring orders for pre-existing subscriptions)

Placed Order

Here’s an example Create Event request payload for Placed Order. The same payload should be used for Placed Non-Recurring Order. The only difference for a Placed Non-Recurring Order event is that "OrderType" should be set to "One-time Purchase".

{
  "data": {
    "type": "event",
    "attributes": {
      "properties": {
        "OrderId": "1234",
        "OrderType":"Recurring Subscription Payment",
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ],
            "Brand": "Kids Books"
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ],
            "Brand": "Harcourt Classics"
          }
        ]
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Placed Order"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "first_name": "Sarah",
            "last_name": "Mason",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

📘

Creating an event requires at least one profile identifier. For example, the Placed Order event from the POST Create Event call above uses email as a profile identifier. Providing every identifier is unnecessary. You should limit your provided identifiers to known values.

Ordered Product

In addition to tracking a Placed Order and/or Placed Non-Recurring Order event for each customer’s order, we recommend making a Create Event request for an Ordered Product event for each line item in the order. This should include a value property that represents the total cost of an item in the order before any adjustments, as well as more SKU-level detailed information about the item.

This event is useful if you plan to create any filters or triggers based on product-specific information (as opposed to the order as a whole) that isn't "top-level" in the Placed Order event. This event is also used in conjunction with your catalog feed to enable personalized recommendations.

{
  "data": {
    "type": "event",
    "attributes": {
      "properties": {
        "OrderId": "1234",
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ],
            "Brand": "Kids Books"
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ],
            "Brand": "Harcourt Classics"
          }
        ]
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Ordered Product"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "phone_number": "+15005550006",
            "external_id": "63f64a2b-c6bf-40c7-b81f-bed08162edbe",
            "first_name": "Sarah",
            "last_name": "Mason",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

Started Subscription

When someone starts a new subscription, track a corresponding Started Subscription event. This event should contain all of the information about the new subscription and will allow you to send new subscriber thank you or welcome emails.

{
  "data": {
    "type": "event",
    "attributes": {
      "properties": {
        "OrderId": "1234",
        "OrderType":"Recurring Subscription Payment",
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ],
            "Brand": "Kids Books"
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ],
            "Brand": "Harcourt Classics"
          }
        ]
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Started Subscription"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "phone_number": "+15005550006",
            "external_id": "63f64a2b-c6bf-40c7-b81f-bed08162edbe",
            "first_name": "Sarah",
            "last_name": "Mason",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

Updated Subscription

If someone is able to update details of their subscription, track an Updated Subscription event. This event should contain all information about what was changed with the subscription. This will allow you to send a follow up, ask how the customer’s experience was, thank them for upgrades, or request feedback for downgrades.

{
  "data": {
    "type": "event",
    "attributes": {
      "properties": {
        "OrderId": "1234",
        "ItemNames": [
          "Winnie the Pooh",
          "A Tale of Two Cities",
          "Alice's Adventures in Wonderland"
        ],
        "OrderInterval Unit": "days",
        "OrderInterval Frequency": 30,
        "AddedItems": true,
        "RemovedItems": false,
        "ItemsAdded": [
          "Alice's Adventures in Wonderland"
        ],
        "ItemsRemoved": [],
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ],
            "Brand": "Kids Books"
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ],
            "Brand": "Harcourt Classics"
          },
          {
            "ProductID": "1113",
            "SKU": "ALICEINWONDERLAND",
            "ProductName": "Alice's Adventures in Wonderland",
            "Quantity": 1,
            "ItemPrice": 15.99,
            "RowTotal": 15.99,
            "ProductURL": "http://www.example.com/path/to/product3",
            "ImageURL": "http://www.example.com/path/to/product/image3.png",
            "Categories": [
              "Fiction",
              "Classics"
            ]
          }
        ]
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Updated Subscription"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "phone_number": "+15005550006",
            "external_id": "63f64a2b-c6bf-40c7-b81f-bed08162edbe",
            "first_name": "Sarah",
            "last_name": "Mason",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

Canceled Subscription

When someone cancels a subscription, track a canceled Subscription event. This event should contain all the information about the canceled subscription, including a cancellation reason. This will allow you to send a followup email suggesting alternatives to cancelling, such as downgrading, updating their subscription, etc.

{
  "data": {
    "type": "event",
    "attributes": {
       "properties": {
        "OrderId": "1234",
        "Categories": [
          "Fiction",
          "Classics",
          "Children"
        ],
        "ItemNames": [
          "Winnie the Pooh",
          "A Tale of Two Cities"
        ],
        "OrderIntervalUnit": "days",
        "OrderIntervalFrequency": 30,
        "CancellationReason": "No longer interested",
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ]
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ]
          },
          {
            "ProductID": "1113",
            "SKU": "ALICEINWONDERLAND",
            "ProductName": "Alice's Adventures in Wonderland",
            "Quantity": 1,
            "ItemPrice": 15.99,
            "RowTotal": 15.99,
            "ProductURL": "http://www.example.com/path/to/product3",
            "ImageURL": "http://www.example.com/path/to/product/image3.png",
            "Categories": [
              "Fiction",
              "Classics"
            ]
          }
        ]
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Canceled Subscription"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "phone_number": "+15005550006",
            "external_id": "63f64a2b-c6bf-40c7-b81f-bed08162edbe",
            "first_name": "Sarah",
            "last_name": "Mason",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

Fulfilled Order

If you are able to track Fulfilled Orders, send an event which includes the event details and time of fulfillment:

{
  "data": {
    "type": "event",
    "attributes": {
      "properties": {
        "OrderId": "1234",
        "Categories": [
          "Fiction",
          "Classics",
          "Children"
        ],
        "ItemNames": [
          "Winnie the Pooh",
          "A Tale of Two Cities"
        ],
        "Brands": [
          "Kids Books",
          "Harcourt Classics"
        ],
        "DiscountCode": "Free Shipping",
        "DiscountValue": 5,
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ],
            "Brand": "Kids Books"
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ],
            "Brand": "Harcourt Classics"
          }
        ],
        "BillingAddress": {
          "FirstName": "John",
          "LastName": "Smith",
          "Company": "",
          "Address1": "123 abc street",
          "Address2": "apt 1",
          "City": "Boston",
          "Region": "Massachusetts",
          "RegionCode": "MA",
          "Country": "United States",
          "CountryCode": "US",
          "Zip": "02110",
          "Phone": "5551234567"
        },
        "ShippingAddress": {
          "FirstName": "John",
          "LastName": "Smith",
          "Company": "",
          "Address1": "123 abc street",
          "Address2": "apt 1",
          "City": "Boston",
          "Region": "Massachusetts",
          "Region_code": "MA",
          "Country": "United States",
          "Country_code": "US",
          "Zip": "02110",
          "Phone": "5551234567"
        }
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Viewed Product"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "phone_number": "+15005550006",
            "external_id": "63f64a2b-c6bf-40c7-b81f-bed08162edbe",
            "first_name": "John",
            "last_name": "Smith",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

Canceled Order

If you process cancellations, track a Canceled Order event. The Canceled Order event will have almost the same payload as a Placed Order event. For Canceled Order to be included in CLV calculations, it must have a unique_id that corresponds to a previously tracked Placed Order event. For this event, update the event name, the timestamp, and add an additional property for the cancellation reason:

{
  "data": {
    "type": "event",
    "attributes": {
      "properties": {
        "OrderId": "1234",
        "Categories": [
          "Fiction",
          "Classics",
          "Children"
        ],
        "ItemNames": [
          "Winnie the Pooh",
          "A Tale of Two Cities"
        ],
        "Brands": [
          "Kids Books",
          "Harcourt Classics"
        ],
        "DiscountCode": "Free Shipping",
        "DiscountValue": 5,
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ],
            "Brand": "Kids Books"
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ],
            "Brand": "Harcourt Classics"
          }
        ],
        "BillingAddress": {
          "FirstName": "John",
          "LastName": "Smith",
          "Company": "",
          "Address1": "123 abc street",
          "Address2": "apt 1",
          "City": "Boston",
          "Region": "Massachusetts",
          "RegionCode": "MA",
          "Country": "United States",
          "CountryCode": "US",
          "Zip": "02110",
          "Phone": "5551234567"
        },
        "ShippingAddress": {
          "FirstName": "John",
          "LastName": "Smith",
          "Company": "",
          "Address1": "123 abc street",
          "Address2": "apt 1",
          "City": "Boston",
          "Region": "Massachusetts",
          "Region_code": "MA",
          "Country": "United States",
          "Country_code": "US",
          "Zip": "02110",
          "Phone": "5551234567"
        }
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Canceled Order"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "phone_number": "+15005550006",
            "external_id": "63f64a2b-c6bf-40c7-b81f-bed08162edbe",
            "first_name": "John",
            "last_name": "Smith",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

Refunded Order

If you process refunds, track a Refunded Order event. The Refunded Order event will have almost the same payload as a Placed Order event. For Refunded Order to be included in CLV calculations, it must have a unique_id that corresponds to a previously tracked Placed Non-Recurring Order event. For this event, update the event name, the timestamp, and add an additional property for the refund reason. You can also add an array of the refunded items if you process partial refunds or returns and wish to have that data in Klaviyo.

{
  "data": {
    "type": "event",
    "attributes": {
      "properties": {
        "OrderId": "1234",
        "Reason": "No longer needed",
        "Categories": [
          "Fiction",
          "Classics",
          "Children"
        ],
        "ItemNames": [
          "Winnie the Pooh",
          "A Tale of Two Cities"
        ],
        "Brands": [
          "Kids Books",
          "Harcourt Classics"
        ],
        "DiscountCode": "Free Shipping",
        "DiscountValue": 5,
        "Items": [
          {
            "ProductID": "1111",
            "SKU": "WINNIEPOOH",
            "ProductName": "Winnie the Pooh",
            "Quantity": 1,
            "ItemPrice": 9.99,
            "RowTotal": 9.99,
            "ProductURL": "http://www.example.com/path/to/product",
            "ImageURL": "http://www.example.com/path/to/product/image.png",
            "Categories": [
              "Fiction",
              "Children"
            ],
            "Brand": "Kids Books"
          },
          {
            "ProductID": "1112",
            "SKU": "TALEOFTWO",
            "ProductName": "A Tale of Two Cities",
            "Quantity": 1,
            "ItemPrice": 19.99,
            "RowTotal": 19.99,
            "ProductURL": "http://www.example.com/path/to/product2",
            "ImageURL": "http://www.example.com/path/to/product/image2.png",
            "Categories": [
              "Fiction",
              "Classics"
            ],
            "Brand": "Harcourt Classics"
          }
        ],
        "BillingAddress": {
          "FirstName": "John",
          "LastName": "Smith",
          "Company": "",
          "Address1": "123 abc street",
          "Address2": "apt 1",
          "City": "Boston",
          "Region": "Massachusetts",
          "RegionCode": "MA",
          "Country": "United States",
          "CountryCode": "US",
          "Zip": "02110",
          "Phone": "5551234567"
        },
        "ShippingAddress": {
          "FirstName": "John",
          "LastName": "Smith",
          "Company": "",
          "Address1": "123 abc street",
          "Address2": "apt 1",
          "City": "Boston",
          "Region": "Massachusetts",
          "Region_code": "MA",
          "Country": "United States",
          "Country_code": "US",
          "Zip": "02110",
          "Phone": "5551234567"
        }
      },
      "time": "2022-11-08T00:00:00",
      "value": 9.99,
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Refunded Order"
          }
        }
      },
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "[email protected]",
            "phone_number": "+15005550006",
            "external_id": "63f64a2b-c6bf-40c7-b81f-bed08162edbe",
            "first_name": "John",
            "last_name": "Smith",
            "organization": "Klaviyo",
            "title": "Engineer",
            "image": "https://images.pexels.com/photos/3760854/pexels-photo-3760854.jpeg",
            "location": {
              "address1": "89 E 42nd St",
              "address2": "1st floor",
              "city": "New York",
              "country": "United States",
              "region": "NY",
              "zip": "10017",
              "timezone": "America/New_York"
            }
          }
        }
      }
    }
  }
}

Server-side profile properties

We recommend tracking certain profile properties on the server-side due to the same limitations outlined in the case of the metrics above. Tracking the following profile properties can help you segment subscribers and send targeted messaging.

Active Subscriber

Send this profile property as a boolean (true/false) value representing whether or not someone is a current subscriber.

This profile property will allow you to:

  • Create segments and target campaigns or forms to either subscribers or non-subscribers (e.g., exclusive offers to current subscribers but not past subscribers or non-subscribers).
  • Create branching flows or conditional logic to send different message content based on whether or not someone currently subscribes (e.g., a “Why not try subscribing?” block in an email to non-subscribers).

Here is an example Profiles API request payload for Active Subscriber:

{
     "data": {
          "type": "profile",
          "attributes": {
               "properties": {
                    "ActiveSubscriber": true  
               }
          },
          "meta": {
               "identifiers": {
                    "email": "[email protected]"
               }
          }
     }
}

Active Subscriptions

Send this profile property as an array containing the names of all active subscriptions (or actively subscribed products) for that profile. This should reflect your own system’s record of a subscriber’s active subscription(s).

This property will allow you to:

  • Create segments and target campaigns or forms to only those who subscribe to certain items or subscriptions (e.g., new meat option alert to meat box subscribers but not vegetable box subscribers).
  • Create branching flows or conditional logic to send different message content based on whether or not someone subscribes to particular items (e.g., “Best Sellers” email targeted to book subscribers instead of magazine subscribers).

Here is an example Create or Update Client Profile request payload for Active Subscriptions:

{
     "data": {
          "type": "profile",
          "attributes": {
               "properties": {
                    "ActiveSubscriptions": ["Vegetable Box","Snack Box","Magazines"]      
               }
          },
          "meta": {
               "identifiers": {
                    "email": "[email protected]"
               }
          }
     }
}

With Create or Update Client Profile, you can also use meta.patch_properties to add a new active subscription to your array.

Active Subscription IDs

Send this profile property as an array containing the IDs of all active subscriptions (or actively subscribed products) for a profile. This should reflect your own system’s record of the IDs of a subscriber’s active subscription(s).

This property will allow you to:

  • Pull information about these subscriptions from your catalog feed using our catalog lookup feature (e.g., names, images, descriptions, links).

Here is an example Client API request payload for Active Subscription IDs:

{
     "data": {
          "type": "profile",
          "attributes": {
               "properties": {
                    "ActiveSubscriptionIDs": ["abc123","def456","ghi789"]
               }
          },
          "meta": {
               "identifiers": {
                    "email": "[email protected]"
               }
          }
     }
}

Next Replenishment Date

Send this profile property as a date representing the next date on which the subscriber's subscription will renew. 

This property will allow you to create date-triggered flows to send messaging before or after the next replenishment date.

Here is an example Client API request payload for Active Subscription IDs:

{
     "data": {
          "type": "profile",
          "attributes": {
               "properties": {
                    "NextReplenishmentDate": "2019-10-31 00:00:00"
               }
          },
          "meta": {
               "identifiers": {
                    "email": "[email protected]"
               }
          }
     }
}

Subscription Frequency

Send this profile property as a number representing the amount of days (or other unit of measurement) between a subscriber's subscription renewals. 

This property will allow you to create segments based on renewal/shipment frequency in order to engage differently with subscribers that prefer different fulfillment cadences.

Here is an example server-side request payload for Subscription Frequency:

{
     "data": {
          "type": "profile",
          "attributes": {
               "properties": {
                    "SubscriptionFrequency": 30
               }
          },
          "meta": {
               "identifiers": {
                    "email": "[email protected]"
               }
          }
     }
}

Catalog feed integration

Integrating your catalog will allow you to utilize product blocks in emails. To set up a custom catalog integration, please follow the process outlined in our article on syncing a custom catalog feed to Klaviyo

Additional resources