skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
zavudev/zavu-skills227 installs

broadcast-campaign

Create and manage broadcast campaigns for bulk messaging across SMS, WhatsApp, Email, and Telegram.

How do I install this agent skill?

npx skills add https://github.com/zavudev/zavu-skills --skill broadcast-campaign
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The skill provides instructions for managing bulk messaging campaigns using the Zavu API. It includes multi-language examples and details platform safety features like identity verification and content review. The primary security consideration is the potential for indirect prompt injection through template variables.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

  • Runlayerpass

    1/1 file flagged

  • ZeroLeakspass

    Score: 93/100 · 2 sections analyzed

What does this agent skill do?

Broadcast Campaign

When to Use

Use this skill when building code to send messages to multiple recipients in a campaign — including bulk email. Covers the full broadcast lifecycle from creation to monitoring.

Broadcast Lifecycle

draft -> pending_review -> pending_admin_review -> approved -> sending -> completed
                        -> rejected -> (edit) -> pending_review (retry, max 3)
                        -> rejected -> escalated (manual review by Zavu team)
                        -> rejected_final
         approved -> scheduled -> sending -> completed
         sending -> paused (can resume)
         (any active) -> cancelled
         (any) -> failed (permanent failure)

Step-by-Step Workflow

1. Create Broadcast

const result = await zavu.broadcasts.create({
  name: "Black Friday Sale",
  channel: "sms", // smart | sms | sms_oneway | whatsapp | telegram | email
  text: "Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20",
});
const broadcastId = result.broadcast.id; // brd_xxx

Python:

result = zavu.broadcasts.create(
    name="Black Friday Sale",
    channel="sms",
    text="Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20",
)
broadcast_id = result.broadcast.id

Go:

result, err := client.Broadcasts.Create(context.TODO(), zavudev.BroadcastCreateParams{
    Name:    zavudev.String("Black Friday Sale"),
    Channel: zavudev.String("sms"),
    Text:    zavudev.String("Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20"),
})
broadcastID := result.Broadcast.ID

Ruby:

result = client.broadcasts.create(
    name: "Black Friday Sale",
    channel: "sms",
    text: "Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20",
)
broadcast_id = result.broadcast.id

PHP:

$result = $client->broadcasts->create([
    'name' => 'Black Friday Sale',
    'channel' => 'sms',
    'text' => 'Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20',
]);
$broadcastId = $result->broadcast->id;

Channel Options

ChannelDescription
smartPer-contact intelligent routing
smsSMS to all contacts
sms_onewayOne-way SMS (no replies) — needs no number and no credential
whatsappWhatsApp (requires template for non-window contacts)
telegramTelegram
emailEmail (needs emailSubject) — recommended path for bulk email

Message Types

TypeDescription
textPlain text (default)
imageImage with optional caption
videoVideo message
audioAudio message
documentDocument file
templateWhatsApp pre-approved template

Email Broadcast (with HTML body)

For bulk email campaigns, use channel: "email" with an HTML body. This is the recommended way to send mass email through Zavu.

const result = await zavu.broadcasts.create({
  name: "Newsletter",
  channel: "email",
  emailSubject: "Special offer for {{name}}",
  text: "Hi {{name}}, check out our latest sale!",   // plain text fallback
  emailHtmlBody: "<h1>Hi {{name}}!</h1><p>Check out our latest sale.</p>",
  metadata: { campaign_id: "camp_123", region: "US" },
});

2. Add Contacts (batch, max 1000/request)

const result = await zavu.broadcasts.contacts.add({
  broadcastId: broadcastId,
  contacts: [
    { recipient: "+14155551234", templateVariables: { name: "John" } },
    { recipient: "+14155555678", templateVariables: { name: "Jane" } },
  ],
});
console.log(result.added, result.duplicates, result.invalid);

3. Send (triggers content review)

Sending a broadcast needs no account verification, on any channel. Identity and business verification raise daily ceilings; neither is a permission to broadcast. What stands in front of a broadcast is the content review, and it cannot be bypassed.

The broadcast's own text is read once — not once per recipient — before the automated review runs. A broadcast that is refused lands on rejected; one that is flagged waits for a person even on email, which otherwise sends as soon as the review passes it.

A whatsapp broadcast skips review. It can only be built on a template, and Meta vets the business and the content when it approves that template. What is enforced instead is that the template is approved — an unapproved one is refused with 400 template_not_approved, and since WhatsApp passes no other review, that is the only gate on it.

Each recipient is then sent as an ordinary message, so the daily ceilings and the 10DLC requirement on +1 SMS destinations apply per recipient.

// Send immediately
await zavu.broadcasts.send({ broadcastId });

// Or schedule
await zavu.broadcasts.send({
  broadcastId,
  scheduledAt: "2024-01-15T10:00:00Z",
});

A draft never goes straight out — what happens next depends on the channel:

BroadcastWhat this call does
WhatsApp on a Meta-approved templateSkips review (Meta already vetted it) and starts sending
EmailAutomated review; sends as soon as it passes
SMS, Telegram, smart, everything elseAutomated review, then pending_admin_review — a person approves before it sends

So a 202 means accepted, not sending. Poll the status rather than assuming; only WhatsApp-template broadcasts move to sending immediately.

Calling send on a broadcast that is already approved or scheduled sends or reschedules it directly, since it has already been through review.

4. Monitor Progress

const progress = await zavu.broadcasts.progress({ broadcastId });
console.log(`${progress.percentComplete}% complete`);
console.log(`Delivered: ${progress.delivered}, Failed: ${progress.failed}, Skipped: ${progress.skipped}`);
console.log(`Estimated completion: ${progress.estimatedCompletionAt}`);

Per-contact statuses:

  • pending, queued, sending: not handed to the provider yet.
  • sent: the provider accepted the message; delivery is not confirmed yet. A recipient moves on to delivered or failed when the channel reports it. Channels that never report delivery leave the recipient at sent.
  • delivered: the channel confirmed delivery to the device (a WhatsApp read receipt counts too).
  • failed: not delivered. A recipient can move from sent or delivered to failed when the provider reports a failure late.
  • skipped: not sent, because the recipient opted out of the channel or the broadcast was cancelled before reaching it.

The progress response and the broadcast carry the sent count as sent and sentCount, and sent is a valid status filter on GET /v1/broadcasts/{broadcastId}/contacts. The SDK does not type them yet, so read them from the REST response:

curl -s https://api.zavu.dev/v1/broadcasts/$BROADCAST_ID/progress \
  -H "Authorization: Bearer $ZAVU_API_KEY"
# { "total": 500, "sent": 120, "delivered": 360, "failed": 20, ... }

Completion counts sent as done, so a completed broadcast can still have recipients waiting on a delivery receipt.

5. Handle Rejection (if content review fails)

// Check remaining review attempts
const broadcast = await zavu.broadcasts.get({ broadcastId });
console.log(`Review attempts: ${broadcast.reviewAttempts}/3`);

// Edit content
await zavu.broadcasts.update({
  broadcastId,
  text: "Updated message content with {{name}}",
});

// Retry review (max 3 attempts)
await zavu.broadcasts.retryReview({ broadcastId });

// Or escalate to manual review
await zavu.broadcasts.escalate({ broadcastId });

Other Operations

// Reschedule
await zavu.broadcasts.reschedule({
  broadcastId, scheduledAt: "2024-01-16T14:00:00Z",
});

// Cancel (pending contacts skipped, queued may still deliver)
await zavu.broadcasts.cancel({ broadcastId });

// List contacts in broadcast
const contacts = await zavu.broadcasts.contacts.list({
  broadcastId, status: "delivered", limit: 100,
});

// Delete (draft only)
await zavu.broadcasts.delete({ broadcastId });

Template Variables

Use {{variable_name}} in broadcast text. Override per-contact via templateVariables:

await zavu.broadcasts.contacts.add({
  broadcastId,
  contacts: [
    { recipient: "+14155551234", templateVariables: { name: "John", order_id: "ORD-001" } },
  ],
});

Constraints

  • Max 1000 contacts per add request (batch for larger lists)
  • Sending needs no account verification on any channel. What gates a broadcast is the content review below; drafting requires nothing
  • Each recipient counts against the channel's daily ceiling (see the send-message skill); once it is reached the remaining recipients are marked failed with errorCode: "DAILY_LIMIT_EXCEEDED" and are not retried the next day
  • Content goes through review before sending, except WhatsApp on a Meta-approved template
  • Most channels also wait on a human (pending_admin_review) after the automated pass; email is the exception and sends straight through, unless the review asks for a person
  • Balance is reserved (estimated cost) when sending
  • Max 3 review retry attempts, then escalate
  • Can only update/delete broadcasts in draft status
  • Cancelling doesn't stop already-queued messages

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/zavudev/zavu-skills/broadcast-campaign">View broadcast-campaign on skillZs</a>