SautiKit
AI AgentsPricingDevelopersAPIBlogAbout
Sign inStart building

Voice broadcast campaigns: outbound AI calls at scale

Run outbound AI call campaigns with per-contact templates, calling windows, retries, voicemail detection, and a per-contact CSV report.

use-casebroadcastsai-voice-agentoutboundcampaigns

Next Steps

  • AI receptionist: put an AI agent on your number in minutesCreate an AI agent, publish it, and bind it to your number in three API calls. It answers callers in real time and hands over to your team with a summary. The BYO Stream recipe is the second half.
  • AI support voice agent: answer, look up, resolve — escalate with a summaryBind a managed AI agent to your support number with HMAC-signed tools that hit your API mid-call, and let handover brief your team with a summary. The BYO Stream recipe is the second half.
  • Outbound AI voice calls that qualify leads and run phone surveysYour system dials leads through the Sautikit API. An AI agent runs the qualification script over a live audio Stream, records answers, and hands hot leads to a human via Dial.
  • Your Sautikit number can now answer itself: managed AI agents are liveLaunch: bind a published AI agent to your Sautikit number and it answers callers in real time — interruptible, tool-calling, with a handover that briefs your team. The same agents dial broadcasts.
SautiKit

Programmable voice infrastructure for Africa. Buy numbers, place calls, and bill per second, all in local currency, via API.

Product

AI voice agentsBroadcastsNumbersCalls & routingRecordingsWallet & billingPricing

Developers

DocumentationAPI referenceVoice actionsWebhooksErrorsMCP serverQuickstartAI prompt

Compare

vs Africa's Talkingvs Twiliovs Infobipvs Vapi, Retell & BlandMigrate from Africa's TalkingAll comparisons

Company

AboutBlogConsole

© 2026 Sautikit. All rights reserved • Powered by Helloduty

Terms of ServicePrivacy Policy

Sautikit provides voice API services for application developers. Numbers provisioned on this platform are not configured for emergency calling (e.g. 999 / 112). Do not use Sautikit numbers as a replacement for a primary phone line.

Summary

A voice broadcast dials a list of contacts and puts a live AI agent on every answered call. Not a recording blasted at a thousand phones — a conversation, personalised per contact, that can answer questions, take a decision, and write the outcome back to your systems. You define the campaign once: which agent speaks, what it says to each contact, when it is allowed to dial, and how it retries the people it missed. Broadcasts handle the rest — pacing, retries, voicemail detection, and a per-contact report at the end.

Payment reminders, collections follow-ups, appointment confirmations, outage notifications, renewal calls, event reminders: anything that today means a human working down a spreadsheet, or an SMS that never gets read.

Who this is for

  • Collections and credit teams calling hundreds of accounts a day with due-date reminders and payment follow-ups.
  • Clinics, schools, and service businesses confirming appointments and sending time-sensitive notices people actually hear.
  • Utilities, SACCOs, and fintechs pushing notifications that need acknowledgement, not just delivery.
  • Ops teams who have outgrown manual call lists but do not want to be a robocall operation.

How it works

A broadcast runs a published AI agent against a contact list. The agent brings the conversational ability — the voice, the tools, the judgement about when to end a call. The broadcast brings the campaign machinery: the schedule, the retry policy, the per-contact personalisation, and the report.

1. Create the campaign

prompt_template is composed on top of the agent's base_prompt for every call, with {{variable}} placeholders filled per contact. start_phrase is the exact opening line the agent speaks when the contact answers — script it, so every call starts identically and identifies you.

const res = await fetch("https://api.sautikit.com/v1/broadcasts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SAUTIKIT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "July payment reminders",
    agent_id: process.env.REMINDER_AGENT_ID, // must be a published agent
    caller_number_id: process.env.CAMPAIGN_NUMBER_ID,
    prompt_template:
      "Remind {{name}} that their instalment of KES {{amount}} is due on {{due_date}}. If they can pay, confirm when. If not, capture a promise-to-pay date. Be brief and courteous.",
    start_phrase:
      "Hello, this is Wema Credit calling with a reminder about your account.",
    schedule_days: [1, 2, 3, 4, 5], // Mon-Fri
    daily_start_minute: 540, // 09:00
    daily_end_minute: 1020, // 17:00
    timezone: "Africa/Nairobi",
    max_attempts: 3,
    backoff_minutes: 120,
    retry_on: ["no_answer", "busy", "failed", "voicemail"],
  }),
});
 
const broadcast = await res.json();

The calling window matters as much as the script. The dialer will not place a call outside daily_start_minute to daily_end_minute in your timezone, or on days missing from schedule_days — a contact queued at 16:59 on Friday who cannot be reached rolls to Monday morning, not to Friday night.

2. Load contacts

Contacts carry the variables the template needs. Append them as JSON — one bad row is rejected individually and never sinks the batch — or upload a CSV in the dashboard for the same result.

await fetch(
  `https://api.sautikit.com/v1/broadcasts/${broadcast.id}/contacts`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SAUTIKIT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      contacts: [
        {
          phone: "+254712345678",
          variables: { name: "Alice", amount: "4,500", due_date: "Friday 25th" },
        },
        {
          phone: "+254700000001",
          variables: { name: "Ben", amount: "12,000", due_date: "Friday 25th" },
        },
      ],
    }),
  },
);

3. Start it — and stay in control

await fetch(`https://api.sautikit.com/v1/broadcasts/${broadcast.id}/start`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.SAUTIKIT_API_KEY}` },
});

/pause stops dialing immediately and /resume picks the queue back up, so a wrong script caught after fifty calls stays a fifty-call mistake. /duplicate clones a finished campaign — same agent, template, and schedule — for next month's run.

Retries and voicemail: reach people, don't spam machines

max_attempts and backoff_minutes govern the redial loop, and retry_on says which outcomes earn another attempt: no_answer, busy, failed, and voicemail. Voicemail handling is detection plus retry — when a machine answers, the dialer marks the attempt voicemail and schedules the next try inside your calling window. Your reminder reaches a person or it does not count as reached; it is never read out to an answering machine.

Real conversations, not robocalls

Every answered call is the full agent experience. The contact can interrupt mid-sentence and be heard. They can ask questions — "which instalment is this?" — and the agent answers from the context the template gave it. And because agents carry HMAC-signed HTTP tools against your endpoints, the call can do things: check the live balance before quoting it, capture a promise-to-pay date directly into your collections system, or reschedule the appointment it was calling to confirm. The agent ends the call itself when the conversation is done, and every call is capped by the agent's max_call_minutes.

That difference shows up in the outcomes. A robocall delivers audio; an agent call comes back with a result per contact — paid, promised Thursday, disputed, asked not to be called again.

Test with one call before you dial a thousand

POST /v1/agents/{id}/send places a single ad-hoc call through the same composition path — the agent's base_prompt plus your prompt_template and variables — without any campaign machinery. Call your own phone, hold the conversation, and tune the script before the list ever hears it.

await fetch(`https://api.sautikit.com/v1/agents/${AGENT_ID}/send`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SAUTIKIT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "+254712345678", // your own number
    prompt_template:
      "Remind {{name}} that their instalment of KES {{amount}} is due on {{due_date}}.",
    variables: { name: "Alice", amount: "4,500", due_date: "Friday 25th" },
  }),
});

Measure it

GET /v1/broadcasts/{id}/report.csv returns the campaign snapshot — queued, attempted, reached, and per-contact outcomes — ready for a spreadsheet or your BI pipeline. For any individual call, GET /v1/calls/{id}?transcript=1 has the per-turn transcript with tool calls, so "what exactly did the agent promise Mrs. Otieno" is a lookup, not a guess. Calls are recorded by default.

ℹ

The hosted Sautikit MCP server exposes create_broadcast, start_broadcast, pause_broadcast, and get_broadcast_report, so an AI assistant like Claude can build, launch, and review a campaign from a conversation.

What it costs

Campaign calls bill like any other agent call: the standard per-second outbound call rate plus KES 4.00 per minute of AI time, metered per second. A 35-second confirmed reminder costs 35 seconds of each — unanswered attempts and voicemail detections do not burn AI minutes talking to nobody. Concurrency seats pace the dialer: the free tier runs 1 concurrent AI call, paid tiers 5, 8, or 10. The wallet is prepaid via M-Pesa, so a campaign can never spend more than the balance you loaded — a broadcast that hits an empty wallet pauses instead of overdrafting.

⚠

Outbound campaigns carry consent and calling-hour obligations. Dial contacts who opted in, keep to lawful calling hours in each market, identify yourself in the start_phrase, and give people a way to opt out — the agent can capture "stop calling me" as an outcome like any other.

Next steps

  • Broadcasts: the product page — campaign features, pacing, and pricing.
  • AI agents: the agents that make the calls, and what they can do on one.
  • Route inbound calls to an AI agent: the inbound side of the same agents.
  • Outbound lead qualification use case: the build-your-own-model approach to outbound AI calling.
  • AI receptionist use case: put the same agents on your inbound line.