UI Guide
Campaigns

Campaigns

A Campaign dials every contact in an audience using a selected voice flow. OliAI handles rate limiting, retries, and concurrency automatically.

Campaign Lifecycle

DRAFT → IN_PROGRESS → COMPLETED

        PAUSED

       CANCELLED
StatusMeaning
DRAFTCreated but not started. You can still edit or delete it.
IN_PROGRESSActively dialing contacts.
PAUSEDTemporarily halted. Can be resumed.
COMPLETEDAll contacts have been called (success or final failure).
CANCELLEDManually stopped. Cannot be resumed.

Creating a Campaign

Go to Campaigns

Click Campaigns in the sidebar, then click + Create Campaign.

Set Campaign Details

FieldRequiredDescription
NameYesInternal label for this campaign
Use Case TypeYesWhat this campaign does — Collections, Lead Qualification, Medical Booking, Customer Support, Edutech, or Custom. Drives the default intent labels (see below).
FlowYesThe voice flow to use for all calls
AudienceYesThe group of contacts to call
Scheduled StartNoLeave blank to start manually, or set a future date/time
TimezoneNoRequired if you set a scheduled start

Use Case Type can only be changed while the campaign is in DRAFT. Once you start the campaign it becomes read-only. Changing it on a draft re-seeds the intent labels from the new preset, so set it before customizing labels. Campaigns created before this feature shipped default to Custom and show a "Review type" prompt.

Configure Dialing Settings

SettingDefaultDescription
Calls Per Minute10How many calls to initiate per minute
Max Concurrent Calls5Maximum simultaneous active calls
Max Retries3Retries per contact (0–10). See Retry Policy.
Retry Delay (minutes)60Wait between attempts (30 min – 72 h)
Call Timeout (minutes)5Maximum duration per call

Start with lower concurrency (3-5) for your first campaigns to ensure call quality. Scale up once you've validated the flow.

Create the Campaign

Click Create Campaign. The campaign is created in DRAFT status.

Intent Labels

Every campaign has a set of intent labels — the outcomes OliAI uses to classify each call (for example Interested in Paying, Callback Requested, Not Reachable). The set is scoped to that one campaign; editing labels on one campaign never affects another.

When you create a campaign, OliAI pre-fills the labels from your Use Case Type. You can then tailor them on the campaign detail page, in the Intent Labels panel.

Use Case TypeDefault labels
CollectionsInterested in Paying, Not Interested, Callback Requested, Dispute Raised, Already Paid, Financial Difficulty
Lead QualificationQualified – High Intent, Qualified – Low Intent, Not Interested, Callback Requested, Not Reachable, Wrong Number
Medical BookingAppointment Confirmed, Wants to Reschedule, Not Interested, Callback Requested, Not Reachable, Wrong Patient
Customer SupportIssue Resolved, Needs Escalation, Callback Requested, Not Reachable, Wrong Contact
EdutechEnrolled, Interested – Follow Up, Not Interested, Callback Requested, Not Reachable
CustomNo preset labels — you build the set from scratch

A Not Reachable label is always present (even on Custom campaigns) because OliAI relies on it for unanswered calls and retry logic.

Configuring labels

In the Intent Labels panel (while the campaign is in DRAFT) you can:

  • Add up to 10 custom labels on top of the preset.
  • Rename any label, including system labels.
  • Pick a colour from the palette — used for the label badge across the app.
  • Toggle Positive — marks the label as a positive outcome (used in reporting).
  • Set Retry Behaviour — what tagging a call with this label does to retries (see Suppression).
  • Reorder labels with the up/down arrows. Order sets the priority OliAI uses to resolve ambiguous calls (higher = preferred).
  • Delete a label — except system labels (e.g. Not Reachable, Wrong Number), which are required and cannot be removed.
⚠️

The label set locks once the campaign leaves DRAFT. After launch you can no longer add, delete, or reorder labels. Renaming a label updates the name shown on all past calls already tagged with it; it does not re-classify them.

How Calls Get Tagged

After every call ends, OliAI automatically assigns one intent label — no manual review needed:

  • Answered calls — the transcript is sent to your flow's AI model, which picks the single best-matching label from your configured set.
  • Unanswered calls (no answer, busy, failed before connecting) — tagged Not Reachable automatically, with no AI cost.
  • Too short / no speech — calls with under ~5 seconds of speech, or no recognisable content, are flagged Undetermined for your review.
  • AI unavailable — if classification fails after several retries, the call is flagged Undetermined so nothing is silently dropped.

Tagging completes within about a minute of the call ending. Tags are visible in the campaign's Call Log and on the contact's call history. Analysis runs entirely within your own organization's AI configuration — transcripts are never shared across organizations.

Suppression & Do Not Contact

Each intent label has a Retry Behaviour that decides what happens when a call is tagged with it:

Retry BehaviourEffect
RetryableEligible for retries per the retry policy
Suppress in campaignThe contact is removed from this campaign's retry queue. Their call shows status Suppressed.
Suppress org-wideThe contact is added to the org's Do Not Contact registry — skipped by all campaigns.

When a suppression-flagged intent is tagged, the contact is removed from the retry queue immediately.

Suppressed contacts

Filter the campaign Call Log by Suppressed to see them, with the suppressing intent as the reason. Click Restore on a row to put the contact back in the queue — the action is recorded in the security log.

Do Not Contact registry

Org-wide suppressions appear under Do Not Contact (admin), listing the phone number, source campaign, suppressing intent and date. OliAI checks this registry in real time before every call — first attempt or retry — so a number is never dialled once listed.

Do Not Contact applies to the phone number, so it covers duplicate contact records. If a contact is suppressed org-wide from one campaign, their pending calls in other campaigns are cancelled within minutes. Remove a number from the registry to allow contact again.

Journey Rules

Journey Rules decide what happens next for a contact based on the intent label their call was tagged with — so the right follow-up happens instantly, no matter the volume, without anyone reviewing calls by hand.

In the campaign detail page, the Journey Rules panel shows a row per intent label. For each one, pick a next action:

Next actionWhat it does
Add to Retry QueueRe-dials the contact after a delay you set (e.g. Callback Requested → retry in 240 min). Honours the calling window and the campaign's max-retries cap.
Suppress from CampaignNo further retries for this contact in this campaign.
Suppress Org-wide (Do Not Contact)Adds the contact to your organization's Do Not Contact list — they won't be dialled by any campaign.
Flag for Human ReviewMarks the call for review; a Review badge appears in the Call Log.
Commitment Capture ReminderTriggers a commitment reminder (available once Commitment Capture is enabled).
Mark Completed (default)No further action. This is the default for any label without a rule.

Multiple labels can use the same action (e.g. both Not Reachable and No Answer → retry in 4 hours).

Rules run automatically the instant a call is tagged — no human trigger. They're campaign-scoped: editing rules on one campaign never affects another.

Editing rules on a running campaign

Unlike intent labels (which lock at launch), Journey Rules can be changed at any time, including while the campaign runs. Changes apply to new tagging events only — contacts already routed are not re-evaluated.

If a contact is retried and their new call gets a different intent label, the rule for that new label takes over — so routing always reflects the latest outcome.

Starting a Campaign

From the Campaigns list or the campaign detail page, click Start Campaign.

A campaign cannot start until its Use Case Type is set. Legacy campaigns showing the "Review type" prompt must have a type chosen before they can be launched.

OliAI checks your organization's quota before starting. If you don't have enough remaining call minutes, the start will be blocked. See Billing & Usage.

Monitoring Progress

Open a running campaign to see the live progress dashboard:

MetricDescription
TotalTotal contacts in the audience
PendingNot yet called
In ProgressCurrently on a call
CompletedCall finished (any outcome)
FailedAll retry attempts exhausted
Deferred — Frequency CapCalls pushed to a later date by the frequency cap
% Complete(Completed + Failed) / Total

Frequency Cap

The frequency cap limits how often a single contact is called — an org-wide safeguard shared across every campaign, so a contact who appears in several campaigns is protected by one combined limit.

Org Admins configure it in Settings → Call Frequency Cap:

SettingDefaultDescription
Max calls per day3Per contact, per calendar day
Max calls per 7-day window7Per contact, rolling 7 days

Before every call — first attempt or retry — OliAI checks the contact's recent call count across all your campaigns:

  • Daily cap reached → the call is deferred to the next calendar day (in the contact's timezone if known, otherwise the campaign's).
  • Weekly cap reached → deferred until the rolling window frees a slot.

Deferred calls re-queue automatically and still respect the campaign's calling window on the new date. Each deferral is recorded on the call with a reason (Frequency Cap - Daily / Weekly), and the campaign dashboard's Deferred — Frequency Cap metric counts them.

Changes to the cap take effect immediately for future scheduling. Set a value to 0 to disable that limit. The cap counts by phone number, so duplicate contact records share one allowance.

Pausing and Resuming

  • Pause — Stops initiating new calls. Calls in progress complete normally.
  • Resume — Continues from where it left off, dialing remaining contacts.

Viewing Campaign Calls

In the campaign detail page, scroll to the Calls section to see every call attempt:

ColumnDescription
ContactName and phone number
StatusCOMPLETED, FAILED, IN_PROGRESS, etc.
IntentThe auto-assigned intent label (coloured badge), or Undetermined
AttemptsHow many times the call was tried
TranscriptAI-readable summary of the conversation
AudioPlayback of the recorded call

Click CSV in the Calls toolbar to download an enriched results export — every contact with their intent tag, status, timestamp and attempts.

Cancelling a Campaign

Click Cancel Campaign. This:

  • Stops all new dials immediately
  • Allows in-progress calls to finish
  • Sets the campaign to CANCELLED — it cannot be resumed
⚠️

Cancellation is permanent. If you might want to continue later, use Pause instead.

Call Audio Playback

For completed calls, click the Play button in the calls table to listen to the recording. Audio is a dual-track recording of both the customer and the AI.

Retry Policy

OliAI automatically retries calls that fail (no answer, busy, network errors). The Retry Policy panel on the campaign detail page lets you tune this per campaign.

SettingDescription
Maximum retries0–10 retries per contact (so up to 11 total attempts)
Delay scheduleSingle delay (one wait between every attempt, 30 min – 72 h) or Per-attempt (a different wait after each attempt, e.g. 1 h → 4 h → 24 h)
Retry only within the calling windowOn by default — retries outside the calling window are deferred to the next available slot. Turn off to allow retries any time.
Campaign endOptional deadline. A retry that would land after it is skipped and the contact marked Retry Expired.

The panel shows a plain-English summary of the policy, e.g.:

Up to 3 attempts. Wait 2 hours after attempt 1, 6 hours after attempt 2. Retries only within Mon–Fri 9:00–18:00.

Retry policy can be edited while the campaign is running — changes apply from the next retry cycle; contacts already in the retry queue are unaffected. It's campaign-scoped, so changing it on one campaign never affects another.

Edge cases

  • 0 retries — each contact gets a single attempt. A connected call is marked Completed; an unanswered one is marked Failed (its true outcome).
  • Retry Expired — if a retry would fall past the campaign's end date, it's skipped rather than dialed.

Calls are also not retried when a journey rule suppresses them, or when the contact is on Do Not Contact.

Best-time-to-call optimisation

Toggle Best-time-to-call optimisation in the Retry Policy panel to schedule each retry at the time a contact is most likely to answer — always inside the calling window. Off by default.

When on, OliAI picks a preferred hour band per contact, in order:

  1. Individual — their own answered-call history (needs ≥ 3 answered calls with some variation in time-of-day).
  2. Demographic — if individual data is thin, the answer patterns of similar contacts (same age band / city tier / language), provided the group is large enough.
  3. Default — otherwise the org's best-performing time band, or just the normal retry schedule.

The retry is placed in that band on the next valid day within the calling window; if the band never fits the window, the next valid slot is used instead. It still respects the frequency cap and the campaign's retry delay.

Best-time uses contact demographics — fill these in (or import them) to improve clustering. Each contact's computed window is shown on their profile (e.g. "Best time: 10–11 AM (Individual, based on 5 calls)"). Every scheduling decision is logged for future ML.

Customer-requested callbacks

When a contact asks to be called back at a specific time, OliAI can capture that during the call and automatically schedule the next attempt then.

Mark a callback variable on the flow

In the flow's Variables panel, tick Callback request on the variable that records the requested time. This tells OliAI which captured field to read.

Talk to the contact

If the call connects and the contact gives a time ("call me tomorrow at 4pm"), OliAI extracts it from the transcript after the call — resolving relative phrases against the call's end time and the campaign timezone.

The next attempt is scheduled

The follow-up call is placed at the requested time:

  • Inside the calling window → scheduled exactly then.
  • Outside the window → moved to the next valid slot and marked (adjusted).
  • Past the campaign end date → marked Callback Expired (Failed) instead of dialing.

A callback always counts as an attempt and is honoured even if the contact is already at the max-retries cap. If the time is ambiguous, OliAI falls back to the standard retry delay.

The campaign call log shows Callback: <time> (with an (adjusted) note when moved) and a Mark fulfilled action to close it out manually — fulfilled callbacks are skipped by the dialer. The scheduled time is also included in the write-back payload as callback_time.

Real-time campaign dashboard

The Campaigns list page is a live operations view across all your campaigns. While any campaign is In Progress or Paused, it auto-refreshes every 30 seconds; a Live · updated Xs ago indicator shows freshness (turning amber with a stale warning if an update is overdue). A manual Refresh button and use-case / status filters are at the top.

An organization summary sits above the list:

CardDescription
Active campaignsCampaigns currently In Progress
Calls todayDials placed across the org since midnight (UTC)
Contacts reached todayDistinct contacts dialed today
CompletedCampaigns in the Completed state

Each campaign card adds a strip of real-time metrics:

MetricDescription
Calls attemptedTotal dial attempts across the audience
Connection rateConnected ÷ resolved (connected + failed) calls
PositiveShare of connected calls tagged with a positive intent label, with the count
Retry queuePending retries still scheduled, plus the next retry time
Intent splitA colour bar breaking down outcomes by intent label
HealthA Green / Amber / Red badge summarising campaign health

The health badge flags campaigns that need attention — for example Low connection rate, Few positive outcomes, or Awaiting more results before enough calls have resolved to judge. Hover (or read the line under the metrics) for the reason.