Platform · Campaigns
Outbound AI campaigns that pace, retry, and know when to stop.
Enroll contacts by tag, filter, or CSV, split traffic across assistants, and let a minutely dial engine place calls inside your calling windows. Outcomes write back to the campaign record seconds after hangup.
Get started for free. Pay as you go. Or talk to sales
What it does
An engine that converges every minute
The engine ticks every minute: it starts scheduled campaigns, tops up running ones to their concurrency cap, dials inline, and marks campaigns completed when the list drains. Every contact claim is an optimistic conditional update, so overlapping ticks cannot double-dial a contact.
- Scheduled campaigns auto-start on the next tick
- Pause, resume, and stop take effect within one tick
- Drained campaigns mark themselves completed
- Claim-first updates prevent double dialing
A/B test assistants on live traffic
Split a campaign across assistants by traffic percent; splits must sum to 100 before start. Assignment is deficit-based per dial, so realized traffic converges on the configured split even if you edit it mid-campaign. Per-assistant rollups show dialed and answered counts side by side.
- Splits validated to sum to 100% before start
- Deficit-based assignment, not random
- Per-assistant answered and dialed rollups
Calling windows, pacing, and retries
Set a local time-of-day window with days of the week; overnight windows wrap midnight. Cap concurrent calls and calls per minute per campaign. No-answer, busy, and failed outcomes requeue with a configurable delay until max attempts, and retries wait for the window too.
- Timezone-aware windows, including overnight wrap
- Retries honor calling windows
- Per-campaign concurrency and calls-per-minute caps
- Configurable max attempts and retry delay
Every dial passes compliance gates
Before each call the engine skips DND contacts, checks your blacklist, and validates the number as E.164. If the wallet hits zero the campaign pauses with a stated reason and the contact returns to pending, so nothing burns while you top up. Opt-outs and DNC blocks show up in analytics.
- DND contacts skipped automatically
- Blacklist checked on every outbound dial
- Wallet at zero pauses the campaign with a stated reason
Enroll from your CRM or a CSV
Enroll by picking contacts, by the same core filters as your contacts list (tags, status, search, has-phone), or by uploading a CSV that matches existing contacts by phone and creates the rest. A unique constraint dedupes enrollments; filters take up to 25,000 contacts at once.
- Same tag, status, search, and has-phone filters as contacts
- CSV import matches contacts by phone, creates the rest
- Up to 25,000 contacts per filter enrollment
- One row per contact per campaign, database-enforced
Results written back within seconds
The call-events webhook reconciles each outcome the moment a call ends; a minutely sweep catches lost webhooks. Answer rate, transfers, appointments booked, hot leads, dispositions, sentiment, and cost aggregate per campaign, with CSV export and an on-demand AI executive summary.
- Event-driven reconcile from the call webhook
- Hot leads flagged from sentiment plus outcome
- Appointments detected and counted per campaign
- CSV export with KPI block and per-contact outcomes
At scale
Built for the agent lifecycle.
01 · Deploy
Create a campaign, pick assistants and numbers, enroll a list, and press start. Pre-start checks refuse to launch until splits sum to 100, every assistant is voice-ready, and a dialable outbound number exists.
02 · Test
Run a small list first: enroll a handful of contacts, cap concurrency, and read per-contact outcome rows. A/B splits let you trial two prompts on the same list and compare answered calls per assistant.
03 · Scale
Top-up runs every minute to your concurrency cap, spreading dials across a number pool if you use one. Filter enrollment takes up to 25,000 contacts at once; a per-tick dial budget keeps the engine stable.
04 · Observe
Live KPIs update as calls end: answer rate, transfers, appointments, hot leads, opt-outs, spend, and dials per hour. Export the outcome CSV or generate an AI summary of what worked and what to do next.
Under the hood
- ENGINE
Minutely cron tick; optimistic claim-first updates make overlapping ticks safe
- SPLITS
A/B traffic across assistants; deficit-based assignment converges on the configured split
- WINDOWS
Local time-of-day windows with day-of-week selection; overnight windows wrap midnight
- RETRIES
No-answer, busy, and failed requeue with a configurable delay until max attempts
- GATES
DND, blacklist, and E.164 checks per dial; wallet at zero pauses the campaign with a reason
- RECONCILE
Call webhook writes outcomes at hangup; a minutely sweep and 30-minute stale fail catch the rest
- TARGETING
Enroll by contact ids, the contacts-list filter (tags, status, search), or CSV upload; deduped per campaign
FAQ
How does the dial engine work?
A cron ticks every minute. Each tick starts due scheduled campaigns, reconciles in-flight calls, then tops up each running campaign to its concurrency cap and dials inline, subject to the calling window and any calls-per-minute cap. Every contact claim is a conditional update, so overlapping ticks cannot dial a contact twice.
What do I need before a campaign can start?
At least one assistant with a traffic split summing to 100%, each assistant provisioned for voice, and an outbound number: either a number assigned per assistant or a shared number pool. The start endpoint validates all of this and returns a specific error for anything missing.
How are retries and do-not-call handled?
No-answer, busy, and failed calls requeue with your configured delay until max attempts is reached, and only dial inside the calling window. DND contacts are skipped before dialing, the account blacklist is checked on every call, and opt-outs and DNC blocks are counted in campaign analytics.
What does an outbound campaign cost?
Calls bill at $0.07 per minute from a prepaid wallet. If the wallet hits zero mid-campaign, the engine pauses the campaign and holds remaining contacts as pending; top up and resume where it left off. Signup is free and pay as you go.
Can I split traffic between two agent scripts?
Yes. Assign a traffic percent per assistant; splits must sum to 100 before start. Assignment is deficit-based per dial, so the realized split converges on your configuration even if you edit it mid-campaign, and per-assistant analytics show dialed and answered counts side by side.
