Custom Integration FAQ

read

Overview

If you’re building a custom integration to Klaviyo using our JavaScript and server-side APIs, here are some common questions and answers to keep in mind.

How should I name my metrics?

We recommend using action words for metric names. An event of a particular metric is triggered when someone takes an action so the name should reflect the kind of action that was taken to trigger that event. Examples of events in our standard action-word-first naming scheme include Viewed Product, Started Checkout, and Placed Order.

Why do your code examples have so many curly brackets {{ }}?

Many templating languages have a markup that uses curly brackets ({{ }}) to retrieve server-side information when the page loads. The actual language/words we use as well as the curly bracket notation itself may need to be altered for your platform. The important part is that values for each property are dynamically rendered based on the information needed for that property.

My customers can create accounts. How do I cookie them?

If visitors or customers can create accounts for your website, add the following snippet such that it appears on snippet:

<script>
   var _learnq = _learnq || [];
   {% if user.is_logged_in %}
   _learnq.push(['identify', {'$email': '{{ user.email }}'}]);
   {% endif %}
 </script>

Depending on the types of templates you use for your website, the {% if user.is_logged_in %} and {{ user.email }} syntax may be different. Using the template language available, you want to check if the person viewing the current page is logged in then, if so, output their email address.

You can also send other properties about the logged in user with this Identify request, including $first_name and $last_name if those are available through your templating language or data layer.

How should I structure my data for segmentation and flow filtering?

If you are building your own custom integration, and are deciding what data to send to Klaviyo and how to structure this data, make sure that all properties you want to segment on are sent as top-level properties and are not nested.

For example, if you create a Placed Order metric where an event will track whenever someone completes a purchase on your site, you may want to filter events based on what item(s) someone purchased.

In order to do this, there has to be a top-level ItemNames array that includes all purchased product names -- this would be in addition to a nested array with details for each item. The nested data becomes helpful when iterating over the items in the order and displaying multiple properties about each item, one at a time (eg. ProductName, ItemPrice, and Quantity). Below, you can see the ItemNames array in the payload for this Placed Order event in addition to the Items array that contains detailed information about each product:

{
   "token": "API_KEY",
   "event": "Placed Order",
   "customer_properties": {
     "$email": "john.smith@test.com",
     "$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,
     "Categories": ["Fiction", "Classics", "Children"],
     "ItemNames": ["Winnie the Pooh", "A Tale of Two Cities"],
     "Brands": ["Kids Books", "Harcourt Classics"],
     "Discount Code": "Free Shipping",
     "Discount Value": 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"
       }
     ]
   },
   "time": 1387302423
 }

How come some values aren't appearing in my segment and flow filters?

Our filters will populate with any event property values or profile property values that have previously been sent to us. Until we receive an event or profile property with that data, it will not appear in the drop-down for filtering.

If an event property shares a name with a profile property, only the profile property will appear in the filter. Make sure to choose different names for your event properties and profile properties.

Should I use $email or $id as my unique identifier?

Before you begin building a custom integration, note that the Identify method -- which allows you to identify and set properties on an individual -- allows you to identify any individual by including either their email address, with the $email key, or a unique identifier such as their user ID, with the $id key.

We highly recommend that you consistently identify all individuals using their email address only (with the $email key), and do not pass any $id value.

If you choose to use your own unique identifier with the $id key, you take on the full responsibility of identity management within your Klaviyo account. You must ensure that all requests are made mapping the right $id value you're setting to the right $email. If you send some requests with $id only, these profiles will exist "anonymously" without any associated $email. If requests then come in for the same person, but only $email is part of the request, a permanent duplicate profile will get created. Given the complexity of ensuring $id and $email are mapped correctly with every request across all data sources, we recommend exclusively using email address to identify individuals. This will fully safeguard against duplicate profile creation.

How do I tell if my custom integration is working?

The first thing to check is whether or not Klaviyo is receiving events correctly. To do this, you can log into your Klaviyo account and click on the Metrics tab. This tab will show all the different events (or metrics) syncing into your Klaviyo account. You should see the following metrics here: Placed Order, Ordered Product, and Started Checkout. You may also see a metric for Active on Site. If you do, that means we've received at least one event for each of those metrics.

Next, for each metric, click on the Activity Feed to view a list of the most recent events we've received. If you don't see the metrics you're expecting in Klaviyo, here are a few things to consider:

  • The Placed Order and Started Checkout metrics won't show up until someone has placed an order or checked out, respectively.
  • You should create a test checkout and a test order to see data appear.
  • Check that the public API key you're making API requests with matches the API key in your account.
  • Make sure you haven't forgotten to replace the placeholder API key.
  • For JavaScript Track requests, make sure people are being identified before you make the Track request.
  • Klaviyo doesn't Track anonymous activity because you can't take action or send emails to people who haven't been identified.

How do I backfill historical data?

Has your store or website existed before your integration with Klaviyo? We have good news:

Backfilling Via our APIs

If you have historical data on your customers, you can send that to Klaviyo using our Track and Identify APIs. If you’ve already built an integration to Klaviyo for real-time data, the process here is very similar. In order to send historical information, iterate through every historical “event” you have and send a Track request for that event. If you have historical properties about people (their email preferences, birthdays, etc) you can send that using our Identify API.

Backfilling Via CSV Uploads

Each of these can be sent via CSV uploads as well, here are a few considerations.

Can I use a tag manager to integrate?

Yes. Any of our Track or Identify requests can be sent via JavaScript (and thus injected via a tag manager) but there are a few things necessary to keep in mind:

  • Our requests may not have time or be able to trigger for people who have slow computers, or ad or JavaScript blockers installed on their browsers.
  • Information stored in a frontend data layer or in the JavaScript of a website may be visible to the public internet. Be careful not to send or expose any sensitive information about your browsers or customers when integrating using only Javascript.

Should I use the server-side API or front-end API?

Our Track and Identify APIs have both server-side and front-end (JavaScript) components. Both server-side and front-end requests can be used to send the same data so theoretically an entire custom integration can be built using one or the other. That said, both have their advantages and disadvantages:

Frontend Code

  • Advantages:
    • Can be implemented on any platform that supports JavaScript
    • Does not require access to the back-end code of a platform and so can be used on hosted solutions (eg. Shopify and BigCommerce)
    • Usually more straight-forward to set up
  • Disadvantages:
    • Runs on the end-users computer
    • Can be interrupted by JavaScript blockers, slow internet connections, or slow computers
    • Exposed to the public internet

Server-Side Code

  • Advantages:
    • Runs on your own server
    • Highly reliable
    • Access to information only available on the server (eg. order status)
    • Supports more private requests
  • Disadvantages:
    • Requires access to the back-end of a platform or at least to its APIs

What is the difference between Abandoned Carts and Abandoned Checkouts?

In your Klaviyo account, you might find that we have default flows in the Flows tab or Flows Library called Abandoned Cart. One of them uses a trigger called Added to Cart, while the other uses a trigger called Started Checkout. Because the latter is triggered when someone lands on the checkout page, other platforms may refer to this as an “Abandoned Checkout” instead of an “Abandoned Cart." In Klaviyo, we call both flows Abandoned Cart and use different triggering events since both refer to a cart that was abandoned, just at different parts of the customer journey.

My payload looks valid but I'm receiving a "0" response?

Our Track and Identify APIs will respond with a "0" if the payload sent was invalid. Here are some reasons you may be getting an unexpected response or unexpected results:

  • There may be curly or fancy quote marks used in your payload instead of regular quote marks.
    • ' and " are valid quote marks
    • , , , and may be added by some text-editing softwares, but are not valid programming quote marks and will cause the JSON to be invalid if used outside of a string.
  • A server-side payload must contain a valid email address in it's "customer_properties" dictionary

I received a "1" response from the Track API but my event isn't appearing in Klaviyo?

Our Track and Identify APIs will respond with a "1" if the payload sent was valid. Here are some reasons you may be getting an unexpected response or unexpected results:

  • Every event tracked to your account must have a unique combination of event name and $event_id. If you track the same combination a second time, you will receive a "1" response but the event will not be ingested.
  • @example.com domain email addresses are technically valid but we do not accept them into our event or profile processing pipeline
x
Was this article helpful?
3 out of 3 found this helpful