Klaviyo Cost Tuning
Overview
Optimize Klaviyo costs through active profile management, list hygiene, event sampling, and API usage monitoring. Klaviyo bills primarily by active profiles and message volume, not API calls.
Prerequisites
- Access to Klaviyo billing dashboard
- Understanding of active profile definition
klaviyo-api SDK for programmatic management
Klaviyo Pricing Model
Klaviyo bills based on active profiles (contacts who have received or been targeted by marketing), not API requests.
| Component |
How It's Billed |
Cost Driver |
| Email |
Per active profile tier |
Number of marketable profiles |
| SMS |
Per message sent + carrier fees |
Message volume |
| Push |
Included with email plan |
N/A |
| API calls |
Free (rate limited, not billed) |
N/A |
| Reviews |
Per request volume |
Review request sends |
Email Pricing Tiers (Approximate)
| Active Profiles |
Monthly Cost |
| 0 - 250 |
Free |
| 251 - 500 |
$20/mo |
| 501 - 1,000 |
$30/mo |
| 1,001 - 1,500 |
$45/mo |
| 1,501 - 5,000 |
$60-$100/mo |
| 5,001 - 10,000 |
$100-$150/mo |
| 10,001 - 25,000 |
$150-$375/mo |
| 25,001+ |
Custom pricing |
Key insight: Reducing active profiles has the biggest cost impact. Cleaning suppressed/unengaged contacts directly reduces your bill.
Instructions
Work the levers in order — active-profile reduction has the largest impact, so start
there before touching event sampling or API monitoring. Each step maps to a klaviyo-api
routine in the full walkthrough; the complete five-step implementation
carries the runnable code for every step, and worked examples show
the dollar impact of each.
- Audit active profile count — page through
ProfilesApi.getProfiles with a minimal
fieldset to establish the current tier. Skeleton below.
- Identify unengaged profiles — query an "Unengaged 180+ Days" segment via
SegmentsApi.
- Suppress unengaged contacts — unsubscribe (stays but unmarketable = not billed) or
add a global suppression property. This is what actually lowers the bill.
- Sample non-critical events — keep revenue events at 100%, sample high-volume/low-value
events (
Viewed Product, Page View) to cut ingestion.
- Monitor API usage — wrap SDK calls in a rate tracker to catch runaway processes before
they trip the 700 req/min limit.
Establish a session once, then run the audit (Step 1):
import { ApiKeySession, ProfilesApi, SegmentsApi } from 'klaviyo-api';
const session = new ApiKeySession(process.env.KLAVIYO_PRIVATE_KEY!);
const profilesApi = new ProfilesApi(session);
// Count total profiles (paginate with page[cursor])
let totalProfiles = 0;
let cursor: string | undefined;
do {
const response = await profilesApi.getProfiles({
pageCursor: cursor,
fieldsProfile: ['email'], // Minimal fields for speed
});
totalProfiles += response.body.data.length;
const nextLink = response.body.links?.next;
cursor = nextLink ? new URL(nextLink).searchParams.get('page[cursor]') || undefined : undefined;
} while (cursor);
console.log(`Total profiles: ${totalProfiles}`);
Steps 2–5 (segment query, suppression job, event sampling, usage tracker) live in the
full implementation walkthrough.
Output
Applying this skill produces:
- A current active-profile count and the pricing tier it falls into (see the tables above).
- A list of unengaged profiles (180+ days no open/click) eligible for suppression.
- A suppression run — profiles unsubscribed or globally suppressed, lowering the billed
active count (often enough to drop a tier).
- An event-sampling config that keeps revenue-critical events at 100% while sampling noise.
- A
KlaviyoUsageTracker emitting [Klaviyo] High API rate: N req/min warnings before the
700 req/min steady limit is reached.
Examples
- Drop a pricing tier: suppressing 3,100 unengaged profiles takes an account from 12,400 to
9,300 active profiles, moving it from the 10,001–25,000 tier down to 5,001–10,000.
- Cut SMS spend: gating the abandoned-cart flow on an engaged-only segment stops full-list
texting and its per-message carrier charges.
- Sample noisy events: a 0.25/0.10 sample on
Viewed Product/Page View cuts ingestion of
those events ~75–90% with no loss to revenue attribution.
See references/examples.md for the full before/after figures and code
for each scenario.
Cost Reduction Checklist
Error Handling
| Issue |
Cause |
Solution |
| Unexpected bill increase |
Unengaged profiles grew |
Run suppression script |
| SMS costs spiking |
Flow sending to full list |
Add engaged-only segment filter |
| Duplicate profiles |
Multiple identify calls |
Merge duplicates, use createOrUpdateProfile |
| API rate limits hit |
Bulk operations |
Use queue with concurrency control |
Resources
- Full implementation walkthrough — runnable code for all five steps
- Worked examples — before/after cost scenarios
- Klaviyo Pricing
- Data Privacy API
- For architecture patterns, see the
klaviyo-reference-architecture skill in this pack.
Source: jeremylongshore/claude-code-plugins-plus-skills → plugins/saas-packs/klaviyo-pack/skills/klaviyo-cost-tuning/SKILL.md
1---2name: klaviyo-cost-tuning3description: "'Optimize Klaviyo costs through plan selection, contact management, and usage monitoring. Use when analyzing Klaviyo billing, reducing active profile costs, or implementing usage monitoring and budget alerts. Trigger with phrases like \"klaviyo cost\", \"klaviyo billing\", \"reduce klaviyo costs\", \"klaviyo pricing\", \"klaviyo expensive\", \"klaviyo budget\". '"4allowed-tools: "Read, Write, Edit, Grep"5category: business-and-finance6source_repo: jeremylongshore/claude-code-plugins-plus-skills7source_path: "plugins/saas-packs/klaviyo-pack/skills/klaviyo-cost-tuning/SKILL.md"8source_url: https://github.com/jeremylongshore/claude-code-plugins-plus-skills/blob/HEAD/plugins/saas-packs/klaviyo-pack/skills/klaviyo-cost-tuning/SKILL.md9---1011# Klaviyo Cost Tuning1213## Overview1415Optimize Klaviyo costs through active profile management, list hygiene, event sampling, and API usage monitoring. Klaviyo bills primarily by **active profiles** and **message volume**, not API calls.1617## Prerequisites1819- Access to Klaviyo billing dashboard20- Understanding of active profile definition21- `klaviyo-api` SDK for programmatic management2223## Klaviyo Pricing Model2425Klaviyo bills based on **active profiles** (contacts who have received or been targeted by marketing), not API requests.2627| Component | How It's Billed | Cost Driver |28|-----------|----------------|-------------|29| Email | Per active profile tier | Number of marketable profiles |30| SMS | Per message sent + carrier fees | Message volume |31| Push | Included with email plan | N/A |32| API calls | Free (rate limited, not billed) | N/A |33| Reviews | Per request volume | Review request sends |3435### Email Pricing Tiers (Approximate)3637| Active Profiles | Monthly Cost |38|----------------|-------------|39| 0 - 250 | Free |40| 251 - 500 | $20/mo |41| 501 - 1,000 | $30/mo |42| 1,001 - 1,500 | $45/mo |43| 1,501 - 5,000 | $60-$100/mo |44| 5,001 - 10,000 | $100-$150/mo |45| 10,001 - 25,000 | $150-$375/mo |46| 25,001+ | Custom pricing |4748> **Key insight:** Reducing **active profiles** has the biggest cost impact. Cleaning suppressed/unengaged contacts directly reduces your bill.4950## Instructions5152Work the levers in order — active-profile reduction has the largest impact, so start53there before touching event sampling or API monitoring. Each step maps to a `klaviyo-api`54routine in the full walkthrough; the [complete five-step implementation](references/implementation.md)55carries the runnable code for every step, and [worked examples](references/examples.md) show56the dollar impact of each.57581. **Audit active profile count** — page through `ProfilesApi.getProfiles` with a minimal59 fieldset to establish the current tier. Skeleton below.602. **Identify unengaged profiles** — query an "Unengaged 180+ Days" segment via `SegmentsApi`.613. **Suppress unengaged contacts** — unsubscribe (stays but unmarketable = not billed) or62 add a global suppression property. This is what actually lowers the bill.634. **Sample non-critical events** — keep revenue events at 100%, sample high-volume/low-value64 events (`Viewed Product`, `Page View`) to cut ingestion.655. **Monitor API usage** — wrap SDK calls in a rate tracker to catch runaway processes before66 they trip the 700 req/min limit.6768Establish a session once, then run the audit (Step 1):6970```typescript71import { ApiKeySession, ProfilesApi, SegmentsApi } from 'klaviyo-api';7273const session = new ApiKeySession(process.env.KLAVIYO_PRIVATE_KEY!);74const profilesApi = new ProfilesApi(session);7576// Count total profiles (paginate with page[cursor])77let totalProfiles = 0;78let cursor: string | undefined;79do {80 const response = await profilesApi.getProfiles({81 pageCursor: cursor,82 fieldsProfile: ['email'], // Minimal fields for speed83 });84 totalProfiles += response.body.data.length;85 const nextLink = response.body.links?.next;86 cursor = nextLink ? new URL(nextLink).searchParams.get('page[cursor]') || undefined : undefined;87} while (cursor);8889console.log(`Total profiles: ${totalProfiles}`);90```9192Steps 2–5 (segment query, suppression job, event sampling, usage tracker) live in the93[full implementation walkthrough](references/implementation.md).9495## Output9697Applying this skill produces:9899- **A current active-profile count** and the pricing tier it falls into (see the tables above).100- **A list of unengaged profiles** (180+ days no open/click) eligible for suppression.101- **A suppression run** — profiles unsubscribed or globally suppressed, lowering the billed102 active count (often enough to drop a tier).103- **An event-sampling config** that keeps revenue-critical events at 100% while sampling noise.104- **A `KlaviyoUsageTracker`** emitting `[Klaviyo] High API rate: N req/min` warnings before the105 700 req/min steady limit is reached.106107## Examples108109- **Drop a pricing tier:** suppressing 3,100 unengaged profiles takes an account from 12,400 to110 9,300 active profiles, moving it from the 10,001–25,000 tier down to 5,001–10,000.111- **Cut SMS spend:** gating the abandoned-cart flow on an engaged-only segment stops full-list112 texting and its per-message carrier charges.113- **Sample noisy events:** a 0.25/0.10 sample on `Viewed Product`/`Page View` cuts ingestion of114 those events ~75–90% with no loss to revenue attribution.115116See [references/examples.md](references/examples.md) for the full before/after figures and code117for each scenario.118119## Cost Reduction Checklist120121- [ ] Suppress profiles unengaged >180 days122- [ ] Remove hard-bounced email addresses123- [ ] Audit and merge duplicate profiles124- [ ] Use double opt-in to reduce fake signups125- [ ] Sample high-volume, low-value events126- [ ] Batch API calls instead of individual requests127- [ ] Cache frequently-read data (segments, lists)128- [ ] Use sparse fieldsets to reduce transfer size129- [ ] Review SMS sending -- highest per-message cost130- [ ] Set up sunset flow (auto-suppress after N days unengaged)131132## Error Handling133134| Issue | Cause | Solution |135|-------|-------|----------|136| Unexpected bill increase | Unengaged profiles grew | Run suppression script |137| SMS costs spiking | Flow sending to full list | Add engaged-only segment filter |138| Duplicate profiles | Multiple identify calls | Merge duplicates, use `createOrUpdateProfile` |139| API rate limits hit | Bulk operations | Use queue with concurrency control |140141## Resources142143- [Full implementation walkthrough](references/implementation.md) — runnable code for all five steps144- [Worked examples](references/examples.md) — before/after cost scenarios145- [Klaviyo Pricing](https://www.klaviyo.com/pricing)146- [Data Privacy API](https://developers.klaviyo.com/en/reference/data_privacy_api_overview)147- For architecture patterns, see the `klaviyo-reference-architecture` skill in this pack.148149---150151**Source:** [`jeremylongshore/claude-code-plugins-plus-skills`](https://github.com/jeremylongshore/claude-code-plugins-plus-skills) → `plugins/saas-packs/klaviyo-pack/skills/klaviyo-cost-tuning/SKILL.md`