Solution Recipe 9: Use Klaviyo Flow Webhooks to Automate Suppressions Using Segments and Klaviyo’s APIs

David
13min read
Developer recipes
June 6, 2022

Solution Recipes are tutorials to achieve specific objectives in Klaviyo. They can also help you master Klaviyo, learn new third-party technologies, and come up with creative ideas. They are written mainly for developers & technically-advanced users.

  • WHAT YOU’LL LEARN: How to use webhooks to automatically suppress certain Klaviyo profiles using a segment-triggered flow and Klaviyo’s APIs.
  • WHY IT MATTERS: Some organizations sync profiles into Klaviyo that do not have marketing consent, or are otherwise not contactable and should be suppressed. For example, merchants that sell on third-party marketplaces like eBay, Walmart, or Amazon may push order data into Klaviyo, but with obfuscated email addresses that should be excluded. By creating a segment with all qualifying profiles, this type of suppression can be automated.
  • LEVEL OF SOPHISTICATION: Moderate

Introduction

Klaviyo flows has a webhook flow action which allow you to send customizable and dynamic HTTP POST requests with a JSON payload to a destination of your choosing within a Klaviyo flow. The most commonly discussed use cases for webhook actions involve sending data to third-party APIs or also to Klaviyo’s own APIs.

In this example we will use a webhook action to send a request to Klaviyo’s own APIs, however you can also build your own API endpoint too.

Challenge

Acme Corp is a (fictional) omni-channel clothing retailer that sells direct to consumer through an online store and various online marketplaces. They have connected an ordering system to Klaviyo, meaning all their order events are successfully syncing into Klaviyo and a Klaviyo profile is being generated for every customer.

It’s working great, except for one thing: this merchant sells through various marketplaces like eBay, Walmart, and Amazon and all order records originating in these marketplaces contain email addresses that are deliberately obfuscated.

As eBay describes it:

In the majority of cases, we don’t share buyers’ personal email addresses. We replace email addresses with aliases for buyers and sellers to hide personal contact information. When you communicate, your email appears like 63ae59ac280fe0fa69@members.ebay.com and is sent through our secure platform.
Ebay

This can create some noisy profile data in the Klaviyo account — e.g. because an obfuscated email alias by design can’t be matched up with the customer’s true email. Additionally, these marketplaces have policies that restrict the types of communications that are permitted, meaning it may not be appropriate to communicate with these email aliases. So, Acme Corp wants to just suppress these profiles from their Klaviyo account.

There are a couple potential ways to achieve this:

  1. Acme Corp could alter the integration with their eCommerce backend to avoid syncing these orders into Klaviyo in the first place, but would miss out on important revenue reporting
  2. Acme Corp could upload suppressions into Klaviyo manually via CSV files, but that doesn’t scale

By using webhooks, Acme Corp can achieve a fully automated solution.

Ingredients

  • 1 Klaviyo segment defining profiles to suppress
  • 1 Klaviyo Flow containing a webhook action
  • 1 Klaviyo API endpoint

Instructions

Step 1: Create a segment in Klaviyo

The first step is to create a segment in Klaviyo containing profiles that we want to suppress. In this example, we’re going to include any profiles where the email address contains a text string that we only see from aliases originating from Amazon, Walmart, and eBay.

Defining a segment in Klaviyo

Step 2: Create a flow triggered on segment membership

Next, we’re going to create a flow in Klaviyo that is triggered on segment membership. This means that when someone first enters the segment, they will automatically enter the flow. Keep in mind that, by design, Profiles may only enter a segment-triggered flow once.

It is pretty easy to set up. Just click into Flows and then Create From Scratch. Then select the segment you just defined as the trigger.

A flow in Klaviyo triggered on segment membership

Step 3: Choose your Klaviyo API endpoint for suppression or deletion

You can choose to either Suppress a profile, or Delete a profile from your Klaviyo account.

Suppressing a profile means the profile can no longer receive messages except for transactional messages. The profile will remain in your Klaviyo account but will be marked as suppressed. Events will still be recorded on this profile, which can be useful to have as the profile may subscribe in the future.

How a profile appears when suppressed

Deleting a profile means the profile is completely removed from your Klaviyo account, along with any event history and cannot be restored.

Step 4: Setup the webhook with the relevant Klaviyo API endpoint

Suppressing a profile

Configure the webhook as below. You will need to enter your private key in the [YOUR-PRIVATE-API-KEY] section

URL: https://a.klaviyo.com/api/profile-suppression-bulk-create-jobs/
Header 1 = accept: application/json
Header 2 = content-type: application/json
Header 3 = revision: 2023-02-22
Header 4 = Authorization: Klaviyo-API-Key [your-private-api-key]

JSON BODY
{
  "data": {
    "type": "profile-suppression-bulk-create-job",
    "attributes": {
      "suppressions": [
        {
          "email": "{{person.email}}"
        }
      ]
    }
  }
}

It should look like this when you have configured it

The configured webhook to suppress a profile

Deleting a profile

Configure the webhook as below. You will need to enter your private key in the [YOUR-PRIVATE-API-KEY] section

URL: https://a.klaviyo.com/api/profile-suppression-bulk-create-jobs/
Header 1 = accept: application/json
Header 2 = content-type: application/json
Header 3 = revision: 2023-02-22
Header 4 = Authorization: Klaviyo-API-Key [your-private-api-key]
JSON BODY
{
  "data": {
    "type": "data-privacy-deletion-job",
    "attributes": {
      "email": "{{person.email}}"
    }
  }
}

It should look like this when you have configured it

The configured webhook to delete a profile

Step 4: Test and set the flow live

Once you have your webhook configured, you can preview and test the webhook works by clicking the “Preview Webhook” button

Verify an email address has populated from your segment and click “Send Test Request”

Make sure the placeholder text has rendered an email address

If everythings works then you will get a green success bar

Successfully sent webhook indicator

Verify the profile is now suppressed/deleted and then you can set your flow live!

Bonus: Building a custom API endpoint with Napkin

This step is not required, but shows you how a custom API endpoint can be built and used in Klaviyo. By building a custom API endpoint you can automate additional actions, for example updating your data warehouse or an external CRM tool.

Below, we’ll show you how to achieve this with a low-code solution built with a neat tool called Napkin.io, a tool Klaviyo acquired

Napkin helps manage serverless cloud functions. We’ll go more into how Napkin works, but the gist is it’s a web app that makes it really simple to code, test, and deploy a secure API endpoint. It’s also worth mentioning that if you prefer a no-code solution, you can achieve a similar outcome using Zapier webhooks or similar tools. Here we prefer the former approach even though it’s slightly more complicated because it illustrates the pattern of having Klaviyo webhooks send requests to a custom API which can be extended to handle other creative use cases and scenarios.

Build an API endpoint that accepts emails and suppresses them in Klaviyo

Below, we’ll add a webhook action to our Klaviyo flow which will send an HTTP POST request to a destination of our choosing. Since we have to point that webhook action at a custom API, we first need to code and deploy that API.

It’s possible to write and deploy APIs in lots of different ways. For example, all the major cloud providers like Amazon, Google, and Microsoft support this with things like API GatewaysLambda functionsCloud Functions, or Azure Functions. Here, because we like to explore new technology and because it’s so simple to use we’re going to showcase how to write and deploy an API with a tool called Napkin.io. As noted above, however, if you prefer to do this in a totally no-code way, you could use something like Zapier webhooks which would essentially require a so-called Zap that first catches a webhook (from Klaviyo) and then emits a webhook (back to Klaviyo), following the same logic in this example.

In this case, we’ve created an account in Napkin.io and we’ll start by selecting New Function.

Napkin.io administrative interface

Then we give it a name. We’ll call this “SUPPRESS-KLAVIYO-PROFILES”. We’ll write this in Python, so we select Python as the development environment.

Naming a cloud function in Napkin.io

Now, all we need to do is write the API code which, in this case, is really simple. We want to take the JSON payload this API receives, parse it to find an email address, then forward it to the appropriate Klaviyo API to suppress that profile. Here’s some simple code that achieves that.


import requests
import urllib.parse
from napkin import request, response

# Parse inbound payload
payload = request.get_json()
email = payload.get('email')

# Send data to Klaviyo's people/exclusions endpoint
url = "https://a.klaviyo.com/api/v1/people/exclusions?api_key={PRIVATE_KEY}".format(PRIVATE_KEY = os.getenv("private_key"))

# URL encode the payload and send as form data
payload= "email=" + urllib.parse.quote(email)
headers = {
  'Content-Type': 'application/x-www-form-urlencoded'
}

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)

Some additional notes about our code and configuration:

  • This API accepts JSON and expects a field called “email”. We’ll want to remember this for the next step, because that will dictate how we structure our JSON payload that is sent to this API.
  • It then forwards the email address to Klaviyo’s /people/exclusions API, which suppresses the profile from receiving any emails from Flows or Campaigns.
  • Since that Klaviyo API endpoint requires the use of a private Klaviyo API key, we store this as an environment variable in Napkin which allows us to avoid pasting this sensitive value in plaintext in the code.
  • We additionally secure our API endpoint with Napkin’s authentication feature so that only webhooks containing the Napkin-generated API key will be able to use this API. This will help prevent unauthorized use of the API. We’ll need to remember this for the next step as well, because we need to include a special key-value pair in our header.
  • This API is so simple in its purpose that we haven’t included some logic that might make sense in other scenarios, such as payload validation and more actionable error responses.

Napkin automatically generates a URL — in this case https://acme-corp.npkn.net/suppress-klaviyo-profiles — which will host our API, so the only thing left to do is click Deploy. Napkin also has some nice logging as well to test the code, but for present purposes we can assume that’s already been done : )

Building an API with Napkin just requires adding code to process inbound requests

Add webhook action

So, now we’ve got a segment that contains profiles to suppress and a flow that is triggered on membership in that segment. We also have an API endpoint that is capable of forwarding suppressions to Klaviyo when provided with an email address in a JSON body (within an HTTP POST request). In other words, the only thing we’re missing is the webhook action in the flow that sends a request to the API we have deployed.

This step is straightforward with Klaviyo webhook actions. We’ll add a webhook action in the flow, then configure the webhook to be sent to the URL hosting our API endpoint we just created. We’ll paste in the Napkin API key as a header (again, see this for more background). In the JSON payload, we just need to send over 1 email, which is what populates by default so no additional edits are required.

Adding a webhook action in a Klaviyo flow

If we want, we can preview that the payload will contain the data we expect by selecting Preview Webhook. This can help us confirm the payload renders as expected, which can be especially helpful in scenarios requiring more complex payloads or more advanced logic in the webhook template. Here, we can confirm that the payload contains a key for 1 email and a value with an 1 @marketplace.amazon.com email address. Looks good.

How to send a test webhook in a Klaviyo flow

Next, we can select Send Test Request. This will send the JSON payload to our API endpoint we built on Napkin.io. The test request should send in real-time and you can confirm that the webhook was sent successfully by Klaviyo via an auto-generated metric called “Webhook Send Successful”. If any troubleshooting is required, Napkin also logs out requests that are received by the API and since we have a 1 print statement in our code, the Napkin event log will display the console output as well.

Once the payload is received successfully by our API, it will process a request back to Klaviyo and the profile will be suppressed in the Klaviyo app, which will be seen as a red “X” on the user’s profile in Klaviyo.

After you’ve confirmed that everything works well, you can set the webhook action to “live” and optionally, you can back-populate the flow to process any existing segment members. From this point, any time a profile originates in Klaviyo that qualifies into the segment, it will be automatically suppressed.

Impact

In this Solution Recipe, we look at using the Klaviyo flow webhook action to send profile data triggered on segment membership to a custom API endpoint which then sends data back to Klaviyo. This illustrates a few useful patterns that can be extended to cover much more advanced use cases, such as sending webhooks to a custom API and round-tripping data back into Klaviyo after transforming it. Sending webhooks enables wide-ranging functionality, and can greatly enhance what’s possible with Klaviyo.

Learn more!

If you’re interested in learning more about Klaviyo’s developer experience and capabilities, please visit developers.klaviyo.com!

David
David Henriquez