# Klaviyo

Klaviyo is an email marketing and automation platform designed for e-commerce businesses. It provides tools for managing customer profiles, email campaigns, automated flows, audience segmentation, and analytics. The Sling Klaviyo connector extracts data from the Klaviyo API (v2025-07-15), supporting profiles, lists, segments, campaigns, flows, events, metrics, templates, tags, catalog items, and membership data.

{% hint style="success" %}
**CLI Pro Required**: APIs require a [CLI Pro token](https://docs.slingdata.io/sling-cli/cli-pro) or [Platform Plan](https://docs.slingdata.io/sling-platform/platform).
{% endhint %}

## Setup

The following credentials are accepted:

**Secrets:**

* `api_key` **(required)** -> Your Klaviyo Private API Key

### Getting Your API Key

1. Log in to your [Klaviyo account](https://www.klaviyo.com/login)
2. Click **Settings** (gear icon) in the bottom-left corner
3. Go to **Account** > **Settings** > **API Keys**
4. Click **Create Private API Key**
5. Give it a name (e.g., "Sling Integration")
6. Select **Read-Only Key** for the access level (Sling only needs read access)
7. Click **Create** and copy the key (it starts with `pk_`)

{% hint style="warning" %}
**Important:** Use a **Private API Key** (starts with `pk_`), not a Public API Key (6-character alphanumeric string). Public keys do not have access to the server-side API endpoints that Sling uses.
{% endhint %}

### Using `sling conns`

{% code overflow="wrap" %}

```bash
sling conns set KLAVIYO type=api spec=klaviyo secrets='{ api_key: "pk_xxxxxxxxxxxxxxxxxxxx" }'
```

{% endcode %}

### Environment Variable

{% code overflow="wrap" %}

```bash
export KLAVIYO='{ type: api, spec: klaviyo, secrets: { api_key: "pk_xxxxxxxxxxxxxxxxxxxx" } }'
```

{% endcode %}

### Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

```yaml
connections:
  KLAVIYO:
    type: api
    spec: klaviyo
    secrets:
      api_key: "pk_xxxxxxxxxxxxxxxxxxxx"
```

## Replication

Here's an example replication configuration to sync Klaviyo data to a PostgreSQL database:

```yaml
source: KLAVIYO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: klaviyo.{stream_name}

streams:
  # Core data with incremental sync
  profiles:
    mode: incremental
  events:
    mode: incremental

  # Campaign and automation data
  campaigns:
  flows:
  templates:
    mode: incremental

  # Audience data
  lists:
  segments:

  # Reference data
  metrics:
  tags:
  catalog_items:

  # Membership data (parent-child)
  list_profiles:
  segment_profiles:
```

**Incremental sync example:**

```yaml
source: KLAVIYO
target: MY_POSTGRES

defaults:
  mode: incremental
  object: klaviyo.{stream_name}

streams:
  profiles:
  events:
  templates:
```

**Full refresh example:**

```yaml
source: KLAVIYO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: klaviyo.{stream_name}

streams:
  lists:
  segments:
  campaigns:
  flows:
  metrics:
  tags:
  catalog_items:
```

## Endpoints

### Audience Management

| Endpoint           | Description                                         | Incremental |
| ------------------ | --------------------------------------------------- | ----------- |
| `profiles`         | Customer profiles (contacts/subscribers)            | Yes         |
| `lists`            | Email lists/audiences                               | No          |
| `segments`         | Audience segments                                   | No          |
| `list_profiles`    | Profile memberships per list (child of lists)       | No          |
| `segment_profiles` | Profile memberships per segment (child of segments) | No          |

### Campaign & Automation

| Endpoint    | Description                  | Incremental |
| ----------- | ---------------------------- | ----------- |
| `campaigns` | Email campaigns              | No          |
| `flows`     | Automation workflows (flows) | No          |
| `templates` | Email templates              | Yes         |

### Analytics & Events

| Endpoint  | Description                                          | Incremental |
| --------- | ---------------------------------------------------- | ----------- |
| `events`  | Email activity events (opens, clicks, bounces, etc.) | Yes         |
| `metrics` | Metric/event type definitions                        | No          |

### Catalog & Metadata

| Endpoint        | Description                   | Incremental |
| --------------- | ----------------------------- | ----------- |
| `tags`          | Tags for organizing resources | No          |
| `catalog_items` | Product catalog items         | No          |

To discover available endpoints:

```bash
sling conns discover KLAVIYO
```

## Parent-Child Endpoints

Some endpoints are children of parent endpoints and require the parent to run first:

* **list\_profiles** -> Requires `lists` to run first (iterates through each list to fetch member profiles)
* **segment\_profiles** -> Requires `segments` to run first (iterates through each segment to fetch member profiles)

When using these endpoints in a replication, Sling automatically handles the ordering via internal queues. The parent endpoint collects IDs, and the child endpoint iterates through them.

## Incremental Sync

The Klaviyo connector supports time-based incremental sync for the following endpoints:

* **profiles** - Syncs profiles modified after the last sync using the `updated` field
* **events** - Syncs events created after the last sync using the `datetime` field
* **templates** - Syncs templates modified after the last sync using the `updated` field

### How it works

* **First run:** Fetches records from the last 30 days (profiles and events) or last 365 days (templates)
* **Subsequent runs:** Only fetches records created or modified after the last sync timestamp
* **Profiles** use `greater-than` filter on the `updated` field
* **Events** and **templates** use `greater-or-equal` filter on their respective date fields

## Rate Limiting

The Klaviyo API enforces rate limits based on your account plan:

* **Free:** 3 requests/second for most endpoints
* **Paid plans:** Higher limits available

The connector automatically:

* Uses conservative rate limiting (3 requests/second)
* Limits concurrency to 3 parallel requests
* Retries with exponential backoff on 429 (rate limit) responses (up to 5 attempts)

## Common Use Cases

### Sync Customer Profiles and Activity

```yaml
source: KLAVIYO
target: MY_POSTGRES

defaults:
  mode: incremental
  object: klaviyo.{stream_name}

streams:
  profiles:
  events:
  metrics:
    mode: full-refresh
```

### Sync Campaign and Automation Data

```yaml
source: KLAVIYO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: klaviyo.{stream_name}

streams:
  campaigns:
  flows:
  templates:
    mode: incremental
```

### Sync Audience Membership Data

```yaml
source: KLAVIYO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: klaviyo.{stream_name}

streams:
  lists:
  segments:
  list_profiles:
  segment_profiles:
```

### Sync All Klaviyo Data

```yaml
source: KLAVIYO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: klaviyo.{stream_name}

streams:
  '*':

  # Override incremental endpoints
  profiles:
    mode: incremental
  events:
    mode: incremental
  templates:
    mode: incremental
```

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).
