# Create coupons via Klaviyo

> In this tutorial, let's set up Klaviyo to automatically generate coupons inside Talon.One and add them to customer profiles in Klaviyo.

> For the complete documentation index, see [llms.txt](https://docs.talon.one/llms.txt).

Let's imagine your website has a newsletter. When a customer subscribes to the newsletter,
you want to send them a personal coupon.

To achieve this, we rely on webhooks and API endpoints:

- To send data from Klaviyo to Talon.One, we use [Klaviyo's webhook functionality](https://developers.klaviyo.com/en/docs/how_to_add_a_webhook_action_to_a_flow)
  and Talon.One's [Track event](/integration-api#tag/Events/operation/trackEventV2) endpoint.
- To send data from Talon.One to Klaviyo, we use [Talon.One's webhook functionality](/docs/product/account/dev-tools/manage-webhooks.md) and Klaviyo's
  [Create or Update Profile](https://developers.klaviyo.com/en/reference/create_or_update_profile) endpoint.

## Talon.One requirements

- You are an [admin](/docs/product/account/account-settings/manage-roles.md#admin-role) user.
- You have set up [an Application][App].
- Your Application contains [a running campaign][campaigns] with the **Coupons** feature
  [enabled](/docs/product/campaigns/settings/manage-campaign-features.md).

You can edit the default format of the coupon codes in
the campaign's <Settings className="icon" /> [**Settings**][coupon format] section.

[coupon format]: /docs/product/campaigns/coupons/coupon-page-overview#edit-coupon-format

## Klaviyo requirements

- You have enabled [multi-factor authentication (MFA)](https://help.klaviyo.com/hc/en-us/articles/360026617692) for your account.
- Your [user role](https://help.klaviyo.com/hc/en-us/articles/115005231648) is Manager, Admin, or Owner.
- You have created a [list](https://help.klaviyo.com/hc/en-us/articles/115005078967).
  In this tutorial, we assume the list is named `Newsletter`.
  :::tip
  The workflow described in this tutorial also works with [segments](https://help.klaviyo.com/hc/en-us/articles/115005237908).
  :::

## Workflow overview

In the sections below, we create a workflow that includes the following steps:

- Adding a customer to a newsletter list in Klaviyo triggers a [flow](#create-the-flow) with a webhook action.
- The webhook action calls Talon.One's [Track event](/integration-api#tag/Events/operation/trackEventV2)
  endpoint, providing the customer's profile ID.
- Registering the event in Talon.One triggers a [rule](#create-the-rule) that creates a coupon code for the customer.
- Creating the coupon triggers a [custom webhook](#create-the-webhook) in Talon.One.
- The custom webhook calls Klaviyo's [Create or Update Profile](https://developers.klaviyo.com/en/reference/create_or_update_profile)
  endpoint, providing the profile ID and the coupon code.
- The customer's profile is updated with the coupon code.

<KlaviyoWorkflow className="figma" width="100%" alt="Klaviyo workflow" />

## Set up the integration

<StepsContainer>

### Create the API keys

To send data back and forth, we need access keys for Talon.One's [Integration API](/docs/dev/integration-api/overview.md) and Klaviyo's [Profiles API](https://developers.klaviyo.com/en/reference/profiles_api_overview).

#### Integration API key

To create an Integration API key in Talon.One:

1. In your Application, click <Settings className="icon" /> **Settings** > **Integration API Keys**.
1. Click <Add className="icon" /> **Create API Key**.
1. In the **Create API Key** drawer, if you are asked for a key type, select **Production**.
1. In **Key name**, type a name to identify the key.
1. In **Key expiration date**, select a date.

   :::tip
   Avoid choosing expiration dates that fall at the end of the year or during other
   high-traffic periods.
   :::

1. In **Third-party integration**, select **No**.
1. Click **Create API Key**.
1. Click <Copy className="icon" /> to copy the key for use.

:::note
You cannot view or copy the API key after closing the drawer.
:::

#### Profiles API key

To create a Profiles API key in Klaviyo, refer to the [Klaviyo docs](https://help.klaviyo.com/hc/en-us/articles/7423954176283).

The key must have **Read/Write** access for the **Profiles** scope.

### Create the flow

Next, we create a Klaviyo [flow](https://help.klaviyo.com/hc/en-us/articles/115002774932) with a webhook action that
calls Talon.One's [Track event](/integration-api#tag/Events/operation/trackEventV2) endpoint:

1. In Klaviyo, open **Flows** and click **Create flow**.
1. Click **Build your own**, type a name for the flow, and click **Create flow**.
1. Select the **Added to list** trigger, choose the list you [created](#klaviyo-requirements), and save the trigger.
1. On the left-side menu of the flow builder, click the **Webhook** action and drag it into your flow.
1. Name the webhook and make the following settings:
   - **Destination URL:** `https://YOUR_DEPLOYMENT_URL/v2/events`, where `YOUR_DEPLOYMENT_URL`
      is the base URL of your Talon.One deployment, for example, `mycompany.europe-west1.talon.one`.
   - **Headers:**

      | Key               | Value                                                                                                          |
      | ----------------- | -------------------------------------------------------------------------------------------------------------- |
      | **Authorization** | `ApiKey-v1 YOUR_API_KEY`, where `YOUR_API_KEY` is the Integration API key you [created](#integration-api-key). |
      | **Content-Type**  | `application/json`                                                                                             |
      | **Accept**        | `application/json`                                                                                             |

   - **JSON body:**

      ```json
      {
        "type": "klaviyoEvent",
        "profileId": "{{ person.KlaviyoID|default:'' }}",
        "attributes": {
          "flowName": "newsletter"
        }
      }
      ```

Now, whenever a customer is added to your list, a request is sent to Talon.One's API.

The request includes the following:

- The **type** of the event (`klaviyoEvent`).
- A **unique ID** of the current customer's profile in Klaviyo (`person.KlaviyoID`).
  This allows us to personalize the coupon code.
- A **custom attribute** named `flowName` with the static value `newsletter`.
  This allows us to uniquely identify the requests from this flow.

To register the event, both the event type and the custom attribute must exist in Talon.One, so let's [create them](#create-the-custom-attributes).

### Create the custom attributes

To create the custom attributes required for your [flow](#create-the-flow):

1. In Talon.One, click <Account className="icon"/> **Account** > <Tools className="icon"/> **Tools** > **Attributes** > **Create Attribute**.
1. In **Entity**, select **Event**.
1. In **Event type**, type `klaviyoEvent`.
1. In **Type**, select **String**.
1. In **API name**, type `flowName`.
1. In **Name**, type `Flow name`.
1. Fill the other fields as needed and click **Create Attribute**.

This creates both the `klaviyoEvent` event type and the `flowName` attribute.

### Create the webhook

To send data back to Klaviyo, we create a webhook that calls Klaviyo's [Create or Update Profile](https://developers.klaviyo.com/en/reference/create_or_update_profile) endpoint:

1. In the Campaign Manager, click <Account className="icon"/> **Account** > <Tools className="icon"/>
   **Tools** > **Webhooks** and click **Create Webhook**.
1. In **Properties**, enter a name and select your Application.
1. Add the parameters to include in the request. In this tutorial, we use the following parameters:

   | **Param type** | **Param name**      |
   | -------------- | ------------------- |
   | `string`       | `CouponCode`        |
   | `string`       | `CustomerProfileID` |

1. In **Request**, set **Verb** to **POST**.
1. In **URL**, enter `https://a.klaviyo.com/api/profile-import/`.
1. In **Headers**, click **Add** and define the following headers:
   - `Authorization: Klaviyo-API-Key YOUR_KLAVIYO_API_KEY`, where `YOUR_KLAVIYO_API_KEY` is the API key you [created](#profiles-api-key).
   - `revision: 2024-10-15`. For more information about API revisions, see the [Klaviyo docs](https://developers.klaviyo.com/en/docs/api_versioning_and_deprecation_policy#api-versioning).
   - `accept: application/json`
   - `content-type: application/json`
1. In **Payload**, add the following request payload:

   ```json
   {
     "data": {
       "type": "profile",
       "attributes": {
         "properties": {
           "t1_coupon": "${$CouponCode}"
         }
       },
       "id": "${$CustomerProfileID}"
     }
   }
   ```

   :::tip
   To learn more about accessing Talon.One attributes and including them in the webhook,
   see [Use parameters in the webhook payload](/docs/product/account/dev-tools/manage-webhooks.md#use-parameters-in-the-webhook-payload).
   :::

This webhook calls Klaviyo's API to store the coupon code in a [custom profile property](https://help.klaviyo.com/hc/en-us/articles/115000250912)
named `t1_coupon`. The property is created automatically when the endpoint is called.

### Create the rule

Now, let's bring it all together by creating a [rule](/docs/product/rules/create-and-manage-rules.md)
that generates the coupon code and stores it in Klaviyo:

| What          | Name                                               | Properties                                                                                                                                                                                                                                                                                      |
| ------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Condition** | Check for event typesand custom event values | Event type: <code>klaviyoEvent</code><Attribute name="Flow Name (Event)" type="custom" /> is equal to <code>newsletter</code>.                                                                                                     |
| **Effect 1**  | Create coupon code                                 | Set your desired coupon settings.Ensure **Recipient** is set to **Current Customer (Friend)**.                                                                                                                                                                       |
| **Effect 2**  | Webhooks                                           | Choose the name of the webhook you [created](#create-the-webhook).Set **CouponCode** to <Attribute name="Generated Coupon in Session" type="builtin" />.Set **CustomerProfileID** to <Attribute name="Integration ID (Customer Profile)" type="builtin" />. |

When the matching event is registered, the rule is triggered, a coupon code is generated, and
the custom webhook is triggered, which stores the coupon code in Klaviyo.

</StepsContainer>

## Next steps

Now that all of your newsletter subscribers have a personal coupon code, you can send
them the code, for example, by creating an [email campaign](https://help.klaviyo.com/hc/en-us/articles/115005054847) in Klaviyo.

To reference the coupon code in the email, use the following [personalization tag](https://help.klaviyo.com/hc/en-us/articles/4408802648731): `{{ person|lookup:"t1_coupon" }}`.

[App]: /docs/product/applications/overview.md
[campaigns]: /docs/product/campaigns/overview.md
