broadcast.completed

A broadcast finished sending, carrying the delivered and failed tallies.

When this fires

Every recipient in a broadcast has been attempted and the send is over. The payload carries what actually happened.

Required ability

broadcast:send — token must carry this at mint time to subscribe an endpoint to this event.

Payload

{
  "id": "evt_01HX...",
  "type": "broadcast.completed",
  "created_at": "2026-09-01T10:31:00Z",
  "api_version": "2026-05-01",
  "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
  "data": {
    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
    "audience": "customer",
    "pass_window_id": null,
    "plan_id": null,
    "expiring_within_days": null,
    "sent": 126,
    "failed": 2
  }
}

Field reference

FieldTypeNotes
idstring ULIDUnique event id, prefixed evt_. Use for idempotent processing.
typestringAlways broadcast.completed for this event.
created_atISO 8601 timestampServer-side emission time.
api_versionstringWebhook API contract version.
project_idstring UUIDProject this event belongs to.
data.project_idstring UUIDSame project, repeated inside data so a consumer reading only the data object is self-sufficient.
data.audiencestringThe segment addressed.
data.pass_window_idstring UUID / nullSet only for the two single-window pass segments.
data.plan_idstring UUID / nullThe plan the segment was narrowed to, if any. null when unnarrowed.
data.expiring_within_daysinteger / nullThe horizon used, set only for expiring_soon.
data.sentintegerMessages Telegram accepted.
data.failedintegerRecipients that could not be reached after the per-message retries were exhausted.

sent means Telegram accepted the message, not that a human read it. There is no read receipt, and a delivered message sitting in a muted chat counts as sent.

Reading the failure count

A steady trickle of failures is normal and not actionable: the overwhelming majority are members who blocked the bot or deleted their Telegram account. Those are permanent — the sender detects them and stops retrying that recipient rather than burning attempts.

What is worth alerting on is a sudden change in the ratio. failed climbing from ~2% to ~40% between two broadcasts usually means the bot token was revoked or the bot was removed from the project's resources, not that forty percent of an audience left at once.

sent + failed can be lower than the recipient_estimate reported by broadcast.queued — a recipient with no chat row is skipped without counting as either.

Caveats

  • Fires once per broadcast, at the end. A broadcast that Telegram rate-limits heavily can take minutes to finish; there is no progress event in between.
  • If the sending job is released and retried after a long rate-limit, the tallies count the completed run only.
  • A broadcast aborted before sending — no connected bot, an unknown audience, an empty body after sanitisation, or an audience the plan no longer includes — emits neither this nor broadcast.queued. Nothing was sent, so nothing is announced. The REST API refuses those cases up front with a 422 rather than accepting a send that will never leave.

How is this guide?

On this page

Subscriby is a product designed by you — for you.

No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request