Skip to content
Development
Skill

/klaviyo

Klaviyo email/SMS marketing - profiles, events, flows, segmentation

From plugin
maggy
71073 skills1 agent25 commands1 hook

Claude Code

$ npx -y skills add alinaqi/maggy --skill klaviyo --agent claude-code

SKILL.md

klaviyo.SKILL.md
name: klaviyo
description: Klaviyo email/SMS marketing - profiles, events, flows, segmentation
when-to-use: When integrating Klaviyo for email/SMS marketing
user-invocable: false
effort: medium

Klaviyo E-Commerce Marketing Skill

For integrating Klaviyo email/SMS marketing - customer profiles, event tracking, campaigns, flows, and segmentation.

**Sources:** [Klaviyo API Docs](https://developers.klaviyo.com/en/docs) | [API Reference](https://developers.klaviyo.com/en/reference/api-overview)

---

Why Klaviyo

| Feature | Benefit | |---------|---------| | **E-commerce Native** | Built for online stores, deep integrations | | **Event-Based** | Trigger flows from any customer action | | **Segmentation** | Advanced filtering on behavior + properties | | **Email + SMS** | Unified platform for both channels | | **Analytics** | Revenue attribution per campaign |

---

API Basics

Base URLs

| Type | URL | |------|-----| | Server-side (Private) | `https://a.klaviyo.com/api` | | Client-side (Public) | `https://a.klaviyo.com/client` |

Authentication

// Server-side: Private API Key
const headers = {
  "Authorization": "Klaviyo-API-Key pk_xxxxxxxxxxxxxxxxxxxxxxxx",
  "Content-Type": "application/json",
  "revision": "2024-10-15",  // API version
};

// Client-side: Public API Key (6 characters)
const publicKey = "XXXXXX";  // Company ID
// Use as query param: ?company_id=XXXXXX

API Key Scopes

| Scope | Access | |-------|--------| | Read-only | View data only | | Full | Read + write (default) | | Custom | Specific permissions |

---

Installation

Node.js

npm install klaviyo-api
// lib/klaviyo.ts
import { ApiClient, EventsApi, ProfilesApi, ListsApi } from "klaviyo-api";

const client = new ApiClient();
client.setApiKey(process.env.KLAVIYO_PRIVATE_KEY!);

export const eventsApi = new EventsApi(client);
export const profilesApi = new ProfilesApi(client);
export const listsApi = new ListsApi(client);

Python

pip install klaviyo-api
# lib/klaviyo.py
from klaviyo_api import KlaviyoAPI

klaviyo = KlaviyoAPI(
    api_key=os.environ["KLAVIYO_PRIVATE_KEY"],
    max_delay=60,
    max_retries=3
)

Direct HTTP (Any Language)

// lib/klaviyo.ts
const KLAVIYO_BASE_URL = "https://a.klaviyo.com/api";

async function klaviyoRequest(
  endpoint: string,
  method: "GET" | "POST" | "PATCH" | "DELETE" = "GET",
  body?: object
) {
  const response = await fetch(`${KLAVIYO_BASE_URL}${endpoint}`, {
    method,
    headers: {
      Authorization: `Klaviyo-API-Key ${process.env.KLAVIYO_PRIVATE_KEY}`,
      "Content-Type": "application/json",
      revision: "2024-10-15",
    },
    body: body ? JSON.stringify(body) : undefined,
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Klaviyo API error: ${JSON.stringify(error)}`);
  }

  return response.json();
}

---

Profiles (Customers)

Create/Update Profile

// Upsert profile (create or update)
async function upsertProfile(data: ProfileInput) {
  return klaviyoRequest("/profiles", "POST", {
    data: {
      type: "profile",
      attributes: {
        email: data.email,
        phone_number: data.phone, // E.164 format: +1234567890
        first_name: data.firstName,
        last_name: data.lastName,
        properties: {
          // Custom properties
          lifetime_value: data.ltv,
          plan: data.plan,
          signup_source: data.source,
        },
        location: {
          city: data.city,
          region: data.state,
          country: data.country,
          zip: data.zip,
        },
      },
    },
  });
}
# Python
def upsert_profile(data):
    return klaviyo.Profiles.create_or_update_profile({
        "data": {
            "type": "profile",
            "attributes": {
                "email": data["email"],
                "first_name": data["first_name"],
                "last_name": data["last_name"],
                "properties": {
                    "plan": data.get("plan"),
                }
            }
        }
    })

Get Profile

async function getProfileByEmail(email: string) {
  const response = await klaviyoRequest(
    `/profiles?filter=equals(email,"${email}")`
  );
  return response.data[0];
}

async function getProfileById(profileId: string) {
  return klaviyoRequest(`/profiles/${profileId}`);
}

Update Profile Properties

async function updateProfileProperties(
  profileId: string,
  properties: Record<string, any>
) {
  return klaviyoRequest(`/profiles/${profileId}`, "PATCH", {
    data: {
      type: "profile",
      id: profileId,
      attributes: {
        properties,
      },
    },
  });
}

// Usage
await updateProfileProperties("profile_id", {
  last_purchase_date: new Date().toISOString(),
  total_orders: 5,
  vip_status: true,
});

---

Events (Tracking)

Track Event (Server-Side)

async function trackEvent(data: EventInput) {
  return klaviyoRequest("/events", "POST", {
    data: {
      type: "event",
      attributes: {
        profile: {
          data: {
            type: "profile",
            attributes: {
              email: data.email,
              // or phone_number, or external_id
            },
          },
        },
        metric: {
          data: {
            type: "metric",
            attributes: {
              name: data.eventName,
            },
          },
        },
        properties: data.properties,
        value: data.value, // For revenue tracking
        unique_id: data.uniqueId, // Deduplication
        time: data.timestamp || new Date().toISOString(),
      },
    },
  });
}

Common E-Commerce Events

// Viewed Product
await trackEvent({
  email: customer.email,
  eventName: "Viewed Product",
  properties: {
    ProductID: product.id,
    ProductName: product.name,
    ProductURL:
Read more
@alinaqi
Ships withmaggy

Turn Claude Code into a self-reviewing, test-enforced engineering system that remembers context across sessions — then route work across 13 models from a single dashboard.

71073 skills1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
710
Star history of alinaqi/maggy on GitHub, a chart by star-history.com

Other skills on maggy.

aeo-optimization

aeo-optimization

AI Engine Optimization - semantic triples, page templates, content clusters for AI citations

@alinaqi@alinaqiInstall Skill
agent-teams

agent-teams

Claude Code Agent Teams - default team-based development with strict TDD pipeline enforcement

@alinaqi@alinaqiInstall Skill
ai-models

ai-models

Latest AI models reference - Claude, OpenAI, Gemini, Eleven Labs, Replicate

@alinaqi@alinaqiInstall Skill
android-kotlin

android-kotlin

Android Kotlin development with Coroutines, Jetpack Compose, Hilt, and MockK testing

@alinaqi@alinaqiInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about klaviyo.

Which coding agents can use klaviyo?
klaviyo installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.