Token导航 LogoToken导航

Agent Skill · 待分类

klaviyo(klaviyo 日程管理)

klaviyo 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

klaviyo 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证为 MIT,第三方扫描已通过,按安装量在待分类类的 11,209 个 Skill 里排第 1,170。

总安装 4,657周安装 198GitHub Stars 590下载 1,632核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:klaviyo(klaviyo 日程管理)
来源仓库:https://github.com/alinaqi/claude-bootstrap
仓库路径:skills/klaviyo
安装命令:
npx skills add https://github.com/alinaqi/claude-bootstrap --skill klaviyo
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/alinaqi/claude-bootstrap --skill klaviyo

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

Klaviyo 技能用于电商营销自动化,支持客户画像、事件追踪、邮件/SMS 活动管理。适用于需要深度集成电商平台并与 Klaviyo API 对接的营销自动化项目。提供客户分群、转化归因和统一渠道管理等高级功能,基于事件触发工作流。

安装命令:npx skills add https://github.com/alinaqi/claude-bootstrap --skill klaviyo 使用前需获取 Klaviyo API 密钥,区分服务端(Private)和客户端(Public)端点使用场景。

来源仓库内路径:skills/klaviyo

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/alinaqi/claude-bootstrap --skill klaviyo;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

klaviyo 怎么安装?

在终端执行 npx skills add https://github.com/alinaqi/claude-bootstrap --skill klaviyo。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

klaviyo 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

klaviyo 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

klaviyo 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

klaviyo 用的人多吗?

公开数据是累计安装 4,657 次,近一周安装 198 次,下载 1,632 次,GitHub 590 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

klaviyo 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理待分类类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要厂商级技术支持和 SLA 的生产系统。

待分类类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
infsh-cli

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
klaviyo

klaviyo 日程管理 · 本页

4,657590接触敏感数据MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Klaviyo E-Commerce Marketing Skill

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

Sources: Klaviyo API Docs | API Reference


Why Klaviyo

FeatureBenefit
E-commerce NativeBuilt for online stores, deep integrations
Event-BasedTrigger flows from any customer action
SegmentationAdvanced filtering on behavior + properties
Email + SMSUnified platform for both channels
AnalyticsRevenue attribution per campaign

API Basics

Base URLs

TypeURL
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

ScopeAccess
Read-onlyView data only
FullRead + write (default)
CustomSpecific 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: product.url,
    ImageURL: product.image,
    Price: product.price,
    Categories: product.categories,
  },
});

// Added to Cart
await trackEvent({
  email: customer.email,
  eventName: "Added to Cart",
  properties: {
    ProductID: product.id,
    ProductName: product.name,
    Quantity: quantity,
    Price: product.price,
    CartTotal: cart.total,
    ItemNames: cart.items.map(i => i.name),
  },
  value: product.price * quantity,
});

// Started Checkout
await trackEvent({
  email: customer.email,
  eventName: "Started Checkout",
  properties: {
    CheckoutURL: checkout.url,
    ItemCount: cart.itemCount,
    Categories: cart.categories,
    ItemNames: cart.items.map(i => i.name),
  },
  value: cart.total,
});

// Placed Order
await trackEvent({
  email: customer.email,
  eventName: "Placed Order",
  properties: {
    OrderId: order.id,
    ItemCount: order.itemCount,
    Categories: order.categories,
    ItemNames: order.items.map(i => i.name),
    Items: order.items.map(i => ({
      ProductID: i.productId,
      ProductName: i.name,
      Quantity: i.quantity,
      Price: i.price,
      ImageURL: i.image,
      ProductURL: i.url,
    })),
    BillingAddress: order.billingAddress,
    ShippingAddress: order.shippingAddress,
  },
  value: order.total,
  uniqueId: order.id, // Prevent duplicate orders
});

// Fulfilled Order
await trackEvent({
  email: customer.email,
  eventName: "Fulfilled Order",
  properties: {
    OrderId: order.id,
    TrackingNumber: fulfillment.trackingNumber,
    TrackingURL: fulfillment.trackingUrl,
    Carrier: fulfillment.carrier,
  },
});

// Cancelled Order
await trackEvent({
  email: customer.email,
  eventName: "Cancelled Order",
  properties: {
    OrderId: order.id,
    Reason: cancellation.reason,
  },
  value: -order.total, // Negative value for refunds
});

Client-Side Tracking (JavaScript)

<!-- Add to your site -->
<script async src="https://static.klaviyo.com/onsite/js/klaviyo.js?company_id=XXXXXX"></script>

<script>
  // Identify user
  klaviyo.identify({
    email: "customer@example.com",
    first_name: "John",
    last_name: "Doe",
  });

  // Track event
  klaviyo.track("Viewed Product", {
    ProductID: "prod_123",
    ProductName: "Blue T-Shirt",
    Price: 29.99,
  });

  // Track with value
  klaviyo.track("Added to Cart", {
    ProductID: "prod_123",
    ProductName: "Blue T-Shirt",
    Price: 29.99,
    $value: 29.99,  // Revenue tracking
  });
</script>

Lists & Segments

Add Profile to List

async function addToList(listId: string, emails: string[]) {
  return klaviyoRequest(`/lists/${listId}/relationships/profiles`, "POST", {
    data: emails.map(email => ({
      type: "profile",
      attributes: { email },
    })),
  });
}

// By profile ID
async function addProfileToList(listId: string, profileId: string) {
  return klaviyoRequest(`/lists/${listId}/relationships/profiles`, "POST", {
    data: [{ type: "profile", id: profileId }],
  });
}

Remove from List

async function removeFromList(listId: string, profileId: string) {
  return klaviyoRequest(
    `/lists/${listId}/relationships/profiles`,
    "DELETE",
    {
      data: [{ type: "profile", id: profileId }],
    }
  );
}

Get List Members

async function getListMembers(listId: string, cursor?: string) {
  const params = new URLSearchParams({
    "page[size]": "100",
  });
  if (cursor) {
    params.set("page[cursor]", cursor);
  }

  return klaviyoRequest(`/lists/${listId}/profiles?${params}`);
}

Create List

async function createList(name: string) {
  return klaviyoRequest("/lists", "POST", {
    data: {
      type: "list",
      attributes: { name },
    },
  });
}

Campaigns

Get Campaigns

async function getCampaigns(status?: "draft" | "scheduled" | "sent") {
  const params = new URLSearchParams();
  if (status) {
    params.set("filter", `equals(status,"${status}")`);
  }

  return klaviyoRequest(`/campaigns?${params}`);
}

Get Campaign Performance

async function getCampaignMetrics(campaignId: string) {
  return klaviyoRequest(
    `/campaign-recipient-estimations/${campaignId}`,
    "GET"
  );
}

Flows (Automations)

Get Flows

async function getFlows() {
  return klaviyoRequest("/flows");
}

async function getFlowById(flowId: string) {
  return klaviyoRequest(`/flows/${flowId}`);
}

Common Flow Triggers

Flow TypeTrigger Event
Welcome SeriesAdded to List
Abandoned CartAdded to Cart + No Purchase
Browse AbandonViewed Product + No Cart
Post-PurchasePlaced Order
WinbackNo Order in X Days
Review RequestFulfilled Order

Webhooks

Create Webhook

async function createWebhook(data: WebhookInput) {
  return klaviyoRequest("/webhooks", "POST", {
    data: {
      type: "webhook",
      attributes: {
        name: data.name,
        endpoint_url: data.url,
        secret_key: data.secret,
        topics: data.topics, // e.g., ["profile.created", "event.created"]
      },
    },
  });
}

Webhook Topics

TopicTrigger
profile.createdNew profile created
profile.updatedProfile properties changed
profile.mergedProfiles merged
event.createdNew event tracked
list.member.addedProfile added to list
list.member.removedProfile removed from list

Verify Webhook Signature

import crypto from "crypto";

function verifyKlaviyoWebhook(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expectedSignature = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("base64");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Express handler
app.post("/webhooks/klaviyo", (req, res) => {
  const signature = req.headers["klaviyo-webhook-signature"] as string;

  if (!verifyKlaviyoWebhook(JSON.stringify(req.body), signature, WEBHOOK_SECRET)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const { type, data } = req.body;

  switch (type) {
    case "profile.created":
      handleNewProfile(data);
      break;
    case "event.created":
      handleNewEvent(data);
      break;
  }

  res.status(200).json({ received: true });
});

Rate Limits

WindowLimit
Burst75 requests/second
Steady700 requests/minute

Handle Rate Limiting

async function klaviyoRequestWithRetry(
  endpoint: string,
  method: "GET" | "POST" | "PATCH" | "DELETE" = "GET",
  body?: object,
  retries = 3
): Promise<any> {
  for (let attempt = 0; attempt < retries; attempt++) {
    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.status === 429) {
      const retryAfter = parseInt(response.headers.get("Retry-After") || "5");
      await new Promise(r => setTimeout(r, retryAfter * 1000));
      continue;
    }

    if (!response.ok) {
      throw new Error(`Klaviyo error: ${response.status}`);
    }

    return response.json();
  }

  throw new Error("Max retries exceeded");
}

Pagination

async function getAllProfiles() {
  const profiles = [];
  let cursor: string | undefined;

  do {
    const params = new URLSearchParams({ "page[size]": "100" });
    if (cursor) {
      params.set("page[cursor]", cursor);
    }

    const response = await klaviyoRequest(`/profiles?${params}`);
    profiles.push(...response.data);

    cursor = response.links?.next
      ? new URL(response.links.next).searchParams.get("page[cursor]")
      : undefined;
  } while (cursor);

  return profiles;
}

Filtering & Sorting

// Filter by date
const recentEvents = await klaviyoRequest(
  `/events?filter=greater-than(datetime,2024-01-01T00:00:00Z)`
);

// Filter by property
const vipProfiles = await klaviyoRequest(
  `/profiles?filter=equals(properties.vip_status,true)`
);

// Multiple filters (AND)
const filtered = await klaviyoRequest(
  `/profiles?filter=and(equals(properties.plan,"pro"),greater-than(properties.ltv,1000))`
);

// Sorting
const sorted = await klaviyoRequest(
  `/profiles?sort=-created`  // Descending by created date
);

// Sparse fieldsets (only return specific fields)
const sparse = await klaviyoRequest(
  `/profiles?fields[profile]=email,first_name,properties`
);

Integration Patterns

E-Commerce Order Sync

// After order is placed
async function syncOrderToKlaviyo(order: Order) {
  // 1. Upsert customer profile
  await upsertProfile({
    email: order.customerEmail,
    firstName: order.customerFirstName,
    lastName: order.customerLastName,
    phone: order.customerPhone,
  });

  // 2. Update lifetime metrics
  await updateProfileProperties(
    await getProfileIdByEmail(order.customerEmail),
    {
      last_order_date: new Date().toISOString(),
      total_orders: order.customerOrderCount,
      lifetime_value: order.customerLifetimeValue,
    }
  );

  // 3. Track order event
  await trackEvent({
    email: order.customerEmail,
    eventName: "Placed Order",
    properties: {
      OrderId: order.id,
      Items: order.items,
      // ... other properties
    },
    value: order.total,
    uniqueId: order.id,
  });
}

Subscription Status Sync

// When subscription changes
async function syncSubscriptionStatus(user: User, status: string) {
  await updateProfileProperties(user.klaviyoProfileId, {
    subscription_status: status,
    subscription_plan: user.plan,
    subscription_updated_at: new Date().toISOString(),
  });

  await trackEvent({
    email: user.email,
    eventName: `Subscription ${status}`,
    properties: {
      plan: user.plan,
      mrr: user.mrr,
    },
    value: status === "cancelled" ? -user.mrr : user.mrr,
  });
}

Environment Variables

# .env
KLAVIYO_PRIVATE_KEY=pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
KLAVIYO_PUBLIC_KEY=XXXXXX
KLAVIYO_WEBHOOK_SECRET=your_webhook_secret

Add to credentials.md:

'KLAVIYO_PRIVATE_KEY': r'pk_[a-f0-9]{32}',
'KLAVIYO_PUBLIC_KEY': r'[A-Z0-9]{6}',

Checklist

Setup

  • Klaviyo account created
  • Private API key generated
  • Public API key noted (company ID)
  • API revision set in headers

Integration

  • Profile sync on signup/update
  • Key events tracked (view, cart, order)
  • Order events include Items array
  • Revenue tracked with $value
  • Unique IDs for deduplication

Testing

  • Test profile creation
  • Test event tracking
  • Verify events in Klaviyo dashboard
  • Test webhook delivery
  • Test rate limit handling

Anti-Patterns

  • Missing email/phone - Every profile needs at least one identifier
  • Duplicate events - Use unique_id for orders/transactions
  • Missing Items array - Required for product recommendations
  • Client-side only - Server-side tracking is more reliable
  • Ignoring rate limits - Implement exponential backoff
  • Hardcoded API keys - Use environment variables
  • Missing revenue tracking - Include $value for ROI attribution

平台分布

Claude Code

28.88%
按下载量换算471

OpenCode

24.81%
按下载量换算405

Gemini CLI

18.19%
按下载量换算297

Antigravity

13.99%
按下载量换算228

Codex

8.01%
按下载量换算131

Cursor

4.18%
按下载量换算68

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills