Schedule icon
Request icon
Return icon
Switch icon
Log icon
SlackIncomingWebhook icon

Plivo SMS Delivery Failure Sentinel

Count recent outbound Plivo SMS every hour, send nothing, and alert Slack when failed or undelivered SMS cross your limits, with the top error code.

Categories
Business

OTPs, order updates and payment alerts sent through Plivo fail quietly: a sender ID or DLT template gets rejected, the account balance runs out, a number is blocked by a carrier, or a route has trouble. Each message just ends failed or undelivered with an error_code, and the first signal is usually customers saying they never got the OTP. Plivo's delivery callbacks report one message at a time; nothing watches the rate. This blueprint turns three scheduled, read-only calls to the Plivo Message API into a delivery health gate: io.kestra.plugin.core.http.Request counts delivered, failed and undelivered SMS, one jq query computes the failure rate and the most common error code, and the result routes to a quiet log or a Slack alert.

How it works

  1. count_delivered, list_failed and list_undelivered (io.kestra.plugin.core.http.Request) call GET /v1/Account/{auth_id}/Message/ with message_direction=outbound, message_type=sms, a message_time__gt filter for the lookback window and one message_state each, using HTTP basic auth with the auth ID and token. Each response carries meta.total_count, so three small calls give exact counts without paging; the failed and undelivered calls also read up to 20 messages for their error_code. They are reads: no message is sent. Retries cover short network blips, and allowFailed plus allowFailure keep an API error from aborting the flow so it can be reported instead.
  2. summarize_messages (io.kestra.plugin.core.debug.Return) first guards for any missing or non-200 response (UNREACHABLE). Otherwise one jq query adds the three counts, computes the share that failed or went undelivered, and finds the most common error_code in the sample. Messages still queued or sent are not counted, because their outcome is not known yet. Fewer than min_messages finished SMS is LOW_VOLUME; at or above critical_failure_rate is CRITICAL; at or above warning_failure_rate is WARNING; otherwise HEALTHY.
  3. route_by_failures (io.kestra.plugin.core.flow.Switch) branches on that classification: HEALTHY and LOW_VOLUME log quietly, WARNING posts a Slack note, CRITICAL and UNREACHABLE page Slack. A defaults fallback logs anything unexpected.
  4. log_audit_result (io.kestra.plugin.core.log.Log) writes one audit line per run with the three HTTP statuses and the full summary.
  5. The flow-level errors block pages Slack if the flow itself fails, and the hourly_check trigger runs at 10 minutes past every hour (Asia/Kolkata), shipped disabled: true.

What you get

  • An hourly, read-only check of SMS delivery with no custom scripting and no extra plugin to install.
  • A status output (HEALTHY / WARNING / CRITICAL / LOW_VOLUME / UNREACHABLE) other flows can gate on, for example to switch OTPs to WhatsApp or voice while SMS fails.
  • Slack messages with failed and undelivered counts, the failure rate and the most common Plivo error code.
  • An audit line on every run, separate from Slack.

Who it's for

  • Teams sending OTPs, transactional alerts or order updates through Plivo, including Indian senders bound by DLT templates.
  • Support and growth teams that need to know before customers do when messages stop arriving.
  • Teams that already run their alerting in Kestra.

Why orchestrate this with Kestra

Plivo's console shows message logs and its callbacks report one message at a time. Kestra turns plain, read-only API calls into a scheduled, typed classification with retries, a failure path and an execution history, and the status output lets your notification flows fall back to another channel automatically.

Prerequisites

  • A Plivo account sending SMS, with its Auth ID and Auth Token from the Plivo console overview page.
  • A Slack incoming webhook for the WARNING, CRITICAL, UNREACHABLE and flow-failure alerts.

Secrets

  • PLIVO_AUTH_ID: the Auth ID (basic auth username and part of the URL path).
  • PLIVO_AUTH_TOKEN: the Auth Token (basic auth password).
  • SLACK_WEBHOOK: Slack incoming webhook used for every alert branch and the flow-failure alert.

In Kestra OSS, secrets are supplied as environment variables prefixed SECRET_ and base64-encoded, for example SECRET_PLIVO_AUTH_ID=$(echo -n 'MAXXXXXXXXXXXXXXXXXX' | base64), and read back with {{ secret('PLIVO_AUTH_ID') }}. Use the Enterprise secrets backend for encryption at rest and access control.

Quick start

  1. Send a few test SMS through the Plivo API (or note a busy hour of real traffic).
  2. Add PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN and SLACK_WEBHOOK as secrets.
  3. Run the flow manually with a low min_messages and compare the counts in the logs with the message logs in the Plivo console; set api_timezone to Asia/Kolkata if they are off by your account's offset.
  4. Enable hourly_check.

How to extend

  • Add a subaccount or powerpack_id filter to watch one product or sender pool with its own limits.
  • Change message_type to whatsapp or mms for a second sentinel on those channels.
  • Restrict the trigger cron to your sending hours, and store the last status in a KV store to alert only on changes.

Inputs

  • lookback_hours: type INT, default 2.
  • api_timezone: type STRING, default UTC.
  • warning_failure_rate: type FLOAT, default 3.0 (percent).
  • critical_failure_rate: type FLOAT, default 10.0 (percent).
  • min_messages: type INT, default 50.

Outputs

  • status: one of HEALTHY, WARNING, CRITICAL, LOW_VOLUME, UNREACHABLE.
  • Example path: {{ fromJson(outputs.summarize_messages.value).top_error }} for the most common error code in the sample.

Links

Pitfalls

  • The error code is taken from a sample of up to 20 failed and 20 undelivered messages (the API page limit); the counts themselves are exact.
  • queued and sent messages are left out until they reach a final state, so a very short window can look healthier than it is.
  • Check the message_time__gt time zone against your account (see api_timezone).
  • This flow only reads; it never sends, cancels or deletes a message.
See How

New to Kestra?

Use blueprints to kickstart your first workflows.