Обновление сделок
Запрос
POST:
https://api.calltouch.ru/lead-service/v1/api/client-order/update
HTTP-заголовки:
- Access-Token — API-ключ
- SiteId — ID ЛК Calltouch
Пример тела запроса
{
"orders": [
// Сделка 1
{
"orderNumber": "ID сделки 1 во внешней CRM",
"funnel": "Название воронки",
"status": "Новая сделка",
"statusDate": "Дата и время перехода сделки на текущий статус",
"updateDate": "Дата и время обновления сделки",
"currency": "rub",
"revenue": "100000.50",
"margin": "100.50",
"manager": "ФИО менеджера",
"leadManager": {
"manager": "Иван Иванов",
"overwrite": false
},
"orderLink": "https://site.ru/crm/deal/123/",
"orderName": "Название сделки",
"addNewComment": {
"text": "Комментарий к сделке"
},
"addTags": {
"overwrite": false,
"tags": [
{"tag": "Тег 1"},
{"tag": "Тег 2"},
{"tag": "Тег N"}
]
},
"addTagsToLead": {
"overwrite": false,
"tags": [
{"tag": "Тег 1"},
{"tag": "Тег 2"},
{"tag": "Тег N"}
]
},
"customFields": [
{"field": "grossprofit", "value": "456.50"},
{"field": "name", "value": "123"}
],
"addCustomFieldsToLead": {
"customFields": [
{"field": "test_field", "value": "test value"}
],
"overwrite": false
},
"products": [
{
"name": "Табурет",
"price": "500.25",
"brand": "ikea",
"category": "Столы, стулья",
"variant": "Черный",
"quantity": 10
},
{
"name": "Стол",
"price": "1500"
}
],
"orderContacts": {
"mainContacts": {
"fio": "Иван",
"phoneNumber": "79000000000",
"email": "test@test.ru",
"waPhone": "79000000000",
"tgId": "1234567",
"tgUsername": "tguser1",
"vkId": "1234567"
},
"otherContacts": {
"phoneNumber": ["79000000001","79000000002"],
"email": ["test2@test.ru","test3@test.ru"],
"waPhone": ["79000000001","79000000002"],
"tgId": ["7654321"],
"tgUsername": ["tguser2"],
"vkId": ["7654321"]
}
},
"reMatching": [
{
"type": "request",
"requestParams": {
"requestId": 1,
"tags": ["тег1","тег2"],
"tagsLogic": "and"
}
},
{
"type": "call",
"callParams": {
"callId": 2 ,
"tags": ["тег1","тег2"],
"tagsLogic": "and"
}
},
{
"type": "chat",
"chatParams": {
"chatId": 3,
"tags": ["тег1","тег2"],
"tagsLogic": "and"
}
},
{
"type": "leadContact",
"leadContactParams": {
"emails": ["name@server.com"],
"phones": ["79157771122", "+7 (915) 888-11-22"],
"date": "Дата и время лида",
"tags": ["тег1","тег2"],
"tagsLogic": "and",
"leadTypeToMatch": "nearestUniq",
"searchDepth": 262800,
"withChats": true
}
},
{
"type": "requestContact",
"requestContactParams": {
"emails": ["name@server.com"],
"phones": ["79157771122", "+7 (915) 888-11-22"],
"date": "Дата и время заявки",
"tags": ["тег1","тег2"],
"tagsLogic": "and",
"requestTypeToMatch": "nearest",
"searchDepth": 262800
}
},
{
"type": "callContact",
"callContactParams": {
"phones": ["84953338877"],
"date": "Дата и время звонка",
"tags": ["тег1","тег2"],
"tagsLogic": "and",
"callTypeToMatch": "nearest",
"searchDepth": 262800
}
},
{
"type": "chatContact",
"chatContactParams": {
"emails": ["name@server.com"],
"phones": ["79157771122", "+7 (915) 888-11-22"],
"waPhones": ["79999999999", "+7 (911) 222-33-44"],
"tgIds": ["123456"],
"tgUsernames": ["@username", "username"],
"vkIds": ["123456"],
"date": "Дата и время чата",
"tags": ["тег1","тег2"],
"tagsLogic": "and",
"chatTypeToMatch": "nearestUniq",
"searchDepth": 262800
}
},
{
"type": "session",
"sessionParams": {
"sessionId": "1234567"
}
},
{
"type": "customSources",
"customSourceParams": {
"source": "Произвольный источник",
"medium": "Произвольный канал",
"campaign": "Произвольная кампания",
"content": "Произвольное объявление",
"term": "Произвольная ключевая фраза"
}
},
{
"type": "withoutSource"
}
]
}
// Сделка N
...
]
}
Комментарии через // следует убрать из запроса перед его выполнением.
Параметры запроса
| Параметр | Формат | Обязательно | Описание |
| orders | array | Да | Массив сделок. Можно перечислить до 100 сделок за 1 запрос. Обновление происходит в режиме онлайн. |
| orders.orderNumber | string | Да | По этому ID мы будем находить у себя уже существующую сделку и обновлять ее. Если не найдем, то выводить ошибку напротив этой сделки в ответе. Обязательно. |
| orders.funnel | string | Нет | Актуальная воронки. Если не указано, то сделка помещается в служебную воронку "Без воронки". Для обновления воронки требуется отправлять вместе с актуальным статусом. |
| orders.status | string | Нет | Актуальный статус. |
| orders.statusDate | string | Обязательно, если указан status | Дата и время перехода сделки на текущий статус. Формат: dd-mm-yyyy hh:mm:ss. |
| orders.updateDate | string | Да |
Дата и время обновления сделки. Формат: dd-mm-yyyy hh:mm:ss. Дата обновления сделки будет не датой обработки API-запроса на обновление, а указанная в самом запросе дата. Дата и время статуса сделки должно быть равно или предшествовать дате и времени обновления. Обратное условие, нежели в API-методе создания сделок, потому что статус не может появится раньше сделки, и не может быть обновлен позже, чем обновлена вся сделка. |
| orders.currency | string | Нет |
Актуальная валюта сделки.
Возможные значения: "rub", "usd". Если не указано, то оставляем текущее значение. |
| orders.revenue | string | Нет | Актуальная выручка. |
| orders.margin | string | Нет | Актуальная маржинальность сделки. Если не указано, оставляем текущее значение. |
| orders.orderLink | string | Нет | Ссылка на сделку в CRM. Если не передано, то оставляем текущее значение. |
| orders.orderName | string | Нет |
Название сделки в CRM. Если не передано, то оставляем текущее значение. |
| orders.addNewComment.text | string | Нет | Обновление комментария. Если до этого существовал комментарий у сделки, он перезатрется. |
| orders.manager | string | Нет | Актуальное ФИО менеджера. Любые символы, максимум 50. |
| orders.leadManager.manager | string | Нет |
Добавление менеджера к лиду, к которому приклеивается сделка. Любые символы, максимум 50. Если сделка не склеивается ни с каким лидом, то менеджер не добавится. Формат: "leadManager": {
|
|
orders.leadManager.overwrite |
boolean | Нет |
Перезаписываем ли существующего менеджера у лида, если он уже есть в лиде. Возможные значения:
Если не указан, по умолчанию false. |
| orders.addtags.tags | array | Нет |
Добавление тегов к сделке. Если такие теги уже есть в ЛК, новые не создаются, а используются существующие. Любые символы, максимум 100 в каждом теги. Максимум 100 тегов. Формат: "addTags": [
{"tag": "Тег 1"},
{"tag": "Тег 2"},
{"tag": "Тег N"}
]
|
| orders.addtags.overwrite | boolean | Нет |
Флаг перезатираем ли мы существующие у сделки теги или добавляем новые теги к существующим. Возможные значения:
Если не указан, по умолчанию false. |
| orders.addTagsToLead.tags | array | Нет |
Добавление тегов к лиду, к которому приклеивается сделка. Если такие теги уже есть в ЛК, новые не создаются, а используются существующие. Необязательно, максимум 100 тегов. Если сделка не склеивается ни с каким лидом, то теги соответственно не добавляем. Формат: "addTagsToLead": {
"tags": [
{ "tag": "Тег 1" },
{ "tag": "Тег 2" }
],
"overwrite": true
}
|
| orders.addTagsToLead.overwrite | boolean | Нет |
Флаг перезатираем ли мы существующие у лида теги или добавляем новые теги к существующим. Возможные значения:
Если не указан, по умолчанию false. |
| orders.customFields | array | Нет |
Пользовательские поля API в сделках. Для использования, пользовательские поля необходимо заранее добавить в настройках API ЛК Calltouch. Подробнее в статье. Пользовательские поля могут быть разных типов. Допустимое содержимое для полей каждого типа указано в статье. Формат: "customFields": [
{"field": "grossprofit", "value": "456.50"},
{"field": "new", "value": "123"},
{"field": "text", "value": "some string"}
]
Максимум 20 пользовательских полей. |
| orders.addCustomFieldsToLead.customFields | array | Нет |
Добавление пользовательских полей к лиду, с которым была склеена сделка. Для использования, пользовательские поля необходимо заранее добавить в настройках API ЛК Calltouch. Подробнее в статье. Пользовательские поля могут быть разных типов. Допустимое содержимое для полей каждого типа указано в статье. Если в рамках создания или обновления сделки она не была склеена с лидом - то содержимое addCustomFieldsToLead просто игнорируется. Формат: "addCustomFieldsToLead": {
"customFields": [
{"field": "test_field", "value": "test value"},
{"field": "num", "value": 123.4}
],
"overwrite": false
}
Максимум 20 пользовательских полей. |
| orders.addCustomFieldsToLead.overwrite | boolean | Нет |
Перезаписывать ли существующее значение пользовательского поля у лида или нет, при его наличии в лиде. Возможные значения:
|
| orders.products | array | Нет |
Товары, связанные со сделкой. Необязательный параметр. Если не передано, то оставляем текущие данные. |
| orders.products.name | string | Да, если передан orders.products |
Наименование товара. Любые символы, максимум 200. Если не передано, то оставляем текущие данные. |
| orders.products.brand | string | Нет |
Бренд, торговая марка товара. Любые символы, максимум 200. Если не передано, то оставляем текущие данные. |
| orders.products.category | string | Нет |
Категория товара. Любые символы, максимум 200. Если не передано, то оставляем текущие данные. |
| orders.products.variant | string | Нет |
Разновидность товара. Любые символы, максимум 200. Если не передано, то оставляем текущие данные. |
| orders.products.price | string | Нет |
Цена за единицу товара. Только числа, дробная часть отделяется точками, указывается до сотых. Максимум 20 символов. Если не передано, то оставляем текущие данные. |
| orders.products.quantity | integer | Нет |
Количество товаров. Только цифры, максимум 10 символов. Не может быть равно нулю. Если не передано, то оставляем текущие данные. |
| orders.reMatching | array | Нет | Перепривязка/отвязка сделки к/от лида. Вначале пытаемся подобрать тип матчинга, который сработает, и только если находим такой, то отвязываем сделку от текущего лида. |
| orders.reMatching.type | string | Обязательно, если указан reMatching, нужно указать хотя бы 1 тип матчинга в приоритете. |
Тип матчинга у сделки. Возможные значения:
Типы матчинга customSources и withoutSource являются конечными, т.е. нет смысла размещать под ними другие типы, т.к. типы customSources и withoutSource сработают 100%. Подробное описание полей в объекте matching в этой статье. |
| orders.orderContacts | object | Нет | Объект с контактами из сделки |
| orders.orderContacts.mainContacts | object | Нет | Объект с основными контактами из сделки |
| orders.orderContacts.mainContacts.fio | string | Нет | ФИО из сделки |
| orders.orderContacts.mainContacts.phoneNumber | string |
Да, если передан .mainContacts Обязательно передать хотябы 1 из контактов: phoneNumber, email, waPhone, tgId, tgUsername или vkId |
Основной номер телефона из сделки, в формате 7XXXXXXXXXX |
| orders.orderContacts.mainContacts.email | string | Основной email из сделки | |
| orders.orderContacts.mainContacts.waPhone | string | Основной номер телефона из W/p, в формате 7XXXXXXXXXX | |
| orders.orderContacts.mainContacts.tgId | string | Основной ID Telegram. Цифры, максимум 20. | |
| orders.orderContacts.mainContacts.tgUsername | string | Основное имя пользователя Telegram. Формат: @username, username. Латинские буквы a-z, цифры 0-9, и нижнее подчеркивание. Минимум 3 символа. Максимальная длина 100 символов (без учета @). | |
| orders.orderContacts.mainContacts.vkId | string | Основной ID Vkontakte. Цифры, максимум 20. | |
| orders.orderContacts.mainContacts.overwrite | boolean | Нет |
Нужно ли перезаписывать основные контакты если они уже есть в обновляемой сделке. Возможные значения:
Если не передан - по умолчанию true. Распространяется на все основные контактные данные. |
| orders.orderContacts.otherContacts | object | Нет | Объект с дополнительными контактами сделки |
| orders.orderContacts.otherContacts.phoneNumber | array | Нет |
Дополнительные номера телефона из сделки. В формате 7XXXXXXXXXX. Массив, максимум 3 штуки. Нельзя передавать дополнительные телефоны, если не был передан основной телефон. |
| orders.orderContacts.otherContacts.email | array | Нет |
Дополнительные Email из сделки. Массив, максимум 3 штуки. Нельзя передавать дополнительные Email, если не был передан основной Email. |
| orders.orderContacts.otherContacts.tgId | array | Нет |
Дополнительные ID Telegram. Цифры, максимум 20 в одном ID. Массив, максимум 3 штуки. Нельзя передавать дополнительные tgId, если не был передан основной tgId. |
| orders.orderContacts.otherContacts.tgUsername | array | Нет |
Дополнительные имя пользователя Telegram. Формат: @username, username. Латинские буквы a-z, цифры 0-9, и нижнее подчеркивание. Минимум 3 символа. Максимальная длина 100 символов в одном tgUsername (без учета @). Массив, максимум 3 штуки. Нельзя передавать дополнительные tgUsername, если не был передан основной tgUsername. |
| orders.orderContacts.otherContacts.vkId | array | Нет |
Дополнительные ID Vkontakte. Цифры, максимум 20 в одном ID. Массив, максимум 3 штуки. Нельзя передавать дополнительные vkId, если не был передан основной vkId. |
| orders.orderContacts.otherContacts.overwrite | boolean | Нет |
Нужно ли перезаписывать дополнительные контакты если они уже есть в обновляемой сделке. Возможные значения:
Если не передан - по умолчанию true. Распространяется на все дополнительные контактные данные. |
Ответ
Процесс обновления запускается сразу же после отправки запроса, после чего сразу же возвращается и ответ.
Пример ответа
{
"meta": [],
"data": {
"orders": [
{
"orderNumber": "UdvPC9bBjjLnEJ9R",
"updateStatus": "success",
"error": null
"matchedType":"call",
"callInfo": {
callId: 123456,
callReferenceId: "abc123",
sipCallId: "abc123-abc123"
},
"requestInfo": null,
"chatInfo": null
}
]
}
}
Параметры ответа
| Параметр | Формат | Описание |
| data.orders.orderNumber | string | Переданный ID сделки из внешний CRM в запросе на обновление. |
| data.orders.updateStatus | string |
Статус обновления. Возможные значения:
|
| data.orders.matchedType | string | Тип лида с которым сматчена обновленная сделка, "request" для заявок, "call" для звонков |
| data.orders[n].callInfo | object | Если сделка склеилась со звонком, то блок callInfo не пустой, иначе null |
| data.orders[n].callInfo.callId | string | ID звонка в Calltouch |
| data.orders[n].callInfo.callReferenceId | string | Внешний ID звонка |
| data.orders[n].callInfo.sipCallId | string | ID звонка с АТС |
| data.orders[n].requestInfo | object | Если сделка склеилась с заявкой, то блок requestInfo не пустой, иначе null |
| data.orders[n].requestInfo.requestId | integer | ID заявки в Calltouch |
| data.orders[n].requestInfo.requestNumber | string | Внешний ID заявки |
| data.orders[n].chatInfo | object | Если сделка склеилась с чатом, то блок chatInfo не пустой, иначе null |
| data.orders[n].chatInfo.chatId | integer | ID чата в Calltouch |
| data.orders.error | string | Отображается причина ошибки обновления |
Типовые ошибки
Если в запросе обнаруживаются ошибки валидации, то обновление не выполняется и выводится ошибка:
{
"meta": [],
"data": {
"type": "validationError",
"apiErrorData": null,
"validationErrorData": {
"violations": [
{
"fieldPath": "orders[0].statusDate",
"message": "Значение даты и времени недопустимо."
}
]
}
}
}
Если в запросе указаны некорректные авторизационные данные — то выводится ошибка. Список типовых ответов при запросах с некорректными авторизационными данными, или некорректными данными в теле API запроса вы можете посмотреть в этой статье.
Особенности обновления сделок
Обновление сделки выполняется только при наличии изменений значимых параметров.
Значимыми считаются изменения любых параметров сделки, передаваемых в запросе, за исключением параметра updateDate (Дата обновления сделки).
Если запрос на обновление не содержит значимых изменений (например, передан дубль или изменён только параметр updateDate), обновление сделки не выполняется.
Система баллов API Calltouch
Система баллов API — механизм, регулирующий нагрузку на сервера Calltouch. Для каждого проекта выдается индивидуальное суточное количество баллов За каждый успешно выполненный запрос списываются баллы. Подробнее читайте в статье: Система баллов API Calltouch.
Количество запросов в секунду к API Calltouch ограничено — не более 5 запросов в секунду с одного IP-адреса. Например, если в 1 секунду с одного IP-адреса поступит 11 API-запросов, то 5 выполнятся сразу, а остальные API-запросы завершатся с ошибкой c кодом 429 (Too Many Requests).