GetRecipient icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Log icon
Schedule icon

Klaviyo Recipient Estimation Job Cancellation Sentinel

Poll Klaviyo recipient estimation jobs, alert Slack on cancellations, and log the result for marketing-ops teams.

Categories
Business

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.

How it works

  1. 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.
  2. 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.
  3. route (io.kestra.plugin.core.flow.If):
    • compliant: logs that nothing tracked is cancelled.
    • alert: posts the count and the exact cancelled job IDs to Slack.
  4. summary logs the count and severity, closing the governance cycle.
  5. errors alerts Slack if the flow itself fails, for example an expired API key.

What you get

  • The exact cancelled job IDs in the Slack alert, not just a count, so whoever responds can look the job up directly instead of re-deriving which campaign stalled.
  • A severity split so one cancelled job during normal campaign cleanup does not read the same as several cancelling together, which is more likely a shared cause (a bad segment definition, a bulk campaign deletion) worth investigating as one incident.
  • A read-only check with zero risk of creating, retrying, or cancelling a job itself.

Who it's for

  • Marketing-ops and lifecycle-marketing teams running send-preparation pipelines that create Klaviyo recipient estimation jobs and want to know when one silently drops out.
  • Teams evaluating the Klaviyo plugin who want a worked example of 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.

Why orchestrate this with Kestra

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.

Prerequisites

  • A Klaviyo account with a Private API Key that can read campaign recipient estimation jobs.
  • At least one real recipient estimation job ID to track, created via Klaviyo's Create Campaign Recipient Estimation Job endpoint (or this repo's existing klaviyo-recipient-estimation-alert blueprint) in a send-preparation pipeline.
  • A Slack incoming webhook URL.

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.

Secrets

  • 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.

Inputs

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

  • {{ 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.

Pitfalls

  • Klaviyo's Get Campaign Recipient Estimation Job response exposes only 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.
  • A job that completes or gets cancelled stops changing; keep job_ids scoped to genuinely in-flight jobs and prune finished ones, or every poll keeps re-reporting the same old cancellation.
  • This endpoint fetches one job per API call in a loop with a roughly 1-second delay between calls; a very large job_ids list makes each run take proportionally longer.

Quick start

  1. Add the KLAVIYO_API_KEY and SLACK_WEBHOOK_URL secrets.
  2. Create one or more real recipient estimation jobs in Klaviyo and set job_ids to their IDs.
  3. Run the flow manually and confirm summary logs a count.
  4. Cancel a tracked job's campaign (or wait for one to cancel naturally) to confirm alert fires with its job ID.
  5. Enable the every_fifteen_minutes trigger once job_ids is fed from a real pipeline.

How to extend

  • Feed job_ids automatically from the same send-preparation pipeline that creates the jobs, instead of maintaining the list by hand.
  • Chain a lookup of the cancelled job's campaign via io.kestra.plugin.klaviyo.campaign.Get to include the campaign name in the Slack alert, not just the job ID.
  • Drop a job ID from a persisted KV list once it reaches complete or has been alerted on as cancelled, so job_ids naturally shrinks to only the jobs still worth tracking.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.