Calls by API: commands and voice

Calls on the key’s lines

  • GET /calls/ — calls ringing or going on now, newest first (up to 100).
  • GET /calls/<id>/ — one call.
  • POST /calls/ — place a call from a line to a 7–15 digit number, example below.
  • GET /operators/?channel_id=12 — the company’s people a call can be routed to.
curl -X POST https://dialogs.tehprof.kz/api/v1/gw/calls/ \
  -H "Authorization: Bearer gw_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "channel_id": 12, "number": "77001234567" }'

{ "id": 5310, "channel_id": 12, "direction": "out",
  "phase": "starting", "active": true, "yours": true, ... }

Commands to a call

RequestWhen
POST /calls/<id>/accept/The call is ringing and nobody’s yet, or an operator handed it to the program
POST /calls/<id>/reject/The call is ringing
POST /calls/<id>/hangup/The call belongs to your key
POST /calls/<id>/transfer/Your key’s call in conversation: an incoming call the program took, or an outgoing one once the client answered
POST /calls/<id>/route/ with { "operator_id": … }The call still rings for the line’s people: this employee gets it first, then the line’s usual route goes on

After transfer the client hears the ringback, the line’s people’s phones ring and the program’s voice connection closes.

An outgoing call stays outgoing after the transfer: direction is out, answered is true, phase is ringing again.

Call fields

  • id, channel_id, conversation_id, peer — the client’s number or messenger id.
  • direction — in or out; active — the call is still going on.
  • phase — starting, ringing, accepting, active, ending, ended, rejected, missed, failed.
  • yours — the call belongs to your key: the program may speak in it and end it.
  • answered — somebody already talked in the call. If such a call rings again, it was handed on, it is not a new call.
  • forward — the line rings the employees’ phones: state (ringing, taken, missed) and taken_by — the employee’s name. The employee’s number is never given.
  • started_at, ended_at, duration_sec — talk time once the call ended; end_reason.
  • repeat — whether the client called this line before, see Call history.

Voice: speak and listen

  1. Ask for a ticket: POST /calls/<id>/voice/ — for a call of your key. The answer has url and expires_in (seconds).
  2. While the ticket is valid, open a WebSocket to wss://dialogs.tehprof.kz + url.
  3. Send your sound in binary messages — the client’s sound comes the same way.

You will see: url and expires_in in the ticket reply, and once the WebSocket connects, the customer’s audio as binary messages.

  • The format both ways is 16-bit PCM (little-endian), 16 kHz, mono. A message has an even length of at most 64 KiB.
  • Up to 2 seconds of sound may be sent ahead. The rest is dropped and the text dropped <ms> comes back.
  • The text flush drops what was sent and not said yet: the program goes quiet at once when the client interrupts.
  • One voice connection per call.
Close codeMeaning
1000The call ended
4400A wrong piece of sound: odd length or over 64 KiB
4403The key lost the permission or the call is no longer yours
4410The connection to the messenger dropped

Events

On a webhook. A key with calls:voice and webhooks:manage gets the call events of its lines at the registered address, with the same X-Dialogs-Signature-V2 signature. The body is { "calls": [ … ] }.

EventWhen
call.ringingAn incoming call rings, a call was handed to your key, or it rings for the line’s people again
call.updatedThe call was taken, handed on, or its owner changed
call.endedThe call ended, the reason is in end_reason
call.analysedThe call summary from the recording is ready: field behaviour (webhook only)

An event has event, call_id, channel_id, conversation_id, peer, direction, phase, active, end_reason, answered, occurred_at and owner — whose call it is: operator, program (with owner_key_prefix — which key), forward (the line rings the employees’ phones), line (an office PBX, for example) or empty.

{ "calls": [ {
  "event": "call.ringing", "call_id": "5311", "channel_id": "12",
  "conversation_id": "9021", "peer": "77001234567",
  "direction": "in", "phase": "ringing", "active": true,
  "answered": false, "end_reason": "", "owner": "",
  "owner_key_prefix": "", "occurred_at": "2026-11-13T09:15:02.118000+00:00"
} ] }

Without a server of your own. Ask GET /calls/ once a second and compare with the previous answer — that is what api.calls.watch() in the SDK does.

A webhook gets events even while the program is not running: no call gets lost.

Install TehProf Dialogs in your CRM

Installing the app and connecting WhatsApp by QR code are free. The line subscription is billed separately.