The double-gate
Callback detection only activates when both switches are on:Bot: callback_prompt_injection
The bot has its callback toggle enabled. This injects the callback-detection instructions into the post-call analysis prompt so the LLM emits callback fields.
bot.callback_prompt_injection and campaign.config.callback_detection.enabled. Enabling one without the other does nothing.
What the bot extracts
When detection is active, post-call analysis emits these standard keys:| Field | Meaning |
|---|---|
callback_requested | true if the customer asked to be called back, or the bot promised to call back. |
callback_preferred_time_text | The customer’s exact words about when (e.g. “5 min baad”, “kal subah”, “shaam ko”). |
callback_reason | Short reason (e.g. “busy”, “driving”, “not free”). |
callback_confidence | 0.0–1.0 (≈0.95 clear request, ≈0.8 implied). |
callback_requested is true.
Time resolution
CXB API converts the free-text time into a concrete scheduled time in the campaign timezone (resolve_callback_time):
- Relative phrases (“30 min”, “half an hour”, “2 hours”, “aadhe ghante”) add to the current time.
- Day markers (“kal”/tomorrow, “parso”/day-after) and dayparts (“subah”/morning ≈ 10:00, “shaam”/evening ≈ 18:00) set the target day/time.
- If no clear time is given, it falls back to the retry delay.
- The resolved time is always clipped into the campaign’s calling window. Times outside the window move to the next valid window.
Scheduling and priority
A scheduled callback puts the contact into thecallback_scheduled state with a due time (next_retry_at). When that time arrives, CXB Dialler leases it before fresh pending contacts and before retries:
kind="callback", with a callback_sequence) and the bot receives callback context (callback_preferred_time_text, callback_reason) in the connected event so it can open appropriately.
Single-day window cancellation
For asingle_day campaign, when the calling window ends any still-waiting callback_scheduled contacts are cancelled — moved to window_closed with callback.status = "cancelled" and counted in callback_cancelled. They are not carried over.
Callback stats
The campaign tracks callbacks separately from ordinary retries:| Stat | Meaning |
|---|---|
callback_pending | Scheduled and waiting to be dialled. |
callback_completed | Callback attempts that reached a terminal state. |
callback_cancelled | Cancelled (e.g. single-day window closed before due). |
callback_exhausted | Ran out of attempts. |
A callback that fails on a retryable outcome is re-scheduled back into
callback_scheduled (not retry_scheduled), so it keeps top priority. When it exhausts attempts or is torn down (e.g. amd_machine, abandoned), the callback is closed and the counters update.Ops checklist
- Bot callback toggle enabled.
- Campaign callback detection enabled.
- Post-call analysis prompt actually emits the callback keys (run a test call asking to be called back).
- Campaign timezone is the customer’s contactable timezone (callback times are clipped to its window).
- Watch
callback_pending/callback_completedon the campaign to confirm callbacks are firing.