New to Kestra?
Use blueprints to kickstart your first workflows.
Poll Klaviyo recipient estimation jobs, alert Slack on cancellations, and log the result for marketing-ops teams.
A Klaviyo campaign recipient estimation job runs asynchronously in the background after someone asks Klaviyo to size an audience before a send. If the campaign behind it gets deleted, or the team sends before the estimate finishes, Klaviyo quietly marks that job cancelled; nothing pages anyone, and the only trace is a job record nobody is watching. This blueprint tracks a list of in-flight job IDs, reports exactly which ones came back cancelled, and scales the alert by how many cancellations show up in the same poll.
This blueprint was created by Mohit Jeswani.
check_jobs (io.kestra.plugin.klaviyo.jobs.GetRecipient) fetches the current status
of every tracked job in job_ids. Read-only; nothing in Klaviyo is changed, created, or
cancelled. allowFailure: true covers an API or auth error without failing the flow
outright.evaluate (io.kestra.plugin.core.output.OutputValues) counts and lists the jobs whose
attributes.status is cancelled, then classifies the poll as NONE_CANCELLED,
ISOLATED_CANCELLATION, or WIDESPREAD_CANCELLATION against widespread_cancel_count.route (io.kestra.plugin.core.flow.If):summary logs the count and severity, closing the governance cycle.errors alerts Slack if the flow itself fails, for example an expired API key.jobs.GetRecipient used
as a standing job-health sentinel, distinct from this repo's existing Klaviyo blueprints,
which report campaign performance metrics, alert on an out-of-range recipient count once an
estimate is ready, and monitor campaign send job status rather than recipient estimation
job status.Klaviyo's own API reports a job's status one lookup at a time; it has no schedule, no
cancellation-count policy, and no Slack integration of its own. Kestra keeps job_ids and
widespread_cancel_count as flow inputs, turns a batch status check into a severity decision,
and keeps a full execution history of every poll and which jobs it flagged.
klaviyo-recipient-estimation-alert blueprint) in a send-preparation pipeline.Klaviyo is a hosted SaaS platform with no official standalone Docker image, so check_jobs
cannot be exercised against a local container; validate against a real Klaviyo account (a
free trial account can create and cancel estimation jobs) first.
KLAVIYO_API_KEY: the Klaviyo Private API Key used by check_jobs. In Kestra OSS, provide
it as the base64-encoded environment variable SECRET_KLAVIYO_API_KEY.SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as
the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
job_ids |
[] |
Recipient estimation job IDs to track |
widespread_cancel_count |
3 |
Cancelled-job count that escalates from isolated to widespread |
{{ outputs.check_jobs.rows }}: every tracked job's raw record (id, type,
attributes.status), as Klaviyo reports it.{{ outputs.evaluate.values.cancelled_count }} / .cancelled_ids: how many tracked jobs are
cancelled and their IDs, semicolon-joined.{{ outputs.evaluate.values.severity }}: NONE_CANCELLED, ISOLATED_CANCELLATION,
WIDESPREAD_CANCELLATION, or CRITICAL.attributes.status
(queued, processing, complete, or cancelled); there is no created_at or similar
timestamp field on this endpoint. Verified directly against Klaviyo's published API
reference, since the plugin task itself passes the response through unmodified rather than
declaring typed fields. This blueprint deliberately classifies by status alone and does not
attempt to flag a job "stuck" in queued/processing for too long, since the API gives no
way to measure that duration from a single poll.job_ids scoped to genuinely
in-flight jobs and prune finished ones, or every poll keeps re-reporting the same old
cancellation.job_ids list makes each run take proportionally longer.KLAVIYO_API_KEY and SLACK_WEBHOOK_URL secrets.job_ids to their
IDs.summary logs a count.alert
fires with its job ID.every_fifteen_minutes trigger once job_ids is fed from a real pipeline.job_ids automatically from the same send-preparation pipeline that creates the jobs,
instead of maintaining the list by hand.io.kestra.plugin.klaviyo.campaign.Get
to include the campaign name in the Slack alert, not just the job ID.complete or has been alerted on as
cancelled, so job_ids naturally shrinks to only the jobs still worth tracking.