klaviyo icon
SlackIncomingWebhook icon
GetRecipientCount icon
If icon
Fail icon
Log icon

Klaviyo Pre-Send Recipient Estimation Alert

Estimate a Klaviyo campaign's audience before sending, alert Slack when out of range, and optionally fail the run so a parent flow gates the send.

Categories
Business

Catch broken segments and wrong-list mistakes before a Klaviyo campaign goes out. This blueprint is a pre-send audience guardrail: it reads Klaviyo's estimated recipient count for a campaign, compares it against an acceptable range, and raises a Slack alert when the estimate is too small (an over-restrictive filter or empty segment) or too large (the wrong list selected). When configured to gate, it fails the execution after alerting so a parent send-preparation flow can block or pause the send. It is built to run on demand right before scheduling a send, or as a reusable subflow inside a larger marketing-send pipeline.

How it works

  1. estimate_recipients (io.kestra.plugin.klaviyo.campaign.GetRecipientCount) reads the current recipient estimate for the campaign_id input with fetchType: FETCH_ONE, passing the campaign id as the single element of the task's array property.
  2. route_estimate (io.kestra.plugin.core.flow.If) branches on whether an estimate exists. Klaviyo computes estimates asynchronously, so when the value is null the flow takes the else path and posts a distinct "estimate unavailable" warning via io.kestra.plugin.slack.notifications.SlackIncomingWebhook rather than treating a missing value as zero and false-alarming as "too small".
  3. When an estimate is available, the nested check_audience_size If compares it against min_recipients and max_recipients. Out of range posts a rich Slack block message (alert_out_of_range) and, when fail_on_out_of_range is true, runs fail_send_gate (io.kestra.plugin.core.execution.Fail). In range, log_in_range records that no action is needed.

What you get

  • A pre-send sanity check that flags audience anomalies before delivery.
  • Clear separation of "estimate not ready yet" from a real zero count.
  • Slack alerts with campaign id, estimate, allowed range, and execution id.
  • Two gating signals: a FAILED execution state and an in_range output.
  • Built-in retries and a flow-level failure alert.

Who it's for

  • Lifecycle and email marketers who schedule Klaviyo campaigns.
  • Marketing-ops engineers building automated send-preparation pipelines.
  • Teams that want a guardrail against sending to the wrong audience.

Why orchestrate this with Kestra

Klaviyo's own scheduler can queue a send, but it has no native step that inspects the estimated audience, blocks on a threshold, and alerts a human before delivery. Kestra fills that gap. You express the whole guardrail as declarative YAML, add a constant retry on estimate_recipients (4 attempts, 30s apart) and a PT5M timeout so a transient 429 or 5xx self-heals, and wire a flow-level errors block that posts a Slack alert with the execution id, so an estimation failure (or a deliberate gate failure) is never silent. Run lineage and outputs are captured per execution, and because this flow emits both a FAILED state and an in_range output, a parent send-prep flow can gate on either, something Klaviyo's scheduler cannot coordinate alone.

Prerequisites

  • A Klaviyo account with a Private API Key that can read campaign recipient estimation.
  • A Slack incoming webhook pointing at the channel that owns send approvals.

Secrets

  • KLAVIYO_API_KEY: Klaviyo Private API Key, used by the estimation task.
  • SLACK_WEBHOOK_URL: Slack incoming webhook URL used for all alerts.

Quick start

  1. Add the KLAVIYO_API_KEY and SLACK_WEBHOOK_URL secrets to your Kestra namespace.
  2. Run the flow with the campaign_id you are about to send, adjusting min_recipients and max_recipients to match your guardrails (the 500 / 250000 defaults are illustrative).
  3. Leave fail_on_out_of_range true when calling this as a subflow gate; set it false for a notify-only check.

How to extend

  • Call this flow as a subflow from a send-preparation pipeline and branch on the in_range output or the FAILED state to pause the send.
  • Derive max_recipients dynamically from a percentage of total list size.
  • Swap the Slack alert for email or PagerDuty, or add an approval task to require a human sign-off before the send proceeds.
  • Loop over multiple campaign ids to check a whole send batch at once.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.