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.

priority_id 2 (is_callback) callback_scheduled_at Any idle agent when due [2,2,2,2] after no-answer

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.

  1. POST callback_scheduled_at on a callback priority (id 2)
  2. Store Callback (no employee pin)
  3. Wait until the time is due (skips working hours)
  4. Any idle ready agent claims it
  5. 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.

BodyResult
Time on callback priority (id 2)Stored. dial_status = Callback.
Time on any other priority400 callback_scheduled_at is only allowed for callback priorities
agent_id present400 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

1
No skill filter
form_type is stored only. Any idle agent may claim it.
2
No employee pin
Master has no agent_id.
3
Still eligible
Panel active, presence ready, AMI idle, wrap finished. If nobody is free, the lead waits.

Progressive vs Predictive

ProgressivePredictive
When claimedNext in that agent’s claimNextLead queueWhen any agent is idle, via claimNextForPool
Overdial poolSame as other hold leadsIn the pool when due. Bridged to any idle agent
OriginateAMI to the claiming extensionCustomer first, then Bridge to any idle extension
If agent busy after answerN/A (agent-first)Hold until any idle agent is free, or Abandoned if the customer hangs up

Hangup and retry

OutcomeStatusNext
Talked (ANSWER)ReceivedNever
No answer / busy / congestionNot Connected[2,2,2,2] + working hours
call_count reaches max_triesArchivedMoved to hold_dialer_disposed
Reject / customer cancelRejectedNever
Customer left while waitingAbandonedRetry 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.