Claude-code-plugins klaviyo-core-workflow-b
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/klaviyo-pack/skills/klaviyo-core-workflow-b" ~/.claude/skills/jeremylongshore-claude-code-plugins-klaviyo-core-workflow-b && rm -rf "$T"
manifest:
plugins/saas-packs/klaviyo-pack/skills/klaviyo-core-workflow-b/SKILL.mdsource content
Klaviyo Core Workflow B -- Events, Segments & Campaigns
Overview
Secondary workflow: track customer events, query segments, create/send campaigns, and trigger metric-based flows via the
klaviyo-api SDK.
Prerequisites
- Completed
(profiles/lists set up)klaviyo-core-workflow-a - API key scopes:
,events:write
,segments:read
,campaigns:read
,campaigns:writeflows:read
Instructions
Step 1: Track Server-Side Events
import { ApiKeySession, EventsApi, EventEnum, ProfileEnum, MetricsApi, } from 'klaviyo-api'; const session = new ApiKeySession(process.env.KLAVIYO_PRIVATE_KEY!); const eventsApi = new EventsApi(session); // Track a purchase event (creates the metric if it doesn't exist) await eventsApi.createEvent({ data: { type: EventEnum.Event, attributes: { metric: { data: { type: 'metric', attributes: { name: 'Placed Order' }, }, }, profile: { data: { type: ProfileEnum.Profile, attributes: { email: 'customer@example.com' }, }, }, properties: { orderId: 'ORD-12345', items: [ { productId: 'SKU-001', name: 'Widget', quantity: 2, price: 29.99 }, { productId: 'SKU-002', name: 'Gadget', quantity: 1, price: 49.99 }, ], itemCount: 3, discount: 10.00, }, // Monetary value for revenue attribution value: 99.97, time: new Date().toISOString(), uniqueId: 'ORD-12345', // Deduplication key }, }, }); // Track a custom event (triggers flows listening for this metric) await eventsApi.createEvent({ data: { type: EventEnum.Event, attributes: { metric: { data: { type: 'metric', attributes: { name: 'Started Checkout' } }, }, profile: { data: { type: ProfileEnum.Profile, attributes: { email: 'customer@example.com' } }, }, properties: { cartValue: 149.97, cartUrl: 'https://shop.example.com/cart/abc123', items: ['Widget x2', 'Gadget x1'], }, value: 149.97, time: new Date().toISOString(), }, }, });
Step 2: Query Events and Metrics
const metricsApi = new MetricsApi(session); // List all metrics (event types) in your account const metrics = await metricsApi.getMetrics(); for (const m of metrics.body.data) { console.log(`${m.attributes.name} (${m.id})`); } // Get recent events sorted by newest first const events = await eventsApi.getEvents({ sort: '-datetime', filter: 'equals(metric_id,"METRIC_ID_HERE")', }); for (const event of events.body.data) { console.log(`${event.attributes.datetime}: ${event.attributes.eventProperties?.orderId}`); }
Step 3: Work with Segments
import { SegmentsApi } from 'klaviyo-api'; const segmentsApi = new SegmentsApi(session); // List all segments const segments = await segmentsApi.getSegments(); for (const seg of segments.body.data) { console.log(`${seg.attributes.name} (${seg.id}) - active: ${seg.attributes.isActive}`); } // Get profiles in a segment const segmentProfiles = await segmentsApi.getSegmentProfiles({ id: 'SEGMENT_ID', }); for (const profile of segmentProfiles.body.data) { console.log(profile.attributes.email); } // Check segment size (useful before campaign sends) const segmentWithCount = await segmentsApi.getSegment({ id: 'SEGMENT_ID', additionalFieldsSegment: ['profile_count'], }); console.log(`Segment size: ${segmentWithCount.body.data.attributes.profileCount}`);
Step 4: Create an Email Campaign
import { CampaignsApi, CampaignEnum, TemplatesApi } from 'klaviyo-api'; const campaignsApi = new CampaignsApi(session); const templatesApi = new TemplatesApi(session); // 1. Create an email template const template = await templatesApi.createTemplate({ data: { type: 'template', attributes: { name: 'Weekly Sale Announcement', editorType: 'CODE', html: ` <html> <body> <h1>Hey {{ first_name|default:"there" }}!</h1> <p>Check out our weekly deals.</p> <a href="{{ url }}">Shop Now</a> {% unsubscribe %}Unsubscribe{% endunsubscribe %} </body> </html> `, }, }, }); // 2. Create a campaign targeting a list or segment const campaign = await campaignsApi.createCampaign({ data: { type: CampaignEnum.Campaign, attributes: { name: 'Weekly Sale - March 2025', channel: 'email', audiences: { included: [{ type: 'segment', id: 'SEGMENT_ID' }], excluded: [{ type: 'list', id: 'SUPPRESSION_LIST_ID' }], }, sendOptions: { useSmartSending: true, // Skip recently emailed contacts }, }, }, }); const campaignId = campaign.body.data.id; // 3. Assign template to campaign message const messages = await campaignsApi.getCampaignCampaignMessages({ id: campaignId }); const messageId = messages.body.data[0].id; await campaignsApi.assignTemplateToCampaignMessage({ id: messageId, body: { data: { type: 'template', id: template.body.data.id, }, }, }); // 4. Send the campaign (or schedule) await campaignsApi.createCampaignSendJob({ data: { type: 'campaign-send-job', id: campaignId, }, }); console.log('Campaign queued for sending');
Step 5: Query Flows (Read-Only)
import { FlowsApi } from 'klaviyo-api'; const flowsApi = new FlowsApi(session); // List all flows const flows = await flowsApi.getFlows(); for (const flow of flows.body.data) { console.log(`${flow.attributes.name} - status: ${flow.attributes.status}`); } // Get flow actions (the steps in a flow) const flowActions = await flowsApi.getFlowFlowActions({ id: 'FLOW_ID' }); for (const action of flowActions.body.data) { console.log(` Action: ${action.attributes.actionType} - ${action.attributes.status}`); }
Common Event Names for Flow Triggers
| Event Name | Typical Trigger | Flow Type |
|---|---|---|
| Purchase completed | Post-purchase / cross-sell |
| Cart created | Abandoned cart |
| Product page visit | Browse abandonment |
| Per-item tracking | Product review request |
| Shipment sent | Shipping confirmation |
| Order cancelled | Win-back |
| Email/SMS signup | Welcome series |
| Any API event | Custom automation |
Error Handling
| Error | Status | Cause | Solution |
|---|---|---|---|
| Invalid metric name | 400 | Empty or null metric | Always include |
| Segment not found | 404 | Wrong segment ID | List segments with |
| Campaign send failed | 400 | Missing template/audience | Assign template and set audience first |
| Duplicate event | N/A | Same | Deduplication built-in; safe to retry |
Resources
Next Steps
For common errors, see
klaviyo-common-errors.