Skip to Content
ProvidersKlaviyo

Klaviyo

Category: Email Marketing
Integration type: Tenant API key (stored in integrations table)
External API: Klaviyo REST API v2024-02-15


Purpose

Klaviyo is the preferred email marketing platform for e-commerce tenants — those running Shopify, WooCommerce, or other online stores. The Email Writer agent can push generated email copy into Klaviyo as a draft campaign, similar to the Mailchimp integration.

Klaviyo is chosen over Mailchimp for e-commerce tenants because:

  • Deep Shopify/WooCommerce integration (built-in behavioural triggers)
  • Revenue attribution per email campaign
  • Advanced segmentation based on purchase history

Config Structure

Tenant integration

interface KlaviyoConfig { privateKey: string; // Klaviyo private API key (starts with "pk_") companyId?: string; // Optional — for display in UI only }

Klaviyo uses the private API key for all server-side calls. The public key (starts with pk_) is for client-side tracking and is not stored in the platform.


Integration Pattern

Tool layer (packages/tools/src/klaviyo.ts)

class KlaviyoTool { private baseUrl = 'https://a.klaviyo.com/api'; private revision = '2024-02-15'; constructor(private privateKey: string) {} private headers() { return { Authorization: `Klaviyo-API-Key ${this.privateKey}`, Accept: 'application/json', 'Content-Type': 'application/json', revision: this.revision, }; } async createDraftCampaign(options: { listId: string; // Klaviyo list ID subject: string; previewText: string; fromEmail: string; fromName: string; htmlContent: string; name: string; // Internal campaign name }): Promise<{ campaignId: string; editUrl: string }> { // Step 1: Create the campaign const campaignResponse = await axios.post( `${this.baseUrl}/campaigns/`, { data: { type: 'campaign', attributes: { name: options.name, audiences: { included: [options.listId] }, send_options: { use_smart_sending: true }, tracking_options: { is_tracking_clicks: true, is_tracking_opens: true }, send_strategy: { method: 'immediate' }, }, }, }, { headers: this.headers() }, ); const campaignId = campaignResponse.data.data.id; // Step 2: Create the message template const templateResponse = await axios.post( `${this.baseUrl}/campaign-message-assign-template/`, { data: { type: 'campaign-message-assign-template', attributes: { campaign_id: campaignId, html: options.htmlContent, subject: options.subject, preview_text: options.previewText, from_email: options.fromEmail, from_name: options.fromName, }, }, }, { headers: this.headers() }, ); return { campaignId, editUrl: `https://www.klaviyo.com/campaign/${campaignId}/edit`, }; } async getLists(): Promise<{ id: string; name: string }[]> { const response = await axios.get(`${this.baseUrl}/lists/`, { headers: this.headers(), params: { 'fields[list]': 'name' }, }); return response.data.data.map((list: any) => ({ id: list.id, name: list.attributes.name, })); } async verify(): Promise<void> { // Fetch account metadata to verify key const response = await axios.get(`${this.baseUrl}/accounts/`, { headers: this.headers(), }); if (!response.data.data?.length) { throw new Error('Klaviyo verification failed — no account found for this API key'); } } }

Klaviyo vs Mailchimp — which to suggest

The onboarding wizard asks tenants which email platform they use. If they select Klaviyo, the Klaviyo integration is shown; if Mailchimp, the Mailchimp integration. If neither, the tenant is guided to SendGrid for notification-only email.


Test Cases

Unit tests (packages/tools/src/klaviyo.test.ts)

TestApproach
createDraftCampaign() creates campaign then assigns templateMock axios.post; assert called twice in correct order
createDraftCampaign() returns campaignId and editUrlMock first response { data: { id: 'abc' } }; assert URL
getLists() maps list data correctlyMock { data: [{ id: '1', attributes: { name: 'All' } }] }
verify() throws when data array emptyMock { data: [] }; assert throws
Sends revision headerAssert revision: '2024-02-15' in all requests
Throws on 401 (invalid private key)Mock 401; assert propagated

© 2026 Leadmetrics — Internal use only