Звонки, заявки и сделки
по REST API
Читайте звонки, заявки, контакты и сделки, создавайте задачи, управляйте SIP-аккаунтами и запускайте исходящие вызовы. Плюс вебхуки — события звонков прилетают на ваш адрес сами. Авторизация — OAuth2, ответы — JSON.
- Base URL
- crm.hotlead.io/api/v1
- Авторизация
- OAuth2 · client_credentials
- Адрес авторизации
- crm.hotlead.io/oauth
- Формат ответа
- JSON
- Версия спецификации
- OpenAPI 2.0
- Всего операций
- 30 + вебхуки
Как получить токен и проверить доступ
Токен выдаётся по протоколу
OAuth2.
Отправьте POST на crm.hotlead.io/oauth с тремя параметрами:
grant_type = client_credentials, client_id
(логин кабинета) и client_secret (пароль кабинета).
curl -X POST https://crm.hotlead.io/oauth \
-d grant_type=client_credentials \
-d client_id=ВАШ_ЛОГИН \
-d client_secret=ВАШ_ПАРОЛЬ
Полученный токен подставляйте в заголовок Authorization в каждом
запросе. Проверить доступ проще всего вызовом who-am-i:
curl https://crm.hotlead.io/api/v1/who-am-i \
-H "Authorization: Bearer ВАШ_ТОКЕН"
По ответу /oauth видно результат: 200 с
access_token — доступ есть; 400 invalid_client — неверная
пара логин/пароль (ответ одинаков для неверного пароля и несуществующего логина —
намеренно, защита от перебора учётных записей); 400 user_not_activate —
учётная запись неактивна.
client_id и client_secret — это логин и пароль от личного
кабинета. Держите их на сервере, а не в коде страницы и не в мобильном приложении:
кто их получит, тот увидит все звонки, записи разговоров и клиентскую базу.
Все запросы — только по https.
Справочник методов
Все операции сгруппированы по разделам. Нажмите иконку справа, чтобы скопировать
готовую строку МЕТОД URL. Полный путь — crm.hotlead.io/api/v1
плюс путь метода.
Заявки и звонки
GET/callsСписок звонков
{
"page": 0,
"size": 0,
"total": 0,
"order": "string",
"data": [
{
"id": 0,
"duration": 0,
"billsec": 0,
"record": "string",
"assignedUser": {
"id": {},
"firstName": {},
"lastName": {}
},
"status": "string",
"startedDatetime": "string",
"method": "string",
"contactPhoneNumber": {},
"externalPhoneNumber": {}
}
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}GET/calls/{id}Карточка звонка по идентификатору
{
"id": 0,
"duration": 0,
"billsec": 0,
"record": "string",
"assignedUser": {
"id": 0,
"firstName": "string",
"lastName": "string"
},
"status": "string",
"startedDatetime": "string",
"method": "string",
"contactPhoneNumber": {
"id": 0,
"phoneNumber": "string",
"mobile": true,
"contactId": {},
"info": "string"
},
"externalPhoneNumber": {
"id": 0,
"company": {},
"type": 0,
"phoneNumber": "string",
"carrierId": 0,
"platform": {},
"pbxId": 0,
"status": "string",
"phoneorderId": 0,
"addedDate": "string"
}
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}GET/requestsСписок заявок
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
| ids | query | array | — |
{
"pageNo": 0,
"pageSize": 0,
"totalCount": 0,
"items": [
{
"id": 0,
"channelName": "string",
"contact": {},
"comments": [
{}
],
"assignedUser": {},
"favorite": true,
"readed": true,
"platform": {},
"subject": "string",
"dateCreated": "string",
"uploadedFilesIds": [
{}
],
"call": "string",
"form": "string"
}
]
}GET/requests/callsСписок заявок-звонков
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
{
"pageNo": "string",
"pageSize": "string",
"totalCount": "string",
"items": [
{
"assigned_user": "string",
"contact_note": "string",
"date_created": "string",
"direction": "string",
"favorite": true,
"id": "string",
"location": "string",
"method": "string",
"name": "string",
"pbx": {
"id": "string",
"name": "string"
},
"phone_number": "string",
"platform": "string",
"readed": "string",
"record": "string",
"referer": "string",
"request_url": "string",
"status": {
"category": "string",
"label": "string"
},
"subject": "string",
"transfer_call": "string",
"working_hours": true
}
]
}GET/requests/formsСписок заявок с форм
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
{
"pageNo": "string",
"pageSize": "string",
"totalCount": "string",
"items": [
{
"assigned_user": "string",
"data": [
{
"label": {},
"type": {},
"value": {}
}
],
"dateCreated": "string",
"email": "string",
"favorite": true,
"id": 0,
"location": "string",
"name": "string",
"phone": "string",
"platform": "string",
"readed": true,
"referer": "string",
"request_url": {
"full": "string",
"short": "string"
},
"site_name": "string",
"subject": "string",
"title": "string"
}
]
}GET/requests/{id}Карточка заявки по идентификатору
{
"id": 0,
"channelName": "string",
"contact": {
"id": 0,
"name": "string",
"email": "string",
"createdDate": "string",
"note": "string",
"requestIds": [
{}
],
"dealIds": [
{}
],
"phonesNumberIds": [
{}
],
"important": true,
"taskIds": [
{}
],
"uploadedFilesIds": [
{}
],
"parentContactIds": [
{}
],
"childContactIds": [
{}
]
},
"comments": [
{
"id": {},
"createdDate": {},
"text": {},
"isEdited": {},
"createdBy": {},
"request": {}
}
],
"assignedUser": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"favorite": true,
"readed": true,
"platform": {},
"subject": "string",
"dateCreated": "string",
"uploadedFilesIds": [
0
],
"call": "string",
"form": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}Контакты
GET/contactsСписок контактов
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
| ids | query | array | — |
{
"pageNo": 0,
"pageSize": 0,
"totalCount": 0,
"items": [
{
"id": 0,
"name": "string",
"email": "string",
"createdDate": "string",
"note": "string",
"requestIds": [
{}
],
"dealIds": [
{}
],
"phonesNumberIds": [
{}
],
"important": true,
"taskIds": [
{}
],
"uploadedFilesIds": [
{}
],
"parentContactIds": [
{}
],
"childContactIds": [
{}
]
}
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}POST/contactsДобавить контакт
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"id": 0,
"name": "string",
"email": "string",
"createdDate": "string",
"note": "string",
"requestIds": [
0
],
"dealIds": [
0
],
"phonesNumberIds": [
0
],
"important": true,
"taskIds": [
0
],
"uploadedFilesIds": [
0
],
"parentContactIds": [
0
],
"childContactIds": [
0
]
}{
"id": 0,
"name": "string",
"email": "string",
"createdDate": "string",
"note": "string",
"requestIds": [
0
],
"dealIds": [
0
],
"phonesNumberIds": [
0
],
"important": true,
"taskIds": [
0
],
"uploadedFilesIds": [
0
],
"parentContactIds": [
0
],
"childContactIds": [
0
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}GET/contacts/{id}Карточка контакта по идентификатору
{
"id": 0,
"name": "string",
"email": "string",
"createdDate": "string",
"note": "string",
"requestIds": [
0
],
"dealIds": [
0
],
"phonesNumberIds": [
0
],
"important": true,
"taskIds": [
0
],
"uploadedFilesIds": [
0
],
"parentContactIds": [
0
],
"childContactIds": [
0
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}Сделки
GET/dealsСписок сделок
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
| ids | query | array | — |
{
"pageNo": 0,
"pageSize": 0,
"totalCount": 0,
"items": [
{
"id": 0,
"title": "string",
"description": "string",
"dateCreated": "string",
"dateUpdated": "string",
"favorite": true,
"closed": true,
"removed": true,
"status": "string",
"companyId": 0,
"contactId": 0,
"sortPosition": 0,
"properties": "string",
"stageIds": [
{}
],
"agents": "string",
"members": "string",
"budget": "string",
"uploadedFileIds": [
{}
],
"comments": "string"
}
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}Задачи
GET/tasksСписок задач
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| searchString | query | string | — |
| pageNo | query | integer | — |
| pageSize | query | integer | — |
| ids | query | array | — |
{
"pageNo": 0,
"pageSize": 0,
"totalCount": 0,
"items": [
{
"id": 0,
"assignedUser": {},
"createdDate": "string",
"targetDate": "string",
"finishDate": "string",
"executable": true,
"closed": true,
"title": "string",
"target": "string",
"descrption": "string",
"owner": {},
"options": "string",
"resultOptions": "string",
"company": {},
"linkedContactIds": [
{}
]
}
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}POST/tasksСоздать задачу
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"id": 0,
"assignedUser": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"createdDate": "string",
"targetDate": "string",
"finishDate": "string",
"executable": true,
"closed": true,
"title": "string",
"target": "string",
"descrption": "string",
"owner": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"options": "string",
"resultOptions": "string",
"company": {
"id": 0,
"name": "string",
"countryId": 0,
"account": {},
"siteUrl": "string"
},
"linkedContactIds": [
0
]
}{
"id": 0,
"assignedUser": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"createdDate": "string",
"targetDate": "string",
"finishDate": "string",
"executable": true,
"closed": true,
"title": "string",
"target": "string",
"descrption": "string",
"owner": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"options": "string",
"resultOptions": "string",
"company": {
"id": 0,
"name": "string",
"countryId": 0,
"account": {},
"siteUrl": "string"
},
"linkedContactIds": [
0
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}GET/tasks/{id}Карточка задачи
{
"id": 0,
"assignedUser": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"createdDate": "string",
"targetDate": "string",
"finishDate": "string",
"executable": true,
"closed": true,
"title": "string",
"target": "string",
"descrption": "string",
"owner": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"options": "string",
"resultOptions": "string",
"company": {
"id": 0,
"name": "string",
"countryId": 0,
"account": {},
"siteUrl": "string"
},
"linkedContactIds": [
0
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}PUT/tasks/{id}Изменить задачу
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"id": 0,
"assignedUser": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"createdDate": "string",
"targetDate": "string",
"finishDate": "string",
"executable": true,
"closed": true,
"title": "string",
"target": "string",
"descrption": "string",
"owner": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"options": "string",
"resultOptions": "string",
"company": {
"id": 0,
"name": "string",
"countryId": 0,
"account": {},
"siteUrl": "string"
},
"linkedContactIds": [
0
]
}{
"id": 0,
"assignedUser": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"createdDate": "string",
"targetDate": "string",
"finishDate": "string",
"executable": true,
"closed": true,
"title": "string",
"target": "string",
"descrption": "string",
"owner": {
"id": 0,
"username": "string",
"lastName": "string",
"email": "string",
"phone": "string",
"created": "string",
"timezone": "string",
"locale": "string",
"state": 0,
"companyId": 0,
"parentId": 0
},
"options": "string",
"resultOptions": "string",
"company": {
"id": 0,
"name": "string",
"countryId": 0,
"account": {},
"siteUrl": "string"
},
"linkedContactIds": [
0
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}DELETE/tasks/{id}Удалить задачу
{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}SIP-аккаунты
GET/sip/accountsСписок SIP-аккаунтов
[
{
"id": 0,
"company": "string",
"dialString": "string",
"login": "string",
"host": "string",
"description": "string",
"homeRegion": "string",
"internationalEnable": true,
"doNotDisturb": true
}
]{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}POST/sip/accountsСоздать SIP-аккаунт
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"id": 0,
"company": "string",
"dialString": "string",
"login": "string",
"host": "string",
"description": "string",
"homeRegion": "string",
"internationalEnable": true,
"doNotDisturb": true,
"info": [
{
"id": {},
"name": {},
"secret": {},
"defaultuser": {},
"call-limit": {},
"nat": {},
"dtmfmode": {},
"context": {},
"type": {},
"host": {}
}
],
"displayCaller": {
"displayCallerId": 0,
"displayCallerPhone": "string",
"displayCallerPlatform": {
"displayCallerPlatformId": 0,
"displayCallerPlatformName": "string"
}
}
}{
"id": 0,
"company": "string",
"dialString": "string",
"login": "string",
"host": "string",
"description": "string",
"homeRegion": "string",
"internationalEnable": true,
"doNotDisturb": true,
"info": [
{
"id": {},
"name": {},
"secret": {},
"defaultuser": {},
"call-limit": {},
"nat": {},
"dtmfmode": {},
"context": {},
"type": {},
"host": {}
}
],
"displayCaller": {
"displayCallerId": 0,
"displayCallerPhone": "string",
"displayCallerPlatform": {
"displayCallerPlatformId": 0,
"displayCallerPlatformName": "string"
}
}
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}GET/sip/accounts/{id}Карточка SIP-аккаунта
{
"id": 0,
"company": "string",
"dialString": "string",
"login": "string",
"host": "string",
"description": "string",
"homeRegion": "string",
"internationalEnable": true,
"doNotDisturb": true,
"info": [
{
"id": {},
"name": {},
"secret": {},
"defaultuser": {},
"call-limit": {},
"nat": {},
"dtmfmode": {},
"context": {},
"type": {},
"host": {}
}
],
"displayCaller": {
"displayCallerId": 0,
"displayCallerPhone": "string",
"displayCallerPlatform": {
"displayCallerPlatformId": 0,
"displayCallerPlatformName": "string"
}
}
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}PUT/sip/accounts/{id}Изменить SIP-аккаунт
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"id": 0,
"company": "string",
"dialString": "string",
"login": "string",
"host": "string",
"description": "string",
"homeRegion": "string",
"internationalEnable": true,
"doNotDisturb": true,
"info": [
{
"id": {},
"name": {},
"secret": {},
"defaultuser": {},
"call-limit": {},
"nat": {},
"dtmfmode": {},
"context": {},
"type": {},
"host": {}
}
],
"displayCaller": {
"displayCallerId": 0,
"displayCallerPhone": "string",
"displayCallerPlatform": {
"displayCallerPlatformId": 0,
"displayCallerPlatformName": "string"
}
}
}{
"id": 0,
"company": "string",
"dialString": "string",
"login": "string",
"host": "string",
"description": "string",
"homeRegion": "string",
"internationalEnable": true,
"doNotDisturb": true,
"info": [
{
"id": {},
"name": {},
"secret": {},
"defaultuser": {},
"call-limit": {},
"nat": {},
"dtmfmode": {},
"context": {},
"type": {},
"host": {}
}
],
"displayCaller": {
"displayCallerId": 0,
"displayCallerPhone": "string",
"displayCallerPlatform": {
"displayCallerPlatformId": 0,
"displayCallerPlatformName": "string"
}
}
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}DELETE/sip/accounts/{id}Удалить SIP-аккаунт
{
"id": 0
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}Телефония и заявки
GET/external-phone-numbersСписок внешних номеров
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
| ids | query | array | — |
{
"pageNo": 0,
"pageSize": 0,
"totalCount": 0,
"items": [
{
"id": 0,
"phoneNumber": "string",
"status": "string",
"type": 0,
"addedDate": "string",
"platform": "string",
"pbx": "string",
"carrier": "string"
}
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}POST/outgoing-processИнициировать исходящий вызов
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"phone": "string",
"sip_id": 0
}{
"call_id": 0
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}POST/callback/{id}Заказать обратный звонок
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"phone": "string",
"timezone": "string",
"datetime": "string"
}"string""string""string""string""string"POST/capture-form/{site_hash}Принять обращение с формы на сайте
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| body | тело | object | — |
{
"form": "string",
"form_id": "string",
"cookie": "string",
"url": "string"
}Тело ответа не типизировано в спецификации.
Чёрный список
GET/blacklistСписок номеров в чёрном списке
[
{
"id": 0,
"phone_number": "string"
}
]{
"error": "not_authorized"
}POST/blacklistДобавить номер
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| phone_number | тело | string | обяз. |
{
"phone_number": "string"
}{
"result": true
}{
"error": "phone_number_required"
}{
"error": "not_authorized"
}DELETE/blacklist/{phone}Убрать номер из чёрного списка
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| phone | path | string | обяз. |
{
"result": true
}{
"error": "not_authorized"
}{
"error": "not_found"
}Прочее
GET/commentsСписок комментариев
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
| ids | query | array | — |
{
"pageNo": 0,
"pageSize": 0,
"totalCount": 0,
"items": [
{
"id": 0,
"createdDate": "string",
"text": "string",
"isEdited": true,
"createdBy": {},
"request": {}
}
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}GET/upload-filesСписок загруженных файлов
| Имя | Где | Тип | Обяз. |
|---|---|---|---|
| pageNo | query | integer | — |
| pageSize | query | integer | — |
| ids | query | array | — |
{
"pageNo": 0,
"pageSize": 0,
"totalCount": 0,
"items": [
{
"id": 0,
"originalName": "string",
"fileName": "string",
"extension": "string",
"size": 0,
"mimeType": "string",
"params": "string",
"dateCreated": "string"
}
]
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}GET/who-am-iДанные текущего пользователя — проверка доступа
{
"id": 0,
"username": "string",
"lastName": "string",
"fullName": "string",
"phone": "string",
"email": "string",
"timezone": "string",
"locale": "string",
"tariff": {
"id": 0
},
"company": {
"id": 0,
"name": "string"
},
"roles": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}{
"status": 0,
"title": "string",
"detail": "string"
}Вебхуки — события звонков на ваш адрес
Помимо запросов к API, HOTLEAD сам присылает события звонков на ваш сервер —
не нужно опрашивать API. Адрес приёма и секрет подписи задаются в кабинете:
Интеграции → Webhook. Несколько адресов — через |.
На каждый звонок приходит POST с телом в формате JSON и полем
step: start — звонок начат, answered —
обе стороны сняли трубку, finish — звонок завершён (в этом событии
итоговый status, duration и record_url).
Событие finish приходит на любой завершённый звонок, включая
брошенный во время гудков и исходящий, сорванный до соединения.
Состав тела вебхука
| Поле | Значение |
|---|---|
| step | start / answered / finish |
| call_id | идентификатор звонка |
| direction | incoming / outgoing |
| request_id | идентификатор заявки |
| user_id | ответственный менеджер |
| caller.phone caller.answered_phone | номер вызывающей стороны и фактически ответивший на ней |
| called.phone called.answered_phone | номер вызываемой стороны и фактически ответивший (кто именно принял звонок) |
| date_time | время начала звонка, Unix-время |
| duration | длительность разговора, секунды |
| status.status_description status.status_code | итоговый статус звонка — текст и числовой код (таблица ниже) |
| record_url | ссылка на запись разговора (в событии finish) |
В answered_phone приходит внутренний номер сотрудника
(number, напр. «100»). Это не логин SIP-аккаунта
(login/username, напр. «1002464sip»), по которому
регистрируется софтфон. Чтобы привязать звонок к сотруднику, сопоставляйте
answered_phone с полем number из
GET /api/v1/sip/accounts.
Статусы звонка
| status_description | code | Значение | Ответили |
|---|---|---|---|
| answered | 200 | состоялся разговор | да |
| manager_missed | 408 | менеджер не взял трубку | — |
| customer_missed | 408 | клиент не дождался, бросил | — |
| customer_busy | 486 | занято у клиента | — |
| manager_busy | 486 | занято у менеджера | — |
| call_canceled / canceled | 487 | отменён до соединения | — |
| no_answer / missed | 408 | нет ответа | — |
| chanunavail | 600 | направление недоступно | — |
| off_hours | 480 | вне рабочих часов | — |
| during / in_queue | 183 / 182 | промежуточные состояния | — |
Ответ на звонок — это answered (код 200). «Клиент не дождался»
(customer_missed) и «менеджер не взял» (manager_missed) —
разные значения, различаются напрямую по status_description.
Событие answered приходит только для отвеченных звонков (когда
начался разговор). Неотвеченный звонок даёт только start и
finish — это ожидаемо.
Надёжная доставка и журнал
Успешной считается только доставка с ответом 2xx. Если ваш сервер
ответил иначе, недоступен или превысил таймаут — запрос повторяется:
до 6 попыток с нарастающим интервалом (1 мин → 5 мин → 30 мин → 2 ч → 6 ч),
после чего доставка помечается исчерпанной. Так вы не теряете события при
перезапуске или сетевом сбое. Неуспешные доставки, их статус и кнопка ручной
переотправки — в кабинете на странице Webhook.
Задайте секрет в кабинете (Webhook → «Секрет подписи», кнопка «Сгенерировать») —
и мы будем подписывать каждый запрос. В заголовках придут
X-Hotlead-Timestamp и X-Hotlead-Signature: sha256=…,
где подпись — HMAC-SHA256(secret, "<timestamp>.<сырое тело>").
На своей стороне пересоберите строку из полученного тела и заголовка времени,
сверьте подпись и отклоните запрос, если метка времени старше нескольких минут —
так вы отличите наши события от подделок и защититесь от повторного проигрывания.
Дополнительно можно ограничить приём по фиксированному IP нашего сервера —
адрес выдаём по запросу в поддержке.
Поддержка отвечает на общие вопросы по API и консультирует по интеграции — напишите в Telegram. Программирование, разработка модулей и доработка кода под ваши задачи в поддержку не входят — см. раздел 08 документации.