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)
| Test | Approach |
|---|---|
createDraftCampaign() creates campaign then assigns template | Mock axios.post; assert called twice in correct order |
createDraftCampaign() returns campaignId and editUrl | Mock first response { data: { id: 'abc' } }; assert URL |
getLists() maps list data correctly | Mock { data: [{ id: '1', attributes: { name: 'All' } }] } |
verify() throws when data array empty | Mock { data: [] }; assert throws |
Sends revision header | Assert revision: '2024-02-15' in all requests |
| Throws on 401 (invalid private key) | Mock 401; assert propagated |
Related
- Mailchimp Provider — alternative for non-e-commerce tenants
- Email Writer Agent — generates campaign copy
- Tool Integration Layer — integration management