Callback Request
One time. Any idle agent. Nobody dials it early.
A callback is a time-gated pool lead. CRM sends callback_scheduled_at on a callback priority (seeded as id 2). When due, any idle ready agent may claim it. Master has no agent_id pin. Field shapes are in the API reference.
End-to-end flow
The row sits as Callback until the time is due. Claim starts when any idle agent is panel-active, ready, and AMI idle.
- POST callback_scheduled_at on a callback priority (id 2)
- Store Callback (no employee pin)
- Wait until the time is due (skips working hours)
- Any idle ready agent claims it
- Progressive: AMI to that desk. Predictive: customer first, then any idle bridge
Push
callback_scheduled_at is only for callback priorities (is_callback = 1, seeded as id 2) on POST. Extra keys such as agent_id are rejected. Tickets already on priority_id 8 use PUT /api/escalated-tickets to Close or Callback Schedule — that path does not go through this push body.
| Body | Result |
|---|---|
| Time on callback priority (id 2) | Stored. dial_status = Callback. |
| Time on any other priority | 400 callback_scheduled_at is only allowed for callback priorities |
agent_id present | 400 extra field rejected |
Accepted times: 2026-08-20 15:30:00 or ISO-8601, including past datetimes (due immediately). Rejected: date-only. Other priority_id values cannot send a time on this POST.
curl -sS -X POST https://YOUR_HOST/api/leads \
-H "Authorization: Bearer YOUR_WS_SECRET" \
-H "Content-Type: application/json" \
-d '{
"oli_id": "OLI124",
"phone_number": "9876543211",
"client_name": "B",
"form_type": "GST",
"priority_id": 2,
"callback_scheduled_at": "2026-08-20 15:30:00"
}'
Wait until due
Both engines skip a lead while callback_scheduled_at is in the future. Until then the row stays unreserved. When the time is null or <= NOW(), it can be claimed. A due callback skips the working-hours gate, so a 20:00 CRM time is originated even if work_end is 18:30. After a later Not Connected, the [2,2,2,2] scheduler resumes.
Any idle agent
form_type is stored only. Any idle agent may claim it.Master has no
agent_id.Panel active, presence ready, AMI idle, wrap finished. If nobody is free, the lead waits.
Progressive vs Predictive
| Progressive | Predictive | |
|---|---|---|
| When claimed | Next in that agent’s claimNextLead queue | When any agent is idle, via claimNextForPool |
| Overdial pool | Same as other hold leads | In the pool when due. Bridged to any idle agent |
| Originate | AMI to the claiming extension | Customer first, then Bridge to any idle extension |
| If agent busy after answer | N/A (agent-first) | Hold until any idle agent is free, or Abandoned if the customer hangs up |
Hangup and retry
| Outcome | Status | Next |
|---|---|---|
Talked (ANSWER) | Received | Never |
| No answer / busy / congestion | Not Connected | [2,2,2,2] + working hours |
call_count reaches max_tries | Archived | Moved to hold_dialer_disposed |
| Reject / customer cancel | Rejected | Never |
| Customer left while waiting | Abandoned | Retry in 5 minutes |
Failed originate restores the previous status and clears reserve without incrementing call_count. Received / Rejected are not claimed. Finally disposed leads are not on master. Not Connected uses retry_pattern default [2,2,2,2]. A due callback_scheduled_at is originated even after hours. Archive only when Not Connected call_count reaches max_tries. Abandoned retries in 5 minutes.