Overview of the Campaigns API introduced in revision 2026-04-15, covering multi-channel campaigns across email, SMS, push, and WhatsApp.
Before you begin
Check out our general API overview to make sure you're ready to get started with specific endpoints.
The Campaigns API (revision
2026-04-15) is currently in Beta.All endpoints in this overview require the
revision: 2026-04-15.preheader. The GA revision is planned for 2026-07-15. Endpoint paths and request/response shapes may change before GA.For campaigns using older revisions, see the Campaigns API overview.
Starting with revision 2026-04-15, a campaign can send across email, SMS, push, and WhatsApp using a structured hierarchy of audiences, messages, and variations. Unlike earlier revisions — where each campaign targeted a single channel — the revised API lets you coordinate multiple channels and content variations within a single campaign.
The Campaigns API is organized into five endpoint groups:
- Campaigns — Create, retrieve, update, delete, and clone campaigns.
- Campaign Audiences — Manage targeted audience segments within a campaign, with priority ordering.
- Campaign Messages — Configure and schedule individual sends within an audience.
- Campaign Variations — Define per-channel content (email, SMS, push, WhatsApp) for each message.
- Scheduling — Schedule all messages at once or individually, with support for multiple send strategies.
Use cases
The Campaigns API supports a number of use cases, including:
- Create and send a multi-channel campaign (e.g., email + SMS in a single campaign).
- Set up content variations per channel (email, SMS, push, WhatsApp) within a single message.
- Schedule messages with different strategies — static time, local timezone, or throttled rollout.
- Clone an existing campaign or individual messages and audiences to reuse configurations.
- Manage targeted audience segments with priority ordering to control recipient overlap.
Campaigns will not be sent to profiles who have not provided consent (implicit for email and explicit for SMS). Learn about best practices for collecting email and SMS consent.
Resource hierarchy
The Campaigns API uses a four-level resource hierarchy:
campaign
└── campaign-audience (1..N)
└── campaign-message (1..N per audience)
└── campaign-variation (1..N per message, one per channel)
- Campaign — The top-level container. Holds campaign-level defaults for send timezone, send strategy, and exit conditions; individual messages can override these settings.
- Campaign audience — A targeting configuration within the campaign. Each audience has a priority used for ordering within the canvas UI. A campaign must have at least one audience.
- Campaign message — A scheduled send within an audience. Messages progress through a lifecycle from draft to sent. Each audience can contain multiple messages.
- Campaign variation — The channel-specific content for a message. Each message targets exactly one channel (email, SMS, push, or WhatsApp) via a single variation. A campaign can have multiple messages targeting different channels.
Data model
Campaign
A campaign is the top-level resource. It contains shared send settings and references its child audiences, messages, and tags.
id(string) — The campaign ID (26-character ULID).type(string) — Always"campaign".attributes.definition.name(string) — The campaign name.attributes.definition.builder(string) — The builder type used to create the campaign ("wizard"or"canvas").attributes.definition.archived(boolean) — Whether the campaign is archived.attributes.definition.color(string) — Optional color label for the campaign.attributes.definition.description(string) — Optional description.attributes.definition.send_settings(object) — Shared send settings:send_timezone(string) — IANA timezone string (e.g.,"America/New_York").send_strategy(string) — The send strategy for messages ("STATIC","LOCAL_TIMEZONE","THROTTLED").send_passed_rltz_immediately(boolean) — When usingLOCAL_TIMEZONE, whether to send immediately to timezones where the scheduled local time has already passed.throttle_percentage(integer) — The percentage of recipients to send to per hour whensend_strategyis"THROTTLED". Valid values:10,11,13,14,17,20,25,33,50. Not applicable for other send strategies.exit_condition_enabled(boolean) — Whether exit conditions are active.exit_condition_conversion_metric_id(string|null) — The metric ID used for exit condition evaluation.
attributes.created_at(string) — ISO 8601 timestamp.attributes.updated_at(string) — ISO 8601 timestamp.relationships.campaign-audiences— Related audience resources.relationships.campaign-messages— Related message resources.relationships.tags— Related tag resources.
{
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789",
"attributes": {
"definition": {
"name": "Summer Sale 2026",
"builder": "wizard",
"archived": false,
"color": "#4A90D9",
"description": "Multi-channel summer promotion",
"send_settings": {
"send_timezone": "America/New_York",
"send_strategy": "STATIC",
"send_passed_rltz_immediately": false,
"exit_condition_enabled": false,
"exit_condition_conversion_metric_id": null
}
},
"created_at": "2026-04-14T12:00:00.000000+00:00",
"updated_at": "2026-04-14T12:05:00.000000+00:00"
},
"relationships": {
"campaign-audiences": {
"data": [
{
"type": "campaign-audience",
"id": "01JXYZ1234ABCDEFGHIJK00001"
}
],
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/relationships/campaign-audiences/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/campaign-audiences/"
}
},
"campaign-messages": {
"data": [
{
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010"
}
],
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/relationships/campaign-messages/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/campaign-messages/"
}
},
"tags": {
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/relationships/tags/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/tags/"
}
}
},
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/"
}
}
}
Campaign audience
A campaign audience defines which lists or segments receive messages within a campaign.
id(string) — The audience ID.type(string) — Always"campaign-audience".attributes.audience_name(string) — Display name for this audience.attributes.priority(integer) — Canvas UI ordering position (0-based). Not used for recipient overlap resolution.attributes.has_non_draft_messages(boolean) — Whether this audience has any non-draft messages. Audiences where this istruecannot be updated or deleted.attributes.included(array of strings) — IDs of the lists or segments to include.attributes.excluded(array of strings) — IDs of the lists or segments to exclude.attributes.created_at(string) — ISO 8601 creation timestamp.attributes.updated_at(string) — ISO 8601 last-updated timestamp.relationships.campaign— The parent campaign.relationships.campaign-messages— Messages associated with this audience.
Audiences that contain non-draft messages cannot be updated or deleted. Cancel or revert the audience's messages to draft before making changes.
{
"data": {
"type": "campaign-audience",
"id": "01JXYZ1234ABCDEFGHIJK00001",
"attributes": {
"audience_name": "Audience 1",
"priority": 0,
"has_non_draft_messages": false,
"included": ["LIST_OR_SEGMENT_ID_1"],
"excluded": [],
"archived": false,
"created_at": "2026-04-14T00:00:00.000000+00:00",
"updated_at": "2026-04-14T00:00:00.000000+00:00"
},
"relationships": {
"campaign": {
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789"
}
},
"campaign-messages": {
"data": [
{
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010"
}
]
}
},
"links": {
"self": "https://a.klaviyo.com/api/campaign-audiences/01JXYZ1234ABCDEFGHIJK00001/"
}
}
}
Campaign message
A campaign message represents a scheduled send within an audience. Messages progress through a defined lifecycle as they are scheduled and sent.
id(string) — The message ID.type(string) — Always"campaign-message".attributes.name(string) — The message name.attributes.status(string) — The current lifecycle state.attributes.created(string) — ISO 8601 creation timestamp.attributes.updated(string) — ISO 8601 last-updated timestamp.attributes.definition(object|null) — The full message definition, including tracking settings.attributes.scheduling_info(object|null) — Scheduling information (send time, strategy). Null for DRAFT messages.attributes.tracking_params(array|null) — The UTM tracking parameters configured for this message. Read-only.relationships.campaign— The parent campaign.relationships.campaign-audience— The audience this message belongs to.relationships.campaign-variations— Variations (per-channel content) for this message.
Message lifecycle states:
| State | Description |
|---|---|
DRAFT | Initial state. The message can be edited and configured. |
SCHEDULED | The message is queued and will send at the configured send time. |
SENDING | The message is actively being delivered. |
SENT | Delivery is complete. |
CANCELLED | The message was cancelled. Can be reached from DRAFT, SCHEDULED, or SENDING. |
{
"data": {
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010",
"attributes": {
"name": "Summer sale email",
"status": "DRAFT",
"created": "2026-04-14T00:00:00.000000+00:00",
"updated": "2026-04-14T00:00:00.000000+00:00",
"definition": null,
"scheduling_info": null,
"tracking_params": null
},
"relationships": {
"campaign": {
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789"
}
},
"campaign-audience": {
"data": {
"type": "campaign-audience",
"id": "01JXYZ1234ABCDEFGHIJK00001"
}
},
"campaign-variations": {
"data": [
{
"type": "campaign-variation",
"id": "01JXYZ1234ABCDEFGHIJK00100"
}
]
}
},
"links": {
"self": "https://a.klaviyo.com/api/campaign-messages/01JXYZ1234ABCDEFGHIJK00010/"
}
}
}
Campaign variation
A campaign variation holds the per-channel content for a message. Each variation targets exactly one channel, and a message can have at most one variation per channel.
Variations hold the channel-specific content for a message. Each message targets a single channel via one variation.
id(string) — The variation ID.type(string) — Always"campaign-variation".attributes.created(string) — ISO 8601 creation timestamp.attributes.updated(string) — ISO 8601 last-updated timestamp.attributes.definition.name(string|null) — Optional display name for the variation.attributes.definition.details(object|null) — Channel-specific content. Thechannelfield insidedetailsdetermines which channel this variation targets.relationships.campaign-message— The parent message.
Channel-specific details fields:
For email ("channel": "email"):
template_id(string|null) — ID of the Klaviyo email template.subject(string) — Email subject line.preview_text(string) — Preview text shown in email clients.from_email(string) — Sender email address.from_label(string) — Sender display name.reply_to_email(string) — Reply-to address.cc_email(string) — CC address.bcc_email(string) — BCC address.
For SMS ("channel": "sms"):
template_id(string|null) — ID of the SMS template.body(string) — SMS message body text.shorten_links(boolean|null) — Whether to shorten links in the message.include_contact_card(boolean|null) — Whether to include a contact card.
For push ("channel": "push"):
title(string) — Push notification title.body(string) — Push notification body text.static_asset_id(integer|null) — Static image asset ID.ios_deep_link(string|null) — Deep link URL for iOS.android_deep_link(string|null) — Deep link URL for Android.sound(boolean) — Whether to play a sound.badge(boolean) — Whether to show a badge.
For WhatsApp ("channel": "whatsapp"):
template_id(string|null) — ID of the WhatsApp template.shorten_links(boolean) — Whether to shorten links in the message.
Each message targets a single channel. To reach recipients on multiple channels, create separate messages (each with its own variation) within the same audience.
{
"data": {
"type": "campaign-variation",
"id": "01JXYZ1234ABCDEFGHIJK00100",
"attributes": {
"created": "2026-04-14T00:00:00.000000+00:00",
"updated": "2026-04-14T00:00:00.000000+00:00",
"definition": {
"name": "Email variation",
"details": {
"channel": "email",
"subject": "Summer Sale starts now",
"from_email": "[email protected]",
"from_label": "Example Brand",
"reply_to_email": "",
"cc_email": "",
"bcc_email": "",
"preview_text": "",
"template_id": null
}
}
},
"relationships": {
"campaign-message": {
"data": {
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010"
}
}
},
"links": {
"self": "https://a.klaviyo.com/api/campaign-variations/01JXYZ1234ABCDEFGHIJK00100/"
}
}
}
Create a campaign
Atomic inline creation
The primary way to create a campaign is with a single POST /api/campaigns request that atomically creates the full resource hierarchy — the campaign, its audiences, messages, and variations — in one call.
audiences[]— Each audience must include atemporary_id(a client-generated string used for linking). At least one audience is required.messages[]— Each message references anaudience_temporary_idto associate it with an audience. Messages can include inlinevariations[].- If any child resource fails validation, the entire request is rejected and nothing is persisted.
{
"data": {
"type": "campaign",
"attributes": {
"definition": {
"name": "Summer Sale 2026",
"builder": "wizard",
"send_settings": {
"send_timezone": "America/New_York",
"send_strategy": "STATIC",
"send_passed_rltz_immediately": false,
"exit_condition_enabled": false,
"exit_condition_conversion_metric_id": null
},
},
"audiences": [
{
"temporary_id": "aud_temp_001",
"included": ["LIST_OR_SEGMENT_ID_1"],
"excluded": []
}
],
"messages": [
{
"audience_temporary_id": "aud_temp_001",
"definition": {
"name": "Summer email blast",
"variations": [
{
"definition": {
"name": "Email variation",
"details": {
"channel": "email",
"subject": "Summer Sale starts now",
"from_email": "[email protected]",
"from_label": "Example Brand"
}
}
}
]
}
}
]
}
}
}
curl --request POST \
--url https://a.klaviyo.com/api/campaigns \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'content-type: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre' \
--data @- << 'EOF'
{
"data": {
"type": "campaign",
"attributes": {
"definition": {
"name": "Summer Sale 2026",
"builder": "wizard",
"send_settings": {
"send_timezone": "America/New_York",
"send_strategy": "STATIC",
"send_passed_rltz_immediately": false,
"exit_condition_enabled": false,
"exit_condition_conversion_metric_id": null
}
},
"audiences": [
{
"temporary_id": "aud_temp_001",
"included": ["LIST_OR_SEGMENT_ID_1"],
"excluded": []
}
],
"messages": [
{
"audience_temporary_id": "aud_temp_001",
"definition": {
"name": "Summer email blast",
"variations": [
{
"definition": {
"name": "Email variation",
"details": {
"channel": "email",
"subject": "Summer Sale starts now",
"from_email": "[email protected]",
"from_label": "Example Brand"
}
}
}
]
}
}
]
}
}
}
EOF
{
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789",
"attributes": {
"definition": {
"name": "Summer Sale 2026",
"builder": "wizard",
"archived": false,
"color": null,
"description": null,
"send_settings": {
"send_timezone": "America/New_York",
"send_strategy": "STATIC",
"send_passed_rltz_immediately": false,
"exit_condition_enabled": false,
"exit_condition_conversion_metric_id": null
}
},
"created_at": "2026-04-14T12:00:00.000000+00:00",
"updated_at": "2026-04-14T12:00:00.000000+00:00"
},
"relationships": {
"campaign-audiences": {
"data": [
{
"type": "campaign-audience",
"id": "01JXYZ1234ABCDEFGHIJK00001"
}
],
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/relationships/campaign-audiences/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/campaign-audiences/"
}
},
"campaign-messages": {
"data": [
{
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010"
}
],
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/relationships/campaign-messages/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/campaign-messages/"
}
},
"tags": {
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/relationships/tags/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/tags/"
}
}
},
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/"
}
}
}
Create campaign resources individually
After a campaign exists, you can add audiences, messages, and variations individually using their respective endpoints.
- POST
/api/campaign-audiences— Create a new audience for the campaign. - POST
/api/campaign-messages— Create a new message linked to an audience. - POST
/api/campaign-variations— Create a new variation within a message.
POST /api/campaign-audiences — Create a campaign audience:
{
"data": {
"type": "campaign-audience",
"attributes": {
"included": ["LIST_OR_SEGMENT_ID_2"],
"excluded": []
},
"relationships": {
"campaign": {
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789"
}
}
}
}
}
POST /api/campaign-messages — Create a campaign message:
{
"data": {
"type": "campaign-message",
"attributes": {
"definition": {
"name": "Follow-up SMS"
}
},
"relationships": {
"campaign": {
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789"
}
},
"campaign-audience": {
"data": {
"type": "campaign-audience",
"id": "01JXYZ1234ABCDEFGHIJK00001"
}
}
}
}
}
POST /api/campaign-variations — Create a campaign variation:
{
"data": {
"type": "campaign-variation",
"attributes": {
"definition": {
"name": "Variation SMS 1",
"details": {
"channel": "sms"
}
}
},
"relationships": {
"campaign-message": {
"data": {
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010"
}
}
}
}
}
Update a campaign
Use PATCH requests to update campaign resources while they are in draft.
- PATCH
/api/campaigns/{id}— Update the campaign's name, description, color, send settings, or tracking options. Only fields included in the request body are updated. - PATCH
/api/campaign-audiences/{id}— Update audience priority or group memberships. Audiences with non-draft messages cannot be updated. - PATCH
/api/campaign-messages/{id}— Update message name or configuration. - PATCH
/api/campaign-variations/{id}— Update variation channel-specific attributes (e.g., subject line, body content, template ID).
curl --request PATCH \
--url https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789 \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'content-type: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre' \
--data '
{
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789",
"attributes": {
"definition": {
"name": "Summer Sale 2026 — Updated",
"send_settings": {
"send_strategy": "LOCAL_TIMEZONE",
"send_passed_rltz_immediately": true
}
}
}
}
}
'
Update a campaign audience:
curl --request PATCH \
--url https://a.klaviyo.com/api/campaign-audiences/01JXYZ1234ABCDEFGHIJK00001 \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'content-type: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre' \
--data '
{
"data": {
"type": "campaign-audience",
"id": "01JXYZ1234ABCDEFGHIJK00001",
"attributes": {
"audience_name": "VIP Customers — Updated",
"included": ["LIST_OR_SEGMENT_ID_1", "LIST_OR_SEGMENT_ID_3"],
"excluded": ["LIST_OR_SEGMENT_ID_2"],
"priority": 0
}
}
}
'
Delete campaign resources
- DELETE
/api/campaigns/{id}— Deletes the campaign and cascades to all child audiences, messages, and variations. This is a soft delete (sets thearchivedflag). - DELETE
/api/campaign-audiences/{id}— Deletes the audience and its associated messages and variations. Audiences with non-draft messages cannot be deleted. - DELETE
/api/campaign-messages/{id}— Deletes the message and its variations. - DELETE
/api/campaign-variations/{id}— Deletes a single variation.
Deleting a campaign is a cascading operation. All audiences, messages, and variations under the campaign will be archived. This action cannot be undone.
curl --request DELETE \
--url https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789 \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'revision: 2026-04-15.pre'
Clone a campaign
Cloning creates a complete copy of a campaign (or a sub-resource) in draft status, allowing you to reuse configurations without starting from scratch.
- POST
/api/campaign-clone— Clones the entire campaign hierarchy: all audiences, messages, and variations. The result is a new campaign in draft. - POST
/api/campaign-audience-clone— Copies an audience (and its messages and variations) to a different campaign. - POST
/api/campaign-message-clone— Copies a message (and its variations) to a different audience.
curl --request POST \
--url https://a.klaviyo.com/api/campaign-clone \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'content-type: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre' \
--data '
{
"data": {
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789"
}
}
'
{
"data": {
"type": "campaign",
"id": "01JXYZ9999NEWCAMPAIGNCLONE",
"attributes": {
"definition": {
"name": "Summer Sale 2026 (Copy)",
"builder": "wizard",
"archived": false,
"color": "#4A90D9",
"description": "Multi-channel summer promotion",
"send_settings": {
"send_timezone": "America/New_York",
"send_strategy": "STATIC",
"send_passed_rltz_immediately": false,
"exit_condition_enabled": false,
"exit_condition_conversion_metric_id": null
}
},
"created_at": "2026-04-14T14:00:00.000000+00:00",
"updated_at": "2026-04-14T14:00:00.000000+00:00"
},
"relationships": {
"campaign-audiences": {
"data": [
{
"type": "campaign-audience",
"id": "01JXYZ9999NEWAUDIENCE00001"
}
],
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ9999NEWCAMPAIGNCLONE/relationships/campaign-audiences/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ9999NEWCAMPAIGNCLONE/campaign-audiences/"
}
},
"campaign-messages": {
"data": [
{
"type": "campaign-message",
"id": "01JXYZ9999NEWMESSAGE00010"
}
],
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ9999NEWCAMPAIGNCLONE/relationships/campaign-messages/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ9999NEWCAMPAIGNCLONE/campaign-messages/"
}
},
"tags": {
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ9999NEWCAMPAIGNCLONE/relationships/tags/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ9999NEWCAMPAIGNCLONE/tags/"
}
}
},
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ9999NEWCAMPAIGNCLONE/"
}
}
}
Schedule a campaign
Use POST /api/campaign-message-schedule to schedule a message.
Schedule a message
curl --request POST \
--url https://a.klaviyo.com/api/campaign-message-schedule \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'content-type: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre' \
--data '
{
"data": {
"type": "campaign-message-schedule",
"attributes": {
"send_time": "2026-06-01T14:00:00+00:00",
"strategy": "static"
},
"relationships": {
"campaign-message": {
"data": {
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010"
}
}
}
}
}
'
Cancel or revert a scheduled message
PATCH /api/campaign-message-schedule/{id} cancels or reverts a scheduled message.
curl --request PATCH \
--url https://a.klaviyo.com/api/campaign-message-schedule/01JXYZ1234ABCDEFGHIJK00010 \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'content-type: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre' \
--data '
{
"data": {
"type": "campaign-message-schedule",
"id": "01JXYZ1234ABCDEFGHIJK00010",
"attributes": {
"action": "cancel"
}
}
}
'
Valid actions are
"cancel"and"revert". Therevertaction returns the message to DRAFT status and is only available for messages in theSCHEDULEDstate. Reverting will fail if the message is too close to its scheduled send time.
Scheduling strategies
The campaign's send_strategy (set in send_settings) determines how recipients receive the message.
STATIC — All recipients receive the message at the same absolute UTC time.
{
"send_strategy": "STATIC",
"send_passed_rltz_immediately": false
}
LOCAL_TIMEZONE — Recipients receive the message at the same local time in their respective timezones. For example, scheduling at 10:00 AM means 10:00 AM Eastern, 10:00 AM Pacific, etc. The send_passed_rltz_immediately flag controls what happens for timezones where the scheduled local time has already passed:
true— Send immediately to those recipients.false— Skip those recipients.
{
"send_strategy": "LOCAL_TIMEZONE",
"send_passed_rltz_immediately": true
}
THROTTLED — Sends to a percentage of recipients per hour for a gradual rollout. Valid throttle percentages are: 10, 11, 13, 14, 17, 20, 25, 33, 50.
{
"send_strategy": "THROTTLED",
"throttle_percentage": 25
}
The throttle percentage determines how many recipients receive the message per hour. For example,
25means roughly 25% of recipients per hour, completing delivery in approximately 4 hours.
SMART_SEND_TIME — Klaviyo determines the optimal send time for each recipient based on their historical engagement patterns. When this strategy is selected, the send_time is used as the start of the delivery window rather than a fixed send time.
SMART_SEND_TIMEsupport for the Campaigns API is coming soon. It is not yet available in the2026-04-15revision.
Tracking and UTM parameters
UTM tracking parameters are read-only in the Campaigns API. You can view the tracking_params on a campaign message response, but you cannot set or modify them via the API. Configure UTM parameters through the Klaviyo app or via company-level UTM defaults.
The tracking_params field on a campaign message response contains an array of tracking parameter objects. Each object is either a static parameter (a fixed string value) or a dynamic parameter (resolved from campaign metadata at send time):
{
"tracking_params": [
{
"name": "utm_source",
"value": "klaviyo"
},
{
"name": "utm_campaign",
"type": "dynamic",
"value": "campaign_name"
}
]
}
Open and click tracking are configurable per message via the definition field on create or update:
is_tracking_opens(boolean) — Whether to track email opens. Defaults totrue. Applicable to email messages only.is_tracking_clicks(boolean) — Whether to track link clicks. Defaults totrue. Applicable to email messages only.
Get campaign(s)
Get all campaigns
Use GET /api/campaigns to list campaigns. Unlike earlier revisions, a channel filter is not required — you can list all campaigns regardless of the channels they use.
curl --request GET \
--url 'https://a.klaviyo.com/api/campaigns?filter=contains(name,%27Summer%27)&sort=-updated_at&page[size]=20' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre'
{
"data": [
{
"type": "campaign",
"id": "01JXYZ1234ABCDEFGHIJK56789",
"attributes": {
"definition": {
"name": "Summer Sale 2026",
"builder": "wizard",
"archived": false,
"color": "#4A90D9",
"description": "Multi-channel summer promotion",
"send_settings": {
"send_timezone": "America/New_York",
"send_strategy": "STATIC",
"send_passed_rltz_immediately": false,
"exit_condition_enabled": false,
"exit_condition_conversion_metric_id": null
}
},
"created_at": "2026-04-14T12:00:00.000000+00:00",
"updated_at": "2026-04-14T12:05:00.000000+00:00"
},
"relationships": {
"campaign-audiences": {
"data": [
{
"type": "campaign-audience",
"id": "01JXYZ1234ABCDEFGHIJK00001"
}
]
},
"campaign-messages": {
"data": [
{
"type": "campaign-message",
"id": "01JXYZ1234ABCDEFGHIJK00010"
}
]
},
"tags": {
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/relationships/tags/",
"related": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/tags/"
}
}
},
"links": {
"self": "https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789/"
}
}
],
"links": {
"self": "https://a.klaviyo.com/api/campaigns?filter=contains(name,%27Summer%27)&sort=-updated_at&page[size]=20",
"next": null,
"prev": null
}
}
Get a single campaign
Use GET /api/campaigns/{id} with the include parameter to fetch a campaign and its related resources in a single request:
curl --request GET \
--url 'https://a.klaviyo.com/api/campaigns/01JXYZ1234ABCDEFGHIJK56789?include=campaign-audiences,campaign-messages,campaign-variations' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/vnd.api+json' \
--header 'revision: 2026-04-15.pre'
Get sub-resources
You can also query audiences, messages, and variations directly:
- GET
/api/campaign-audiences— List audiences, filterable bycampaign.id. - GET
/api/campaign-messages— List messages, filterable bycampaign.id,status, and more. - GET
/api/campaign-variations— List variations, filterable bycampaign-message.id.
Querying campaigns
Use the following query parameters to filter, sort, paginate, and shape campaign responses. Review the API reference documentation for the full list of allowed operators per field.
| Parameter | Description | Query example |
|---|---|---|
filter | Retrieve a subset of campaigns. Supported filter fields: id, name (contains), archived (equals), builder (equals), created_at (range), updated_at (range). Learn about the filter query parameter. | GET /api/campaigns?filter=contains(name,'sale')GET /api/campaigns?filter=equals(archived,false)GET /api/campaigns?filter=and(equals(builder,'wizard'),greater-than(created_at,2026-01-01T00:00:00Z)) |
sort | Sort campaigns by a supported field. Prefix with - for descending order. Supported sort fields: id, name, created_at, updated_at. Default: -updated_at. | GET /api/campaigns?sort=-created_atGET /api/campaigns?sort=name |
fields | Request only specified fields using sparse fieldsets. | GET /api/campaigns?fields[campaign]=definition.name,created_at |
include | Include related resources in the response. Supported values: campaign-audiences, campaign-messages, campaign-variations, tags. Learn about the include query parameter. | GET /api/campaigns?include=campaign-audiences,campaign-messagesGET /api/campaigns/{id}?include=campaign-audiences,campaign-messages,campaign-variations |
page[cursor] | Cursor-based pagination token. Use the next link from the response links object to retrieve the next page. | GET /api/campaigns?page[cursor]=eyJhZnRlciI6... |
page[size] | Number of results per page. Default: 100. Maximum: 100. | GET /api/campaigns?page[size]=50 |
Campaign messages query parameters
Campaign messages support their own set of filters and sort options:
| Parameter | Description | Query example |
|---|---|---|
filter | Filter messages. Supported fields: campaign.id (equals), id, name (contains), status (equals), created (range), updated (range). | GET /api/campaign-messages?filter=equals(campaign.id,'01JXYZ1234ABCDEFGHIJK56789')GET /api/campaign-messages?filter=equals(status,'DRAFT') |
sort | Sort messages. Supported fields: id, name, created, updated. Default: -updated. | GET /api/campaign-messages?sort=-created |
page[size] | Number of results per page. Default: 20. Maximum: 100. | GET /api/campaign-messages?page[size]=50 |
Next steps
Using your Klaviyo test account and Postman, try out the following walkthrough:
-
Create a list with at least one subscribed profile in your Klaviyo test account. Copy the list ID.
-
Create a campaign with an inline email audience, message, and variation using
POST /api/campaignswith your list ID inincluded. Copy the campaign ID, audience ID, message ID, and variation ID from the response. -
Retrieve the campaign and its full hierarchy using:
GET /api/campaigns/{id}?include=campaign-audiences,campaign-messages,campaign-variations -
Schedule the message using
POST /api/campaign-message-schedulewith your chosen send strategy and asend_time. -
Monitor send status by polling
GET /api/campaign-messages/{id}and checking thestatusfield as it progresses throughDRAFT→SCHEDULED→SENDING→SENT(orCANCELLEDif cancelled).
Additional resources
- How to create and send an email campaign
- How to create and send an SMS campaign
- How to send a push notification campaign
- Understanding campaign schedule and send options
- Understanding Smart Sending in Klaviyo
- Understanding smart send time
- Collect email and SMS consent via API
- Use Klaviyo's Postman collections