HomeGuidesAPI Reference
ChangelogHelp CenterCommunityContact Us
API Reference

Campaigns API overview (revision 2026-04-15.pre)

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.pre header. 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 using LOCAL_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 when send_strategy is "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 is true cannot 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:

StateDescription
DRAFTInitial state. The message can be edited and configured.
SCHEDULEDThe message is queued and will send at the configured send time.
SENDINGThe message is actively being delivered.
SENTDelivery is complete.
CANCELLEDThe 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. The channel field inside details determines 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 a temporary_id (a client-generated string used for linking). At least one audience is required.
  • messages[] — Each message references an audience_temporary_id to associate it with an audience. Messages can include inline variations[].
  • 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 the archived flag).
  • 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". The revert action returns the message to DRAFT status and is only available for messages in the SCHEDULED state. 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, 25 means 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_TIME support for the Campaigns API is coming soon. It is not yet available in the 2026-04-15 revision.

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 to true. Applicable to email messages only.
  • is_tracking_clicks (boolean) — Whether to track link clicks. Defaults to true. 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 by campaign.id.
  • GET /api/campaign-messages — List messages, filterable by campaign.id, status, and more.
  • GET /api/campaign-variations — List variations, filterable by campaign-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.

ParameterDescriptionQuery example
filterRetrieve 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))
sortSort 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_at

GET /api/campaigns?sort=name
fieldsRequest only specified fields using sparse fieldsets.GET /api/campaigns?fields[campaign]=definition.name,created_at
includeInclude 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-messages

GET /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:

ParameterDescriptionQuery example
filterFilter 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')
sortSort 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:

  1. Create a list with at least one subscribed profile in your Klaviyo test account. Copy the list ID.

  2. Create a campaign with an inline email audience, message, and variation using POST /api/campaigns with your list ID in included. Copy the campaign ID, audience ID, message ID, and variation ID from the response.

  3. Retrieve the campaign and its full hierarchy using:
    GET /api/campaigns/{id}?include=campaign-audiences,campaign-messages,campaign-variations

  4. Schedule the message using POST /api/campaign-message-schedule with your chosen send strategy and a send_time.

  5. Monitor send status by polling GET /api/campaign-messages/{id} and checking the status field as it progresses through DRAFTSCHEDULEDSENDINGSENT (or CANCELLED if cancelled).

Additional resources