> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Klaviyo

<!-- -->

[Server](#)[ ](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/klaviyo)

<!-- -->

[Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/klaviyo)[ ](https://www.npmjs.com/package/@walkeros/server-destination-klaviyo)

<!-- -->

[Package](https://www.npmjs.com/package/@walkeros/server-destination-klaviyo)

<!-- -->

Beta

Server-side event delivery to [Klaviyo](https://www.klaviyo.com/) via the official [`klaviyo-api`](https://www.npmjs.com/package/klaviyo-api) SDK. Tracks events with `EventsApi.createEvent()` and manages profiles with `ProfilesApi.createOrUpdateProfile()`, including revenue tracking, ecommerce metric name mapping, and identify state diffing.

<!-- -->

Where this fits

Klaviyo is a **server destination** in the walkerOS flow:

Receives events server-side from the collector, resolves a profile identifier (email, externalId, or phoneNumber), optionally upserts the profile, then forwards the event to Klaviyo for flows, segmentation, and campaigns.

## Installation[​](#installation "Direct link to Installation")

```
npm install @walkeros/server-destination-klaviyo
```

* Integrated
* Bundled

```
import { startFlow } from '@walkeros/collector';
import { destinationKlaviyo } from '@walkeros/server-destination-klaviyo';

await startFlow({
  destinations: {
    klaviyo: {
      code: destinationKlaviyo,
      config: {
        settings: {
          apiKey: 'YOUR_KLAVIYO_PRIVATE_API_KEY',
        },
      },
    },
  },
});
```

Add to your `flow.json` destinations:

```
"destinations": {
  "klaviyo": {
    "package": "@walkeros/server-destination-klaviyo",
    "config": {
      "settings": {
        "apiKey": "YOUR_KLAVIYO_PRIVATE_API_KEY"
      }
    }
  }
}
```

[See bundled mode setup](https://www.walkeros.io/docs/getting-started/modes/bundled.md) | [CLI reference](https://www.walkeros.io/docs/apps/cli.md)

## Configuration[​](#configuration "Direct link to Configuration")

This <!-- -->destination<!-- --> uses the standard <!-- -->destination<!-- --> config wrapper (consent, data, env, id, ...). For the shared fields see [destination<!-- --> configuration](https://www.walkeros.io/docs/destinations.md#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to Settings")

| Property      | Type     | Description                                                                                                                                                                                            | More |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---- |
| `apiKey*`     | `string` | Klaviyo private API key. Starts with pk\_. Find it under Settings > API Keys in your Klaviyo account.                                                                                                  |      |
| `email`       | `string` | walkerOS mapping value path to resolve email from each event (like user.email).                                                                                                                        |      |
| `phoneNumber` | `string` | walkerOS mapping value path to resolve phone number in E.164 format from each event.                                                                                                                   |      |
| `externalId`  | `string` | walkerOS mapping value path to resolve external ID from each event (like user.id).                                                                                                                     |      |
| `identify`    | `any`    | Destination-level identity mapping. Resolves to profile attributes { firstName?, lastName?, organization?, properties? }. Fires createOrUpdateProfile() on first push and re-fires when values change. |      |
| `currency`    | `string` | Default ISO 4217 currency code for revenue events (like USD, EUR). Sets valueCurrency on Klaviyo events.                                                                                               |      |
| `uniqueId`    | `any`    | Destination-level dedup key mapping. Resolves to the event uniqueId (unique\_id on the wire) and defaults to the walkerOS event id. Rule-level mapping.uniqueId overrides it per event.                |      |

\* Required fields

## Mapping[​](#mapping "Direct link to Mapping")

Per-event rules under `config.mapping`. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](https://www.walkeros.io/docs/mapping.md).

| Property   | Type  | Description                                                                                                                                                                                                                    | More |
| ---------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---- |
| `identify` | `any` | Per-event identify mapping. Resolves to profile attributes for createOrUpdateProfile(). Use with rule-level silent: true on login/signup events.                                                                               |      |
| `value`    | `any` | Revenue value mapping. Resolves to a numeric value for Klaviyo revenue tracking. Sets the event value attribute (value on the wire), plus valueCurrency when settings.currency is set.                                         |      |
| `uniqueId` | `any` | Dedup key mapping. Resolves to the event uniqueId (unique\_id on the wire). Klaviyo keeps only the first event with a given value per profile and metric. Without it Klaviyo dedups on the event time truncated to the second. |      |

## Examples

### Deduplicated order

An order carries a stable unique id so Klaviyo keeps only the first copy when the same order arrives from another producer.

Event

```
{
  "name": "order complete",
  "data": {
    "id": "ORD-123",
    "total": 49.5
  },
  "context": {
    "shopping": [
      "complete",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "email": "user@example.com"
  },
  "nested": [
    {
      "entity": "product",
      "data": {
        "id": "ers",
        "name": "Everyday Ruck Snack",
        "color": "black",
        "size": "l",
        "price": 420
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "product",
      "data": {
        "id": "cc",
        "name": "Cool Cap",
        "size": "one size",
        "price": 42
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "gift",
      "data": {
        "name": "Surprise"
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "a1b2c3d4e5f60107",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000107,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "name": "Placed Order",
  "data": {
    "map": {
      "OrderId": "data.id"
    }
  },
  "settings": {
    "uniqueId": "data.id"
  }
}
```

Out

```
eventsApi.createEvent({
  "data": {
    "type": "event",
    "attributes": {
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "user@example.com",
            "externalId": "us3r"
          }
        }
      },
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Placed Order"
          }
        }
      },
      "properties": {
        "OrderId": "ORD-123"
      },
      "time": "1970-01-20T16:13:20.107Z",
      "uniqueId": "ORD-123"
    }
  }
})
```

### Default event

An event is sent to Klaviyo as a metric with an inline profile resolved from the user email and id.

Event

```
{
  "name": "product view",
  "data": {
    "id": "ers",
    "name": "Everyday Ruck Snack",
    "color": "black",
    "size": "l",
    "price": 420
  },
  "context": {
    "shopping": [
      "detail",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "email": "user@example.com"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "a1b2c3d4e5f60100",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000100,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Out

```
eventsApi.createEvent({
  "data": {
    "type": "event",
    "attributes": {
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "user@example.com",
            "externalId": "us3r"
          }
        }
      },
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "product view"
          }
        }
      },
      "properties": {},
      "time": "1970-01-20T16:13:20.100Z",
      "uniqueId": "a1b2c3d4e5f60100"
    }
  }
})
```

### Destination identify

Destination-level identify upserts the Klaviyo profile with a first name before each event is sent.

Event

```
{
  "name": "page view",
  "data": {
    "domain": "www.example.com",
    "title": "walkerOS documentation",
    "referrer": "https://www.walkeros.io/",
    "search": "?foo=bar",
    "hash": "#hash",
    "id": "/docs/"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "pagegroup": "docs"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "email": "user@example.com",
    "firstName": "Jane"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "a1b2c3d4e5f60104",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000104,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Out

```
profilesApi.createOrUpdateProfile({
  "data": {
    "type": "profile",
    "attributes": {
      "email": "user@example.com",
      "externalId": "us3r",
      "firstName": "Jane"
    }
  }
});

eventsApi.createEvent({
  "data": {
    "type": "event",
    "attributes": {
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "user@example.com",
            "externalId": "us3r"
          }
        }
      },
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "page view"
          }
        }
      },
      "properties": {},
      "time": "1970-01-20T16:13:20.104Z",
      "uniqueId": "a1b2c3d4e5f60104"
    }
  }
})
```

### Email only

A newsletter signup uses only the email address as the Klaviyo profile identifier, with no external id.

Event

```
{
  "name": "newsletter signup",
  "data": {
    "string": "foo",
    "number": 1,
    "boolean": true,
    "array": [
      0,
      "text",
      false
    ]
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "email": "subscriber@example.com"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "a1b2c3d4e5f60105",
  "trigger": "test",
  "entity": "newsletter",
  "action": "signup",
  "timestamp": 1700000105,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Out

```
eventsApi.createEvent({
  "data": {
    "type": "event",
    "attributes": {
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "subscriber@example.com"
          }
        }
      },
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "newsletter signup"
          }
        }
      },
      "properties": {},
      "time": "1970-01-20T16:13:20.105Z",
      "uniqueId": "a1b2c3d4e5f60105"
    }
  }
})
```

### Viewed product

A product view is mapped to the Klaviyo Viewed Product metric with properties such as product name and price.

Event

```
{
  "name": "product view",
  "data": {
    "name": "USB Cable",
    "id": "PROD-1",
    "price": 9.99
  },
  "context": {
    "shopping": [
      "detail",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "email": "user@example.com"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "a1b2c3d4e5f60101",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000101,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "name": "Viewed Product",
  "data": {
    "map": {
      "ProductName": "data.name",
      "ProductID": "data.id",
      "Price": "data.price"
    }
  }
}
```

Out

```
eventsApi.createEvent({
  "data": {
    "type": "event",
    "attributes": {
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "user@example.com",
            "externalId": "us3r"
          }
        }
      },
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Viewed Product"
          }
        }
      },
      "properties": {
        "ProductName": "USB Cable",
        "ProductID": "PROD-1",
        "Price": 9.99
      },
      "time": "1970-01-20T16:13:20.101Z",
      "uniqueId": "a1b2c3d4e5f60101"
    }
  }
})
```

### Placed order

An order complete is sent to Klaviyo as Placed Order with value and currency for revenue attribution.

Event

```
{
  "name": "order complete",
  "data": {
    "id": "ORD-123",
    "total": 99.99,
    "itemNames": [
      "Widget A",
      "Widget B"
    ]
  },
  "context": {
    "shopping": [
      "complete",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "email": "user@example.com"
  },
  "nested": [
    {
      "entity": "product",
      "data": {
        "id": "ers",
        "name": "Everyday Ruck Snack",
        "color": "black",
        "size": "l",
        "price": 420
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "product",
      "data": {
        "id": "cc",
        "name": "Cool Cap",
        "size": "one size",
        "price": 42
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "gift",
      "data": {
        "name": "Surprise"
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "a1b2c3d4e5f60102",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000102,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "name": "Placed Order",
  "data": {
    "map": {
      "OrderId": "data.id",
      "ItemNames": "data.itemNames"
    }
  },
  "settings": {
    "value": "data.total"
  }
}
```

Out

```
eventsApi.createEvent({
  "data": {
    "type": "event",
    "attributes": {
      "profile": {
        "data": {
          "type": "profile",
          "attributes": {
            "email": "user@example.com",
            "externalId": "us3r"
          }
        }
      },
      "metric": {
        "data": {
          "type": "metric",
          "attributes": {
            "name": "Placed Order"
          }
        }
      },
      "properties": {
        "OrderId": "ORD-123",
        "ItemNames": [
          "Widget A",
          "Widget B"
        ]
      },
      "time": "1970-01-20T16:13:20.102Z",
      "value": 99.99,
      "valueCurrency": "EUR",
      "uniqueId": "a1b2c3d4e5f60102"
    }
  }
})
```

### User login identify

A user login upserts the Klaviyo profile with name, organization, and custom properties without firing an event.

Event

```
{
  "name": "user login",
  "data": {
    "firstName": "Jane",
    "lastName": "Doe",
    "company": "Acme Corp",
    "plan": "premium"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "email": "user@acme.com"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "a1b2c3d4e5f60103",
  "trigger": "test",
  "entity": "user",
  "action": "login",
  "timestamp": 1700000103,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "silent": true,
  "settings": {
    "identify": {
      "map": {
        "firstName": "data.firstName",
        "lastName": "data.lastName",
        "organization": "data.company",
        "properties": {
          "map": {
            "plan": "data.plan"
          }
        }
      }
    }
  }
}
```

Out

```
profilesApi.createOrUpdateProfile({
  "data": {
    "type": "profile",
    "attributes": {
      "email": "user@acme.com",
      "externalId": "us3r",
      "firstName": "Jane",
      "lastName": "Doe",
      "organization": "Acme Corp",
      "properties": {
        "plan": "premium"
      }
    }
  }
})
```

Identity is resolved automatically from each event: `email` defaults to `user.email` and `externalId` defaults to `user.id`. Klaviyo requires at least one identifier (`email`, `phoneNumber`, or `externalId`) per event. Events without any identifier are skipped with a warning.

## Revenue tracking[​](#revenue-tracking "Direct link to Revenue tracking")

Map a mapping rule's `settings.value` to a numeric value. The destination sets it as the Klaviyo event's `value` attribute, the field revenue reporting reads, and when `settings.currency` is also set it adds `valueCurrency` alongside it.

## Deduplication[​](#deduplication "Direct link to Deduplication")

Klaviyo keeps only the first event carrying a given `uniqueId` for a profile and metric. The destination sends the walkerOS event id by default, so two distinct events for the same profile and metric never collide.

Map `settings.uniqueId` to a stable business identifier whenever the same event can reach Klaviyo from more than one producer: browser tracking alongside this destination, a CSV or backfill import, or a retried delivery. A mapping rule's `settings.uniqueId` overrides the destination-level one. Numeric ids are coerced to strings, so an order id like `data.id` works whether it is `'ORD-123'` or `90210`.

## Ecommerce metric naming[​](#ecommerce-metric-naming "Direct link to Ecommerce metric naming")

Klaviyo's built-in flows and reports key off specific metric names. Use `mapping.name` to rename walkerOS events to Klaviyo's expected values:

| walkerOS Event   | Klaviyo Metric   | Unlocks                |
| ---------------- | ---------------- | ---------------------- |
| `product view`   | `Viewed Product` | Product analytics      |
| `product add`    | `Added to Cart`  | Cart abandonment flows |
| `order complete` | `Placed Order`   | Revenue reporting, CLV |
