Callion — Integratsiya API (chiquvchi webhook)
Hujjat versiyasi: 2026-07-21. O'zgarishlar 9-bo'lim (Versiyalash) qoidalariga muvofiq e'lon qilinadi.
Ushbu hujjat Callion qo'ng'iroq tugagach sizning endpointingizga yuboradigan hodisani tavsiflaydi. U Callion qo'ng'iroq ma'lumotlarini olishni istagan har qanday tashqi tizim uchun — CRM, BI, analitika platformasi yoki hamkor xizmati uchun — mo'ljallangan. Model universal: siz chiquvchi webhook URL manzilini sozlaysiz (va ixtiyoriy ravishda o'zingiz tanlagan avtorizatsiya sarlavhasi yoki parametrini), Callion har bir qo'ng'iroq tugagach unga JSON bilan POST so'rov yuboradi, siz esa 2xx kodi bilan javob berasiz.
1. Maqsad
Callion sizning endpointingizga qo'ng'iroq tugagan payt bitta hodisa — call_end — yuboradi. U suhbatning yakuniy ma'lumotlarini o'z ichiga oladi: yo'nalish, raqamlar, operator, davomiylik, natija, operator tegi, boshlanish vaqti va yozuv havolasi.
- Yetkazish asinxron bo'lib, qo'ng'iroq trakti tashqarisida amalga oshiriladi. Sizning endpointingizning javobi (yoki uning yo'qligi) qo'ng'iroq ishlashiga hech qanday ta'sir qilmaydi — hodisa yuborilgan paytda qo'ng'iroq allaqachon tugagan bo'ladi.
- Hodisa qo'ng'iroq tugagach yuboriladi, suhbat davomida real vaqtda emas.
- Sizning vazifangiz — POST so'rovni qabul qilish, uni tez 2xx kodi bilan tasdiqlash va ma'lumotlarni o'z fon jarayoningizda qayta ishlash.
Qamrov — qaysi qo'ng'iroqlar yuborilmaydi. Har bir tashqi qo'ng'iroq (kiruvchi va chiquvchi) tugagach bitta hodisa yuboriladi, quyidagilar bundan mustasno:
- ichki (ichki raqamdan ichki raqamga) qo'ng'iroqlar;
- backend qayta ishga tushishi tufayli o'rtada uzilib qolgan qo'ng'iroqlar;
- tashqi abonent raqami 6 ta raqamdan kam bo'lgan qo'ng'iroqlar — bunga yashirilgan/anonim raqamlar va operator qisqa kodlari kiradi.
Shu sababli hodisalar soningiz CDR eksporti bilan aynan mos kelmasligi mumkin; agar to'liq moslik kerak bo'lsa, bu istisnolarni hisobga oling.
Bu integratsiya turi. Ushbu hujjat qo'ng'iroq-hodisalari webhook integratsiyasi uchun. Admin panelida "+" tugmasi orqali Webhook turini qo'shsangiz (URL va ixtiyoriy maxfiy kalit), aynan shu hujjatdagi call_end kontrakti yetkaziladi. amoCRM/Bitrix24 kabi nomli integratsiyalar shu hodisalar ustidagi presetlardir.
2. Transport va autentifikatsiya
| Parametr | Qiymat |
|---|
| Metod | POST |
| Content-Type | application/json |
| Protokol | HTTPS (majburiy) |
| Tana | Hodisaning JSON obyekti (3-bo'limga qarang) |
| Kodlash | UTF-8 |
Autentifikatsiya. Maxfiy qiymatni webhookni sozlashda o'zingiz belgilaysiz va Callion uni har bir so'rov bilan o'zgarishsiz uzatadi. Ikki usul mavjud:
- Sarlavha orqali (sukut bo'yicha). Qo'shimcha sarlavha sozlamasangiz, Callion maxfiy qiymatni
x-api-key sarlavhasida yuboradi. Xohlasangiz, o'zingiz tanlagan sarlavha(lar)ni sozlashingiz mumkin — masalan Authorization: Bearer <qiymat> — u holda Callion aynan siz belgilagan sarlavhalarni yuboradi (bu holda x-api-key qo'shilmaydi). - URL parametri orqali. Maxfiy qiymatni webhook URL manzilingizdagi so'rov qatori parametriga joylashtiring; URL o'zgarishsiz uzatiladi.
Bu maxfiy qiymatni o'z tomoningizda tekshiring va usiz kelgan so'rovlarni rad eting.
Manba IP. So'rovlar Callion infratuzilmasidan keladi. Agar kiruvchi trafikni IP bo'yicha cheklasangiz, Callion'dan chiquvchi manzillarning joriy ro'yxatini so'rang va uni ruxsat ro'yxatiga kiriting. IP'ga yagona autentifikatsiya mexanizmi sifatida tayanmang — webhook sozlamasidagi maxfiy qiymatdan foydalaning.
3. Hodisa konverti
Haqiqiy hodisa namunasi (kiruvchi, javobsiz):
{
"event": "call_end",
"event_id": "1700000000.123",
"call_id": "1700000000.123",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": null,
"operator_name": null,
"duration": 0,
"status": "CANCEL",
"disposition": null,
"started_at": 1700000000,
"recording_url": null
}
Tana — yassi JSON obyekti. Versiya 1 maydonlari 4-bo'limda keltirilgan.
4. Maydonlar jadvali
Versiya 1 hozirda quyidagi 13 ta maydonni o'z ichiga oladi. 9-bo'limga muvofiq, kelajakda versiyani o'zgartirmasdan yangi maydonlar qo'shilishi mumkin, shuning uchun parseringiz noma'lum maydonlarni e'tiborsiz qoldirsin va JSON kalitlar tartibiga tayanmasin.
| Maydon | Turi | Null bo'la olishi | Namuna | Qachon yo'q / null |
|---|
event | string | null emas | "call_end" | Doim mavjud; doim "call_end". |
event_id | string | null emas | "1700000000.123" | Doim mavjud. Hodisaning noyob identifikatori, qayta yetkazishlarda barqaror; dedublikatsiya kaliti sifatida ishlating. |
call_id | string | null emas | "1700000000.123" | Doim mavjud. Qo'ng'iroqning noyob identifikatori; event_id ga teng. |
version | integer | null emas | 1 | Doim mavjud. Tana tuzilmasi versiyasi (hozir 1). |
direction | string | null emas | "incoming" | Doim mavjud. "incoming" / "outgoing" dan biri. |
client_number | string | null | null bo'la oladi | "998901234567" | Mijoz raqami mavjud bo'lmasa null. |
operator_number | string | null | null bo'la oladi | "1001" | Qatnashgan operatorning ichki raqami. Kiruvchida — javob bergan operator (javob berilmagan bo'lsa null). Chiquvchida — qo'ng'iroq qilgan operator (javob berilmagan bo'lsa ham mavjud). |
operator_name | string | null | null bo'la oladi | "Aliyeva N." | operator_number bilan bir xil shart bo'yicha; operatorning ko'rinadigan ismi bo'lmasa null. |
duration | integer | null emas | 205 | Suhbat soniyalari (billsec). Javob berilmagan bo'lsa 0. |
status | string | null | null bo'la oladi | "ANSWERED" | Qo'ng'iroq natijasi. Noshaffof satr — enum bo'yicha tekshirmang. |
disposition | string | null | null bo'la oladi | "sale" | Operatorning qo'ng'iroqdan keyingi tegi; teg qo'yilmagan bo'lsa null. |
started_at | integer | null | null bo'la oladi | 1700000000 | Qo'ng'iroq boshlanish vaqti, UNIX vaqti soniyalarda; mavjud bo'lmasa null. |
recording_url | string | null | null bo'la oladi | "https://<callion-host>/rec/<token>" | Yozuvga to'g'ridan-to'g'ri havola; yozuv bo'lmasa null. |
Semantik izohlar
- Raqamlar yo'nalishga bog'liq.
client_number — bu mijozning (tashqi abonent) raqami, yo'nalishdan qat'i nazar. operator_number — bu operatorning ichki ichki raqami (extension). "Kim kimga qo'ng'iroq qildi" ma'nosi direction maydoni bilan aniqlanadi: "incoming" da mijoz kompaniyaga qo'ng'iroq qiladi, "outgoing" da operator mijozga qo'ng'iroq qiladi. - Raqam formati aralash. Raqamlar qanday olingan bo'lsa, shundayligicha uzatiladi va E.164 ga normallashtirilmaydi. Bu davlat kodli raqam, mahalliy ichki raqam va hokazo bo'lishi mumkin. Raqam doim xalqaro formatda deb hisoblamang — kerak bo'lsa, o'z tomoningizda normallashtiring.
- Operator maydonlari yo'nalishga bog'liq — "javob berilgan" degani emas. Kiruvchi qo'ng'iroqda operator maydonlari javob bergan operatorni ko'rsatadi va javob berilmagan bo'lsa null bo'ladi. Chiquvchi qo'ng'iroqda esa ular qo'ng'iroq qilgan operatorni ko'rsatadi va qo'ng'iroqqa javob berilmagan taqdirda ham mavjud bo'ladi. Shu sababli operator maydonining bo'sh emasligiga qarab "javob berilgan" degan xulosa chiqarmang — javob berilganini
status (ANSWERED) va duration (> 0) orqali aniqlang. status — noshaffof satr. Uni noshaffof qiymat sifatida qayta ishlang va notanish qiymat tufayli hodisani rad etmang. Ma'lumot uchun quyidagi 12 ta qiymat bo'lishi mumkin: ANSWERED, NO ANSWER, BUSY, CANCEL, CONGESTION, CHANUNAVAIL, FAILED, VOICEMAIL, MISSED, REJECTED, TRANSFERRED, UNKNOWN. Ro'yxat ma'lumot sifatida keltirilgan — qiymatlar to'plami kengayishi mumkin; validatsiyani unga bog'lamang.disposition — operator tegi. 6 ta qiymatdan biri: sale, callback, no_answer, wrong_number, not_interested, info_given — yoki operator teg qo'ymagan bo'lsa null.started_at — UNIX vaqti soniyalarda (millisekundlarda emas).call_id event_id ga teng. Ikkalasi ham bitta qo'ng'iroqni identifikatsiya qiladi; istalganini kalit sifatida ishlatishingiz mumkin.
5. Hodisalar
Faqat call_end hodisasi yetkaziladi. Ushbu kanal orqali boshqa hodisa turlari yo'q. Shunga qaramay, event maydonini tekshiring — bu kelajakda yangi turlar qo'shilishi ehtimoliga qarshi obro'yingizni mos saqlaydi.
6. Yozuv havolasi
recording_url maydoni — suhbat yozuvi fayliga to'g'ridan-to'g'ri HTTPS havola.
- Format: WAV, 8 kGts, mono.
- Hajm: odatda taxminan 1 MB; hech qachon 50 MB dan oshmaydi.
- Range so'rovlari qo'llab-quvvatlanadi — faylni qismlarga bo'lib yuklab olish mumkin.
- Kechikish. Havola qo'ng'iroq tugaganidan keyin biroz vaqt o'tib mavjud bo'ladi — hodisa kelishi va yozuv tayyor bo'lishi orasidagi qisqa kechikishni hisobga oling. Agar
recording_url null bo'lmasa, lekin fayl hali tayyor bo'lmasa, qisqa interval orqali yuklashni takrorlang. - Havola taxmin qilib bo'lmaydigan va muddati o'tadigan. URL'ni oldindan bilib bo'lmaydi va u cheklangan muddat amal qiladi (sukut bo'yicha 7 kun, muddat sozlanadi).
- Yozuvni sinash. Ulanishni tekshirish uchun yuborilgan sinov hodisasining
recording_url maydoni ishlaydigan namuna yozuvga (qisqa sukut fayli) ishora qiladi — uni yuklab, o'z yozuv-yuklash oqimingizni tasdiqlashingiz mumkin.
Havola bilan ishlash bo'yicha tavsiyalar:
- Yozuvni havola amal qilish muddati ichida o'z tomoningizga yuklab oling va saqlang. Muddat tugagach havola ishlamay qoladi.
- Yozuv URL'ini loglamang, uzatmang va e'lon qilmang. Uni maxfiy deb hisoblang: havolaga ega har kim u amal qilar ekan, yozuvni yuklab olishi mumkin.
- Agar yozuv bo'lmasa (masalan, qo'ng'iroqqa javob berilmagan),
recording_url null bo'ladi.
7. Yetkazish semantikasi
- Kamida bir marta (at-least-once). Bitta hodisa qayta kelishi mumkin (masalan, sizning endpointingiz yetkazishni o'z vaqtida tasdiqlamasa). Dedublikatsiya uchun
event_id dan foydalaning — qayta yetkazishda u barqaror. - Qayta urinishlar jadvali. Vaqtinchalik xato bo'lsa, Callion yuborishni 6 martagacha takrorlaydi. Urinishlar orasidagi kechikish o'sib boradi: 1s, 5s, 30s, 5 daqiqa, 30 daqiqa, 2 soat. Shundan so'ng hodisa tashlanadi.
- Taymout. Har bir urinishda 10 soniyalik umumiy vaqt budjeti (DNS + ulanish + TLS + so'rov + javob) va 5 soniyalik soket-faoliyatsizlik chegarasi amal qiladi; qaysi biri birinchi ishga tushsa, urinish tugaydi. Taymout vaqtinchalik xato hisoblanadi va qayta uriniladi.
- Tartib kafolatlanmaydi. Hodisalar qo'ng'iroqlar tugagan tartibda kelmasligi mumkin. Yetkazish tartibiga tayanmang —
started_at bo'yicha saralang. - Yozuvli qo'ng'iroqlar. Javob berilgan qo'ng'iroqda birinchi urinish yozuv havolasi tayyorlanguncha taxminan 90 soniyaga kechiktirilishi mumkin; bu 6 urinishdan bittasini sarflashi mumkin.
- Tez javob bering. Qabulni 2xx kodi bilan imkon qadar tez tasdiqlang va qayta ishlashni fonda asinxron bajaring. Uzoq javob taymout va qayta yetkazish xavfini oshiradi.
8. Javob va xatolar
Sizning endpointingiz qabulni 2xx kodi bilan tasdiqlashi kerak. Callion'ning javobingizga qarab xatti-harakati:
| Endpointingiz javobi | Talqin | Callion harakati |
|---|
2xx | Yetkazildi | Hodisa qabul qilingan hisoblanadi; takror bo'lmaydi. |
3xx | Qayta yo'naltirish | Qayta yo'naltirishlar kuzatilmaydi. Endpoint URL bevosita 2xx bilan javob berishi kerak. 3xx doimiy xato hisoblanadi va takrorlanmaydi. |
4xx | Endpoint rad etdi | Doimiy xato (noto'g'ri avtorizatsiya, yo'l yoki validatsiya); takrorlanmaydi. URL va maxfiy qiymat sozlamasini tekshiring. |
5xx | Vaqtinchalik server xatosi | Vaqtinchalik xato; javob tanasi bor-yo'qligidan qat'i nazar qayta uriniladi (yuqoridagi jadval bo'yicha). |
| Taymout / javob yo'q / ulanish xatosi | Yetkazish tasdiqlanmadi | Vaqtinchalik xato; qayta uriniladi. |
Callion sizning javob tanangizdan foydalanmaydi — faqat HTTP kodi muhim. Barcha urinishlar tugagach yoki doimiy xato (4xx/3xx) bo'lgach, hodisa tashlanadi — qayta so'rash uchun alohida API yo'q, shuning uchun yetkazishga ishonchli tayanish uchun event_id bilan dedublikatsiya qiling va yozuvni muddat ichida yuklab oling.
9. Versiyalash
version maydoni hodisa tuzilmasi versiyasini ko'rsatadi (hozir 1).- O'zgarishlar faqat qo'shimcha (additive): yangi maydonlar versiyani o'zgartirmasdan qo'shilishi mumkin.
- Noma'lum maydonlarni e'tiborsiz qoldiring, rad etmang. Sizning parseringiz ushbu hujjatda yo'q maydonlarni xato deb hisoblamasdan o'tkazib yuborishi kerak. Bu kelajakda maydonlar qo'shilganda moslikni kafolatlaydi.
version qiymatining o'zgarishi tuzilmadagi mos kelmaydigan o'zgarishni bildiradi va oldindan e'lon qilinadi.
10. Ilova — namunalar
10.1. Javob berilgan qo'ng'iroq, yozuv bilan
Kiruvchi qo'ng'iroq, operator javob berdi, suhbat 205 soniya, operator sale tegini qo'ydi, yozuv mavjud.
{
"event": "call_end",
"event_id": "1700000500.42",
"call_id": "1700000500.42",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": "1001",
"operator_name": "Aliyeva N.",
"duration": 205,
"status": "ANSWERED",
"disposition": "sale",
"started_at": 1700000500,
"recording_url": "https://<callion-host>/rec/<token>"
}
Maydonma-maydon:
event — "call_end", hodisa turi.event_id — "1700000500.42", dedublikatsiya kaliti.call_id — "1700000500.42", event_id ga teng.version — 1.direction — "incoming", qo'ng'iroq kiruvchi.client_number — "998901234567", mijoz raqami.operator_number — "1001", javob bergan operatorning ichki raqami.operator_name — "Aliyeva N.", operator ismi (qo'ng'iroqqa javob berilgani uchun mavjud).duration — 205, suhbat soniyalari.status — "ANSWERED", qo'ng'iroqqa javob berilgan.disposition — "sale", operator tegi.started_at — 1700000500, boshlanish vaqti (UNIX vaqti soniyalarda).recording_url — WAV ga to'g'ridan-to'g'ri HTTPS havola; muddat ichida yuklab oling.
10.2. Javob berilmagan qo'ng'iroq, yozuvsiz
Kiruvchi qo'ng'iroq, javobdan oldin bekor qilingan: operator tayinlanmagan, davomiylik 0, teg yo'q, yozuv yo'q.
{
"event": "call_end",
"event_id": "1700000000.123",
"call_id": "1700000000.123",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": null,
"operator_name": null,
"duration": 0,
"status": "CANCEL",
"disposition": null,
"started_at": 1700000000,
"recording_url": null
}
Maydonma-maydon:
event — "call_end", hodisa turi.event_id — "1700000000.123", dedublikatsiya kaliti.call_id — "1700000000.123", event_id ga teng.version — 1.direction — "incoming", qo'ng'iroq kiruvchi.client_number — "998901234567", mijoz raqami.operator_number — null, qo'ng'iroqqa javob berilmagan, operator tayinlanmagan.operator_name — null, xuddi shu sababga ko'ra.duration — 0, suhbat bo'lmagan.status — "CANCEL", qo'ng'iroq javobdan oldin bekor qilingan.disposition — null, teg qo'yilmagan.started_at — 1700000000, boshlanish vaqti (UNIX vaqti soniyalarda).recording_url — null, yozuv yo'q.
11. Operatsiyalar
- Maxfiy qiymatni yangilash. Yangi qiymatni integratsiya sozlamasida belgilaysiz. Avtomatik ustma-ust (overlap) oyna yo'q, shuning uchun yangilashni past yuklama davrida bajaring va endpointingiz eski va yangi qiymatning ikkalasini qisqa muddat qabul qilishiga tayyor bo'ling.
- Manba IP. So'rovlar Callion infratuzilmasidan keladi. IP bo'yicha cheklasangiz, chiquvchi manzillarning joriy ro'yxatini Callion aloqa nuqtangizdan so'rang (ro'yxat vaqti-vaqti bilan o'zgarishi mumkin). IP'ga yagona mexanizm sifatida tayanmang.
- Xatolarning ko'rinishi. Barcha urinishlardan so'ng yetkazilmagan hodisa Callion operatori uchun integratsiya loglarida saqlanish muddati davomida ko'rinadi. Hamkorga qaratilgan alohida xato-lentasi hozircha yo'q — yetkazishga ishonchli tayanish uchun
event_id bilan dedublikatsiya qiling. - Versiyalar va o'zgarishlar. Mos kelmaydigan o'zgarish
version qiymatini oshiradi va oldindan e'lon qilinadi (9-bo'lim). Ushbu hujjat yuqorida sana bilan belgilangan. - Aloqa. Integratsiya bo'yicha savollar uchun Callion aloqa nuqtangizga murojaat qiling.
Callion — API интеграции (исходящий вебхук)
Версия документа: 2026-07-21. Изменения анонсируются по правилам раздела 9 (Версионирование).
Документ описывает событие, которое Callion отправляет на ваш эндпоинт по завершении звонка. Он предназначен для любой внешней системы — CRM, BI, аналитической платформы или партнёрского сервиса, — которая хочет получать данные о звонках Callion. Модель универсальна: вы настраиваете URL исходящего вебхука (и, по желанию, свой заголовок авторизации или параметр), Callion отправляет на него POST-запрос с JSON по завершении каждого звонка, а вы отвечаете кодом 2xx.
1. Назначение
Callion отправляет вашему эндпоинту одно событие — call_end — в момент завершения звонка. Оно содержит итоговые данные разговора: направление, номера, оператора, длительность, результат, тег оператора, время начала и ссылку на запись.
- Доставка асинхронная и происходит вне тракта звонка. Ответ вашего эндпоинта (или его отсутствие) никак не влияет на обработку звонка — к моменту отправки события звонок уже завершён.
- Событие отправляется по завершении звонка, а не в реальном времени во время разговора.
- Ваша задача — принять POST-запрос, быстро подтвердить его кодом 2xx и обработать данные в своём фоновом процессе.
Охват — какие звонки НЕ отправляются. По завершении каждого внешнего звонка (входящего и исходящего) отправляется одно событие, за исключением:
- внутренних (extension-to-extension) звонков;
- звонков, прерванных перезапуском backend в середине;
- звонков, у которых номер внешнего абонента короче 6 цифр — сюда входят скрытые/анонимные номера и короткие коды оператора.
Поэтому число ваших событий может не совпадать в точности с выгрузкой CDR; учитывайте эти исключения, если нужна полная сверка.
Тип интеграции. Документ описывает интеграцию вебхука событий звонков. Добавив в админ-панели через "+" тип Webhook (URL и необязательный секрет), вы получаете ровно контракт call_end из этого документа. Именованные интеграции (amoCRM/Bitrix24) — это пресеты поверх тех же событий.
2. Транспорт и аутентификация
| Параметр | Значение |
|---|
| Метод | POST |
| Content-Type | application/json |
| Протокол | HTTPS (обязательно) |
| Тело | JSON-объект события (см. раздел 3) |
| Кодировка | UTF-8 |
Аутентификация. Секрет вы задаёте сами при настройке вебхука, и Callion передаёт его без изменений с каждым запросом. Есть два способа:
- Через заголовок (по умолчанию). Если вы не настроили дополнительный заголовок, Callion отправляет секрет в заголовке
x-api-key. При желании вы можете задать собственный заголовок (или несколько) — например Authorization: Bearer <значение> — тогда Callion отправит именно указанные вами заголовки (в этом случае x-api-key не добавляется). - Через параметр URL. Поместите секрет в параметр строки запроса вашего вебхук-URL; URL передаётся без изменений.
Проверяйте этот секрет на своей стороне и отклоняйте запросы без него.
Исходный IP. Запросы приходят с инфраструктуры Callion. Если вы ограничиваете входящий трафик по IP, запросите у Callion актуальный список исходящих адресов и внесите его в список разрешённых. Не полагайтесь на IP как на единственный механизм аутентификации — используйте секрет из настроек вебхука.
3. Конверт события
Пример реального события (входящий, без ответа):
{
"event": "call_end",
"event_id": "1700000000.123",
"call_id": "1700000000.123",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": null,
"operator_name": null,
"duration": 0,
"status": "CANCEL",
"disposition": null,
"started_at": 1700000000,
"recording_url": null
}
Тело — плоский JSON-объект. Поля версии 1 приведены в разделе 4.
4. Таблица полей
Версия 1 сейчас содержит эти 13 полей. Согласно разделу 9, в будущем могут добавляться новые поля без смены версии, поэтому ваш парсер должен игнорировать неизвестные поля и не полагаться на порядок ключей JSON.
| Поле | Тип | Обнуляемость | Пример | Когда отсутствует / null |
|---|
event | string | не null | "call_end" | Всегда присутствует; всегда "call_end". |
event_id | string | не null | "1700000000.123" | Всегда присутствует. Уникальный идентификатор события, стабильный при повторных доставках; используйте как ключ дедупликации. |
call_id | string | не null | "1700000000.123" | Всегда присутствует. Уникальный идентификатор звонка; равен event_id. |
version | integer | не null | 1 | Всегда присутствует. Версия структуры (сейчас 1). |
direction | string | не null | "incoming" | Всегда присутствует. Одно из "incoming" / "outgoing". |
client_number | string | null | обнуляемое | "998901234567" | null, если номер клиента недоступен. |
operator_number | string | null | обнуляемое | "1001" | Внутренний номер задействованного оператора. Входящий — ответивший оператор (null, если не отвечен). Исходящий — звонящий оператор (присутствует даже если звонок не отвечен). |
operator_name | string | null | обнуляемое | "Иванова А." | По тому же условию, что и operator_number; null, если у оператора нет отображаемого имени. |
duration | integer | не null | 205 | Секунды разговора (billsec). 0, если звонок не отвечен. |
status | string | null | обнуляемое | "ANSWERED" | Итог звонка. Непрозрачная строка — не проверяйте по перечислению. |
disposition | string | null | обнуляемое | "sale" | Тег оператора после звонка; null, если тег не проставлен. |
started_at | integer | null | обнуляемое | 1700000000 | Время начала звонка, UNIX-время в секундах; null, если недоступно. |
recording_url | string | null | обнуляемое | "https://<callion-host>/rec/<token>" | Прямая ссылка на запись; null, если записи нет. |
Семантические примечания
- Номера зависят от направления.
client_number — это номер клиента (внешний абонент) независимо от направления. operator_number — это внутренний внутренний номер (extension) оператора. Смысл «кто кому звонил» определяется полем direction: при "incoming" клиент звонит в компанию, при "outgoing" оператор звонит клиенту. - Формат номеров смешанный. Номера передаются в том виде, в каком они получены, и не нормализуются к E.164. Это может быть номер с кодом страны, местный внутренний номер и т. п. Не считайте, что номер всегда в международном формате — нормализуйте на своей стороне, если это нужно.
- Поля оператора зависят от направления — это не признак «отвечено». Во входящем звонке поля оператора показывают ответившего оператора и равны null, если звонок не отвечен. В исходящем звонке они показывают звонящего оператора и присутствуют даже если звонок не был отвечен. Поэтому не делайте вывод «отвечено» по непустому полю оператора — определяйте это по
status (ANSWERED) и duration (> 0). status — непрозрачная строка. Обрабатывайте как непрозрачное значение и не отклоняйте событие из-за незнакомого значения. Для справки возможны следующие 12 значений: ANSWERED, NO ANSWER, BUSY, CANCEL, CONGESTION, CHANUNAVAIL, FAILED, VOICEMAIL, MISSED, REJECTED, TRANSFERRED, UNKNOWN. Список приведён как информационный — набор значений может пополняться; не завязывайте на него валидацию.disposition — тег оператора. Одно из 6 значений: sale, callback, no_answer, wrong_number, not_interested, info_given — либо null, если оператор не проставил тег.started_at — UNIX-время в секундах (не миллисекунды).call_id равен event_id. Оба идентифицируют один звонок; можно использовать любой как ключ.
5. События
Доставляется только событие call_end. Других типов событий по этому каналу нет. Тем не менее проверяйте поле event, чтобы ваш обработчик оставался совместимым при возможном добавлении новых типов в будущем.
6. Ссылка на запись
Поле recording_url — это прямая HTTPS-ссылка на файл записи разговора.
- Формат: WAV, 8 кГц, моно.
- Размер: обычно около 1 МБ; никогда не превышает 50 МБ.
- Range-запросы поддерживаются — можно скачивать файл частями.
- Задержка. Ссылка становится доступной вскоре после завершения звонка — учитывайте небольшую задержку между приходом события и готовностью записи. Если поле
recording_url не null, но файл ещё не готов, повторите загрузку через короткий интервал. - Ссылка неугадываемая и истекает. URL нельзя предсказать, и он действует ограниченное время (по умолчанию 7 дней, срок настраивается).
- Тест записи. У тестового события, отправленного для проверки связи, поле
recording_url указывает на рабочую образцовую запись (короткий файл тишины) — вы можете скачать её и проверить свой процесс загрузки записей.
Рекомендации по работе со ссылкой:
- Скачайте и сохраните запись на своей стороне в течение срока действия ссылки. После истечения срока ссылка перестаёт работать.
- Не логируйте, не пересылайте и не публикуйте URL записи. Считайте его конфиденциальным: любой, у кого есть ссылка, может скачать запись, пока она действительна.
- Если записи нет (например, звонок не отвечен),
recording_url равен null.
7. Семантика доставки
- Не менее одного раза (at-least-once). Одно и то же событие может прийти повторно (например, если ваш эндпоинт не подтвердил доставку вовремя). Используйте
event_id для дедупликации — при повторной доставке он стабилен. - Расписание повторов. При временной ошибке Callion повторяет отправку до 6 раз. Задержка между попытками нарастает: 1с, 5с, 30с, 5 минут, 30 минут, 2 часа. После этого событие отбрасывается.
- Таймаут. На каждую попытку действует общий бюджет 10 секунд (DNS + соединение + TLS + запрос + ответ) и лимит неактивности сокета 5 секунд; что сработает первым, то и завершает попытку. Таймаут считается временной ошибкой и повторяется.
- Звонки с записью. У отвеченного звонка первая попытка может быть отложена примерно на 90 секунд, пока готовится ссылка на запись; это может израсходовать одну из 6 попыток.
- Порядок не гарантируется. События могут прийти не в том порядке, в котором завершались звонки. Не полагайтесь на порядок доставки — сортируйте по
started_at. - Отвечайте быстро. Подтверждайте приём кодом 2xx как можно быстрее и выполняйте обработку асинхронно в фоне. Долгий ответ повышает риск таймаута и повторной доставки.
8. Ответы и ошибки
Ваш эндпоинт должен подтвердить приём кодом 2xx. Поведение Callion в зависимости от вашего ответа:
| Ответ вашего эндпоинта | Трактовка | Действие Callion |
|---|
2xx | Доставлено | Событие считается принятым; повторов нет. |
3xx | Редирект | Редиректы не отслеживаются. Эндпоинт URL должен отвечать 2xx напрямую. 3xx считается постоянной ошибкой и не повторяется. |
4xx | Эндпоинт отклонил | Постоянная ошибка (неверная авторизация, путь или валидация); не повторяется. Проверьте настройку URL и секрета. |
5xx | Временная ошибка сервера | Временная ошибка; повторяется независимо от наличия тела ответа (по таблице выше). |
| Таймаут / нет ответа / ошибка соединения | Доставка не подтверждена | Временная ошибка; повторяется. |
Тело вашего ответа Callion не использует — важен только HTTP-код. После исчерпания всех попыток или при постоянной ошибке (4xx/3xx) событие отбрасывается — отдельного API для повторного запроса нет, поэтому для надёжности дедуплицируйте по event_id и скачивайте запись в течение срока действия ссылки.
9. Версионирование
- Поле
version указывает версию структуры события (сейчас 1). - Изменения только аддитивные: новые поля могут добавляться без смены версии.
- Неизвестные поля игнорируйте, а не отклоняйте. Ваш парсер должен пропускать поля, которых нет в этом документе, а не считать их ошибкой. Это гарантирует совместимость при добавлении полей в будущем.
- Смена значения
version означает несовместимое изменение структуры и будет объявлена заранее.
10. Приложение — примеры
10.1. Отвеченный звонок с записью
Входящий звонок, оператор ответил, разговор 205 секунд, оператор проставил тег sale, запись доступна.
{
"event": "call_end",
"event_id": "1700000500.42",
"call_id": "1700000500.42",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": "1001",
"operator_name": "Иванова А.",
"duration": 205,
"status": "ANSWERED",
"disposition": "sale",
"started_at": 1700000500,
"recording_url": "https://<callion-host>/rec/<token>"
}
Поле за полем:
event — "call_end", тип события.event_id — "1700000500.42", ключ дедупликации.call_id — "1700000500.42", равен event_id.version — 1.direction — "incoming", звонок входящий.client_number — "998901234567", номер клиента.operator_number — "1001", внутренний номер ответившего оператора.operator_name — "Иванова А.", имя оператора (есть, так как звонок отвечен).duration — 205, секунды разговора.status — "ANSWERED", звонок отвечен.disposition — "sale", тег оператора.started_at — 1700000500, время начала (UNIX-время в секундах).recording_url — прямая HTTPS-ссылка на WAV; скачайте в течение срока действия.
10.2. Неотвеченный звонок без записи
Входящий звонок, отменён до ответа: оператор не назначен, длительность 0, тега нет, записи нет.
{
"event": "call_end",
"event_id": "1700000000.123",
"call_id": "1700000000.123",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": null,
"operator_name": null,
"duration": 0,
"status": "CANCEL",
"disposition": null,
"started_at": 1700000000,
"recording_url": null
}
Поле за полем:
event — "call_end", тип события.event_id — "1700000000.123", ключ дедупликации.call_id — "1700000000.123", равен event_id.version — 1.direction — "incoming", звонок входящий.client_number — "998901234567", номер клиента.operator_number — null, звонок не отвечен, оператор не назначен.operator_name — null, по той же причине.duration — 0, разговора не было.status — "CANCEL", звонок отменён до ответа.disposition — null, тег не проставлен.started_at — 1700000000, время начала (UNIX-время в секундах).recording_url — null, записи нет.
11. Операции
- Ротация секрета. Новое значение вы задаёте в настройках интеграции. Автоматического окна перекрытия нет, поэтому меняйте секрет в период низкой нагрузки и будьте готовы короткое время принимать и старое, и новое значение на своём эндпоинте.
- Исходный IP. Запросы приходят с инфраструктуры Callion. Если ограничиваете по IP, запросите актуальный список исходящих адресов у вашего контакта в Callion (список может периодически меняться). Не полагайтесь на IP как на единственный механизм.
- Видимость ошибок. После всех попыток недоставленное событие видно оператору Callion в логах интеграции в течение срока хранения. Отдельной ленты ошибок для партнёра сейчас нет — для надёжности дедуплицируйте по
event_id. - Версии и изменения. Несовместимое изменение повышает значение
version и анонсируется заранее (раздел 9). Документ помечен датой в начале. - Контакт. По вопросам интеграции обращайтесь к вашему контакту в Callion.
Callion — Integration API (outbound webhook)
Document version: 2026-07-21. Changes are announced under the rules of section 9 (Versioning).
This document describes the event that Callion sends to your endpoint when a call ends. It is intended for any external system — a CRM, BI, analytics platform, or partner service — that wants to receive Callion call data. The model is universal: you configure an outbound webhook URL (and, optionally, an authorization header or parameter of your choice), Callion sends a POST request with JSON to it when each call ends, and you respond with a 2xx code.
1. Purpose
Callion sends your endpoint a single event — call_end — at the moment a call ends. It contains the final data of the conversation: direction, numbers, operator, duration, outcome, operator tag, start time, and a recording link.
- Delivery is asynchronous and happens outside the call path. Your endpoint's response (or the lack of one) has no effect on call handling — by the time the event is sent, the call has already ended.
- The event is sent after the call ends, not in real time during the conversation.
- Your job is to accept the POST request, acknowledge it quickly with a 2xx code, and process the data in your own background process.
Scope — which calls are NOT sent. One event is sent when each external call (inbound and outbound) ends, with the following exceptions:
- internal (extension-to-extension) calls;
- calls interrupted mid-way by a backend restart;
- calls where the external party's number is shorter than 6 digits — this includes hidden/anonymous numbers and carrier short codes.
For this reason your event count may not match a CDR export exactly; account for these exclusions if you need a full reconciliation.
Integration type. This document describes the call-events webhook integration. When you add the Webhook type via the "+" button in the admin panel (a URL and an optional secret), you get exactly the call_end contract from this document. Named integrations (amoCRM/Bitrix24) are presets on top of the same events.
2. Transport and authentication
| Parameter | Value |
|---|
| Method | POST |
| Content-Type | application/json |
| Protocol | HTTPS (required) |
| Body | JSON object of the event (see section 3) |
| Encoding | UTF-8 |
Authentication. You set the secret value yourself when configuring the webhook, and Callion passes it unchanged with every request. There are two methods:
- Via header (default). If you have not configured a custom header, Callion sends the secret in the
x-api-key header. If you prefer, you can configure your own header (or several) — for example Authorization: Bearer <value> — in which case Callion sends exactly the headers you specified (and x-api-key is not added). - Via URL parameter. Place the secret in a query-string parameter of your webhook URL; the URL is passed unchanged.
Verify this secret on your side and reject requests that arrive without it.
Source IP. Requests come from Callion infrastructure. If you restrict inbound traffic by IP, request the current list of outbound addresses from Callion and add it to your allowlist. Do not rely on IP as the only authentication mechanism — use the secret from the webhook configuration.
3. Event envelope
A sample real event (inbound, unanswered):
{
"event": "call_end",
"event_id": "1700000000.123",
"call_id": "1700000000.123",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": null,
"operator_name": null,
"duration": 0,
"status": "CANCEL",
"disposition": null,
"started_at": 1700000000,
"recording_url": null
}
The body is a flat JSON object. The version 1 fields are listed in section 4.
4. Field table
Version 1 currently contains these 13 fields. Per section 9, new fields may be added in the future without a version change, so your parser must ignore unknown fields and must not rely on JSON key order.
| Field | Type | Nullability | Sample | When absent / null |
|---|
event | string | not null | "call_end" | Always present; always "call_end". |
event_id | string | not null | "1700000000.123" | Always present. Unique identifier of the event, stable across redeliveries; use it as the deduplication key. |
call_id | string | not null | "1700000000.123" | Always present. Unique identifier of the call; equal to event_id. |
version | integer | not null | 1 | Always present. Version of the body structure (currently 1). |
direction | string | not null | "incoming" | Always present. One of "incoming" / "outgoing". |
client_number | string | null | nullable | "998901234567" | null if the client's number is unavailable. |
operator_number | string | null | nullable | "1001" | Extension of the operator involved. Inbound — the operator who answered (null if unanswered). Outbound — the operator who placed the call (present even if the call was not answered). |
operator_name | string | null | nullable | "J. Smith" | Same condition as operator_number; null if the operator has no display name. |
duration | integer | not null | 205 | Talk seconds (billsec). 0 if the call was not answered. |
status | string | null | nullable | "ANSWERED" | Call outcome. Opaque string — do not validate against an enum. |
disposition | string | null | nullable | "sale" | The operator's after-call tag; null if no tag was set. |
started_at | integer | null | nullable | 1700000000 | Call start time, UNIX time in seconds; null if unavailable. |
recording_url | string | null | nullable | "https://<callion-host>/rec/<token>" | Direct link to the recording; null if there is no recording. |
Semantic notes
- Numbers depend on direction.
client_number is the client's (external party's) number regardless of direction. operator_number is the operator's internal extension. Who called whom is determined by the direction field: with "incoming" the client calls the company; with "outgoing" the operator calls the client. - Number format is mixed. Numbers are passed exactly as received and are not normalized to E.164. A value may be a number with a country code, a local extension, and so on. Do not assume the number is always in international format — normalize on your side if you need to.
- Operator fields depend on direction — they do not mean "answered". On an inbound call the operator fields show the operator who answered and are null if the call was not answered. On an outbound call they show the operator who placed the call and are present even if the call was not answered. Therefore do not infer "answered" from a non-empty operator field — determine it from
status (ANSWERED) and duration (> 0). status is an opaque string. Treat it as an opaque value and do not reject an event because of an unfamiliar value. For reference, the following 12 values are possible: ANSWERED, NO ANSWER, BUSY, CANCEL, CONGESTION, CHANUNAVAIL, FAILED, VOICEMAIL, MISSED, REJECTED, TRANSFERRED, UNKNOWN. The list is informational — the set of values may grow; do not tie your validation to it.disposition is the operator tag. One of 6 values: sale, callback, no_answer, wrong_number, not_interested, info_given — or null if the operator did not set a tag.started_at is UNIX time in seconds (not milliseconds).call_id equals event_id. Both identify the same call; you may use either as a key.
5. Events
Only the call_end event is delivered. There are no other event types on this channel. Nevertheless, check the event field so that your handler stays compatible if new types are ever added in the future.
6. Recording link
The recording_url field is a direct HTTPS link to the call recording file.
- Format: WAV, 8 kHz, mono.
- Size: typically about 1 MB; never exceeds 50 MB.
- Range requests are supported — the file can be downloaded in parts.
- Delay. The link becomes available shortly after the call ends — allow for a small delay between the event arriving and the recording being ready. If
recording_url is not null but the file is not yet ready, retry the download after a short interval. - The link is unguessable and expires. The URL cannot be predicted, and it is valid for a limited time (7 days by default; the period is configurable).
- Testing the recording. A test event sent to verify connectivity carries a
recording_url that points to a working sample recording (a short silent file), so you can fetch it and validate your own recording-download handling.
Recommendations for handling the link:
- Download and store the recording on your side within the link's validity period. Once it expires, the link stops working.
- Do not log, forward, or publish the recording URL. Treat it as confidential: anyone who has the link can download the recording while it is valid.
- If there is no recording (for example, the call was not answered),
recording_url is null.
7. Delivery semantics
- At-least-once. The same event may arrive again (for example, if your endpoint did not acknowledge delivery in time). Use
event_id for deduplication — it is stable across redeliveries. - Retry schedule. On a temporary error, Callion retries the send up to 6 times. The delay between attempts grows: 1s, 5s, 30s, 5 minutes, 30 minutes, 2 hours. After that the event is dropped.
- Timeout. Each attempt is subject to a total budget of 10 seconds (DNS + connect + TLS + request + response) and a socket-inactivity limit of 5 seconds; whichever fires first ends the attempt. A timeout counts as a temporary error and is retried.
- Ordering is not guaranteed. Events may arrive in a different order than the calls ended. Do not rely on delivery order — sort by
started_at. - Calls with a recording. For an answered call, the first attempt may be delayed by roughly 90 seconds while the recording link is prepared; this may consume one of the 6 attempts.
- Respond fast. Acknowledge receipt with a 2xx code as quickly as possible and do the processing asynchronously in the background. A slow response increases the risk of a timeout and redelivery.
8. Responses and errors
Your endpoint must acknowledge receipt with a 2xx code. Callion's behavior depending on your response:
| Your endpoint's response | Interpretation | Callion's action |
|---|
2xx | Delivered | The event is considered accepted; no retries. |
3xx | Redirect | Redirects are not followed. The endpoint URL must respond 2xx directly. 3xx is treated as a permanent error and is not retried. |
4xx | Endpoint rejected | Permanent error (bad authorization, path, or validation); not retried. Check the URL and secret configuration. |
5xx | Temporary server error | Temporary error; retried regardless of whether there is a response body (per the schedule above). |
| Timeout / no response / connection error | Delivery not confirmed | Temporary error; retried. |
Callion does not use your response body — only the HTTP code matters. Once all attempts are exhausted or on a permanent error (4xx/3xx), the event is dropped — there is no separate API to request it again, so for reliable delivery deduplicate by event_id and download the recording within the link's validity period.
9. Versioning
- The
version field indicates the version of the event structure (currently 1). - Changes are additive only: new fields may be added without a version change.
- Ignore unknown fields; do not reject them. Your parser must skip fields not present in this document rather than treat them as an error. This guarantees compatibility when fields are added in the future.
- A change in the
version value indicates an incompatible change to the structure and will be announced in advance.
10. Appendix — examples
10.1. Answered call with a recording
Inbound call, the operator answered, the conversation lasted 205 seconds, the operator set the sale tag, a recording is available.
{
"event": "call_end",
"event_id": "1700000500.42",
"call_id": "1700000500.42",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": "1001",
"operator_name": "J. Smith",
"duration": 205,
"status": "ANSWERED",
"disposition": "sale",
"started_at": 1700000500,
"recording_url": "https://<callion-host>/rec/<token>"
}
Field by field:
event — "call_end", the event type.event_id — "1700000500.42", the deduplication key.call_id — "1700000500.42", equal to event_id.version — 1.direction — "incoming", the call is inbound.client_number — "998901234567", the client's number.operator_number — "1001", the extension of the operator who answered.operator_name — "J. Smith", the operator's name (present because the call was answered).duration — 205, talk seconds.status — "ANSWERED", the call was answered.disposition — "sale", the operator tag.started_at — 1700000500, the start time (UNIX time in seconds).recording_url — a direct HTTPS link to the WAV; download it within the validity period.
10.2. Unanswered call without a recording
Inbound call, canceled before answer: no operator assigned, duration 0, no tag, no recording.
{
"event": "call_end",
"event_id": "1700000000.123",
"call_id": "1700000000.123",
"version": 1,
"direction": "incoming",
"client_number": "998901234567",
"operator_number": null,
"operator_name": null,
"duration": 0,
"status": "CANCEL",
"disposition": null,
"started_at": 1700000000,
"recording_url": null
}
Field by field:
event — "call_end", the event type.event_id — "1700000000.123", the deduplication key.call_id — "1700000000.123", equal to event_id.version — 1.direction — "incoming", the call is inbound.client_number — "998901234567", the client's number.operator_number — null, the call was not answered, no operator was assigned.operator_name — null, for the same reason.duration — 0, there was no conversation.status — "CANCEL", the call was canceled before answer.disposition — null, no tag was set.started_at — 1700000000, the start time (UNIX time in seconds).recording_url — null, there is no recording.
11. Operations
- Secret rotation. You set the new value in the integration settings. There is no automatic overlap window, so perform the rotation during a low-traffic period and be prepared to accept both the old and the new value on your endpoint for a short time.
- Source IP. Requests come from Callion infrastructure. If you restrict by IP, request the current list of outbound addresses from your Callion contact (the list may change from time to time). Do not rely on IP as the only mechanism.
- Error visibility. After all attempts, an undelivered event remains visible to a Callion operator in the integration logs for the retention period. There is no separate partner-facing error feed yet — for reliable delivery, deduplicate by
event_id. - Versions and changes. An incompatible change increases the
version value and is announced in advance (section 9). This document is dated at the top. - Contact. For integration questions, reach out to your Callion contact.