API reference

Queues

A queue holds callers, first in, first out, until another call takes them. A caller joins with <Enqueue>. An agent's call takes the next caller with <Dial><Queue>name</Queue></Dial>. Queues live entirely in your markup: there is no queues REST API, and Connect sends no queue callbacks.

Connect is live. The API is v0.x, so field names may change before v1.

<Enqueue> attributes

<Enqueue> ends the document: verbs after it do not run. When maxWait runs out, the caller leaves the queue. Enqueue has no action URL, so plan for the call to end there.

AttributeTypeDescription
(body)requiredstringThe queue name, for example sales. Callers who enqueue with the same name wait in the same queue. A queue exists as soon as someone joins it; there is nothing to create first.
waitUrlurlConnect fetches this once when the caller joins and loops the Say, Play and Wait verbs it returns until the caller is picked up. Other verbs are ignored. Without a waitUrl, or if it fails, the caller hears music on hold.
waitMethodPOST | GETHTTP method for waitUrl. Defaults to POST.
maxWaitintegerSeconds the caller can wait before Connect takes them out of the queue. Defaults to 300 (5 minutes).

Pick queue names that are unique to you, for example with your own account or team ID in them.

Taking the next caller

Any call whose markup runs <Dial><Queue>sales</Queue></Dial> is bridged to the caller who has waited longest in sales. That can be an agent dialling in to a number, or a call you place to the agent with POST /api/calls. When either side hangs up, the other side is hung up too.

If nobody is waiting, the Dial ends at once. Set an action on the <Dial> to hear about it: Connect POSTs DialCallStatus (no-answer for an empty queue, failed if the bridge could not be made) and runs the markup you return.

Dial action → your endpoint
// POST https://your.app/voice/after-queue
// X-CPaaS-Event: dial.queue.action
{
  "DialCallStatus": "no-answer",
  "DialCallDuration": 0
}

Example

The caller's webhook puts them in the queue; the agent's webhook takes them out. The JSON form supports enqueue and dial with a queueName; it has no waitMethod, so the waitUrl is always fetched with POST.

Caller and agent markup
<!-- Caller: wait in the "sales" queue -->
<Response>
  <Say>Please hold for the next available agent.</Say>
  <Enqueue waitUrl="https://your.app/voice/hold" maxWait="300">sales</Enqueue>
</Response>

<!-- Agent: take the next caller from "sales" -->
<Response>
  <Dial action="https://your.app/voice/after-queue">
    <Queue>sales</Queue>
  </Dial>
</Response>
200 ok

The waitUrl returns what the caller hears while they wait. It is played from the top again each time it ends.

waitUrl reply
<!-- https://your.app/voice/hold -->
<Response>
  <Say>Thanks for waiting. An agent will be with you shortly.</Say>
  <Play>https://your.app/audio/hold-music.wav</Play>
</Response>
200 ok

Every verb and attribute is in Call-control markup. For a room where several people talk at once, use Conferences.