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 JavaScript API, server-side API, and custom catalog integration

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

About JavaScript and server-side Track and Identify APIs

This guide focuses on how to sync important metrics, or key customer activities, to Klaviyo. While our JavaScript and server-side Track and Identify APIs can be used interchangeably, we recommend using the setup in the following checklist. For a deep dive on why this structure works best, head to our article Getting started with Track and Identify APIs.

  • Use our JavaScript Track 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 Track 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
    • Cancelled Subscription
      When a customer cancels their subscription
    • Fulfilled Order
      When an order is sent to the customer
    • Cancelled Order
      When an order is cancelled
    • Refunded Order
      When an order is refunded 
  • Use our server-side Identify API for 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 our custom catalog feed for the following:

    • Catalog feed:
      An XML feed or JSON feed of your product 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 Track 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="application/javascript" async
src="https://static.klaviyo.com/onsite/js/klaviyo.js?company_id=PUBLIC_API_KEY"></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.

Viewed Product tracking snippet

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. On your product page template, add the following snippet:

<script type="text/javascript">
   var _learnq = _learnq || [];
   var item = {
     "ProductName": "Winnie the Pooh",
     "ProductID": "1111",
     "Categories": ["Fiction", "Children"],
     "ImageURL": "http://www.example.com/path/to/product/image.png",
     "URL": "http://www.example.com/path/to/product",
     "Brand": "Kids Books",
     "Price": 9.99,
     "CompareAtPrice": 14.99
   };
   _learnq.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, if you want to add entries to a “Recently Viewed Items” list in a profile, add the following snippet directly below the Viewed Product snippet. 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.

<script type="text/javascript">
   _learnq.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

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). 

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">
   _learnq.push(['track', Added to Cart, {
     "$value": 29.98,
     "AddedItemProductName": "A Tale of Two Cities",
     "AddedItemProductID": "1112",
     "AddedItemSKU": "TALEOFTWO",
     "AddedItemCategories": ["Fiction", "Classics"],
     "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 Track request:

<script type="text/javascript">
   _learnq.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 server-side Track API. For more information on this question, check out our Custom integration FAQ

Klaviyo has libraries in several server-side languages. Generally, the API requires making an HTTP GET request with a base64 encoded JSON payload. More information can be found in our Track and Identify API reference.

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

  • Make sure to replace PUBLIC_API_KEY with your public API key
  • The $event_id should be a unique identifier for the order (e.g., Order ID)
  • If the same combination of event and $event_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 Track request to our server-side 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)

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

{
   "token": "PUBLIC_API_KEY",
   "event": "Placed Order",
   "customer_properties": {
     "$email": "[email protected]",
     "$first_name": "John",
     "$last_name": "Smith",
     "$phone_number": "5551234567",
     "$address1": "123 Abc st",
     "$address2": "Suite 1",
     "$city": "Boston",
     "$zip": "02110",
     "$region": "MA",
     "$country": "USA"
   },
   "properties": {
     "$event_id": "1234",
     "$value": 29.98,
     "OrderId": "1234",
     "OrderType": "Recurring Subscription Payment",
     "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": 1387302423
 }

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 Track request payload 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.

{
   "token": "PUBLIC_API_KEY",
   "event": "Ordered Product",
   "customer_properties": {
     "$email": "[email protected]",
     "$first_name": "John",
     "$last_name": "Smith"
   },
   "properties": {
     "$event_id": "1234_WINNIEPOOH",
     "$value": 9.99,
     "OrderId": "1234",
     "ProductID": "1111",
     "SKU": "WINNIEPOOH",
     "ProductName": "Winnie the Pooh",
     "Quantity": 1,
     "ProductURL": "http://www.example.com/path/to/product",
     "ImageURL": "http://www.example.com/path/to/product/image.png",
     "ProductCategories": [
       "Fiction",
       "Children"
     ],
     "ProductBrand": "Kids Books"
   },
   "time": 1387302423
 }

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.

{
   "token": "PUBLIC_API_KEY",
   "event": "Started Subscription",
   "customer_properties": {
     "$email": "[email protected]",
   },
   "properties": {
     "$event_id": "1234",
     "$value": 29.98,
     "OrderId": "1234",
     "Categories": ["Fiction", "Classics", "Children"],
     "ItemNames": ["Winnie the Pooh", "A Tale of Two Cities"],
     "DiscountCode": "Free Shipping",
     "DiscountValue": 5,
     "OrderIntervalUnit": "days",
     "OrderIntervalFrequency": 30,
     "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"]
       }
     ]
   },
   "time": 1387302423
 }

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.

{
   "token": "PUBLIC_API_KEY",
   "event": "Updated Subscription",
   "customer_properties": {
     "$email": "[email protected]",
   },
   "properties": {
     "$event_id": "1234",
     "$value": 45.97,
     "OrderId": "1234",
     "Categories": ["Fiction", "Classics", "Children"],
     "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"]
       },
       {
         "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": 1387302423
 }

Cancelled Subscription

When someone cancels a subscription, track a Cancelled Subscription event. This event should contain all the information about the cancelled 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.

{
   "token": "PUBLIC_API_KEY",
   "event": "Cancelled Subscription",
   "customer_properties": {
     "$email": "[email protected]",
   },
   "properties": {
     "$event_id": "1234",
     "$value": 45.97,
     "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": 1387302423
 }

Fulfilled Order

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

{
   "token": "PUBLIC_API_KEY",
   "event": "Fulfilled Order",
   "customer_properties": {
     "$email": "[email protected]",
     "$first_name": "John",
     "$last_name": "Smith",
     "$phone_number": "5551234567",
     "$address1": "123 Abc st",
     "$address2": "Suite 1",
     "$city": "Boston",
     "$zip": "02110",
     "$region": "MA",
     "$country": "USA"
   },
   "properties": {
     "$event_id": "1234",
     "$value": 29.98,
     "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": 1387312956
 }

Cancelled Order

If you process cancellations, track a Cancelled Order event. The Cancelled Order event will have almost the same payload as a Placed Order event. For Cancelled Order to be included in CLV calculations, it must have an $event_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:

{
   "token": "PUBLIC_API_KEY",
   "event": "Cancelled Order",
   "customer_properties": {
     "$email": "[email protected]",
     "$first_name": "John",
     "$last_name": "Smith",
     "$phone_number": "5551234567",
     "$address1": "123 Abc st",
     "$address2": "Suite 1",
     "$city": "Boston",
     "$zip": "02110",
     "$region": "MA",
     "$country": "USA"
   },
   "properties": {
     "$event_id": "1234",
     "$value": 29.98,
     "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": 1387312956
 }

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 an $event_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.

{
   "token": "PUBLIC_API_KEY",
   "event": "Refunded Order",
   "customer_properties": {
     "$email": "[email protected]",
     "$first_name": "John",
     "$last_name": "Smith",
     "$phone_number": "5551234567",
     "$address1": "123 Abc st",
     "$address2": "Suite 1",
     "$city": "Boston",
     "$zip": "02110",
     "$region": "MA",
     "$country": "USA"
   },
   "properties": {
     "$event_id": "1234",
     "$value": 29.98,
     "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": 1387312956
 }

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 server-side Identify API request payload for Active Subscriber:

{
   "token": "PUBLIC_API_KEY",
   "properties": {
     "$email": "[email protected]",
     "ActiveSubscriber": true
   }
 }

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). 

📘

There is no way to append or pop an array item via the API, so if a person adds or removes a new subscription, send a new array of all active subscriptions to Klaviyo.

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 server-side Identify API request payload for Active Subscriptions:

{
   "token": "PUBLIC_API_KEY",
   "properties": {
     "$email": "[email protected]",
     "ActiveSubscriptions": ["Vegetable Box","Snack Box","Magazines"]
   }
 }

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). If a person adds or removes a new subscription, send a new array of all active subscription IDs to Klaviyo. 

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 server-side Identify API request payload for Active Subscription IDs:

{
   "token": "PUBLIC_API_KEY",
   "properties": {
     "$email": "[email protected]",
     "ActiveSubscriptionIDs": ["abc123","def456","ghi789"]
   }
 }

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 server-side Identify API request payload for Next Replenishment Date:

{
   "token": "PUBLIC_API_KEY",
   "properties": {
     "$email": "[email protected]",
     "NextReplenishmentDate": "2019-10-31 00:00:00"
   }
 }

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 Identify API request payload for Subscription Frequency:

{
   "token": "PUBLIC_API_KEY",
   "properties": {
     "$email": "[email protected]",
     "SubscriptionFrequency": 30
   }
 }

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