name: klaviyo-prod-checklist description: 'Execute Klaviyo production deployment checklist and validation procedures.
Use when deploying Klaviyo integrations to production, preparing for launch,
or implementing go-live procedures for email/SMS marketing.
Trigger with phrases like "klaviyo production", "deploy klaviyo",
"klaviyo go-live", "klaviyo launch checklist", "klaviyo prod ready".
' allowed-tools: Read, Bash(curl:), Bash(npm:), Grep version: 1.0.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:
- saas
- klaviyo
- email-marketing
- cdp compatibility: Designed for Claude Code
Klaviyo Production Checklist
Overview
Complete checklist for deploying Klaviyo integrations to production, with health checks, rollback procedures, and validation against real Klaviyo API endpoints.
Prerequisites
- Staging environment tested and verified
- Production API key with correct scopes (
pk_*) - Webhook signing secret configured
- Monitoring and alerting ready
Instructions
Pre-Deployment Checklist
Authentication & Secrets
- Production
KLAVIYO_PRIVATE_KEYstored in secret manager (not env file) - Key has minimal scopes (only what the app needs)
- Webhook signing secret (
KLAVIYO_WEBHOOK_SIGNING_SECRET) configured - Public key (
KLAVIYO_PUBLIC_KEY) set for client-side tracking (if used) - No hardcoded keys in codebase (
grep -r "pk_" src/)
API Integration
- All API calls use
klaviyo-apiSDK (not raw HTTP) - SDK version pinned in
package.json(not^or*) -
revisionheader set to2024-10-15(or current supported revision) - All profile creates use
createOrUpdateProfile(upsert, not create) - Events include
uniqueIdfor deduplication where applicable - Phone numbers validated as E.164 format (
+15551234567)
Error Handling & Resilience
- 429 retry logic honors
Retry-Afterheader - 5xx errors retried with exponential backoff
- 401/403 errors logged with alert (key rotation needed)
- Circuit breaker or graceful degradation when Klaviyo is down
- Request queue prevents exceeding 75 req/s burst limit
Webhook Security
- Webhook endpoint uses HTTPS only
- HMAC-SHA256 signature verification enabled
- Idempotency handling (dedup by event ID)
- Webhook endpoint returns 200 within 30 seconds
Monitoring
- Health check endpoint includes Klaviyo connectivity test
- Alert on 429 rate (>5/min = P2)
- Alert on 401/403 errors (any = P1)
- Alert on 5xx errors (>10/min = P1)
- API latency tracked (P95 > 5s = P2)
- Klaviyo status page monitored (status.klaviyo.com)
Health Check Implementation
// src/health/klaviyo.ts
import { ApiKeySession, AccountsApi } from 'klaviyo-api';
export async function checkKlaviyoHealth(): Promise<{
status: 'healthy' | 'degraded' | 'down';
latencyMs: number;
accountId?: string;
error?: string;
}> {
const start = Date.now();
try {
const session = new ApiKeySession(process.env.KLAVIYO_PRIVATE_KEY!);
const accountsApi = new AccountsApi(session);
const result = await accountsApi.getAccounts();
return {
status: 'healthy',
latencyMs: Date.now() - start,
accountId: result.body.data[0].id,
};
} catch (error: any) {
return {
status: error.status === 429 ? 'degraded' : 'down',
latencyMs: Date.now() - start,
error: `${error.status}: ${error.body?.errors?.[0]?.detail || error.message}`,
};
}
}
// Express health endpoint
app.get('/health', async (req, res) => {
const klaviyo = await checkKlaviyoHealth();
const overallStatus = klaviyo.status === 'healthy' ? 200 : 503;
res.status(overallStatus).json({
status: klaviyo.status,
services: { klaviyo },
timestamp: new Date().toISOString(),
});
});
Pre-Flight Validation Script
#!/bin/bash
# scripts/preflight-klaviyo.sh
set -euo pipefail
echo "=== Klaviyo Production Pre-Flight ==="
# 1. Check Klaviyo status
echo -n "Klaviyo Status Page: "
STATUS=$(curl -s "https://status.klaviyo.com/api/v2/status.json" | python3 -c "import sys,json; print(json.load(sys.stdin)['status']['description'])" 2>/dev/null)
echo "$STATUS"
[ "$STATUS" = "All Systems Operational" ] || echo "WARNING: Klaviyo has active incidents"
# 2. Verify API key
echo -n "API Auth: "
HTTP_CODE=$(curl -s -w "%{http_code}" -o /dev/null \
-H "Authorization: Klaviyo-API-Key $KLAVIYO_PRIVATE_KEY" \
-H "revision: 2024-10-15" \
"https://a.klaviyo.com/api/accounts/")
echo "HTTP $HTTP_CODE"
[ "$HTTP_CODE" = "200" ] || { echo "FAIL: API auth returned $HTTP_CODE"; exit 1; }
# 3. Check rate limit headroom
echo -n "Rate Limit: "
curl -s -I \
-H "Authorization: Klaviyo-API-Key $KLAVIYO_PRIVATE_KEY" \
-H "revision: 2024-10-15" \
"https://a.klaviyo.com/api/profiles/?page[size]=1" 2>/dev/null \
| grep -i "ratelimit-remaining" || echo "Headers not available"
# 4. Verify SDK version
echo -n "SDK Version: "
node -e "console.log(require('klaviyo-api/package.json').version)" 2>/dev/null || echo "Not installed"
echo ""
echo "=== Pre-flight complete ==="
Rollback Procedure
# Immediate rollback: disable Klaviyo integration
# Option 1: Feature flag (preferred)
# Set KLAVIYO_ENABLED=false in your deployment platform
# Option 2: Deploy previous version
git log --oneline -5 # Find last known-good commit
git revert HEAD # Revert the deployment commit
# Push and deploy
# Option 3: If using Kubernetes
kubectl rollout undo deployment/your-app
kubectl rollout status deployment/your-app
Alert Thresholds
| Alert | Condition | Severity |
|---|---|---|
| API Auth Failure | Any 401/403 | P1 -- key may be revoked |
| API Unreachable | 5xx > 10/min | P1 -- check status page |
| Rate Limited | 429 > 5/min | P2 -- reduce request volume |
| High Latency | P95 > 5s | P2 -- check network/Klaviyo load |
| Webhook Signature Invalid | Any rejection | P2 -- verify signing secret |
Resources
Next Steps
For version upgrades, see klaviyo-upgrade-migration.