Использование

REST API для рассылок и отчётности

Клиентское REST API позволяет запускать рассылки по шаблонам WhatsApp Business API и забирать статистику доставки из своих систем: CRM, BI-панели, скрипты автоматизации.

API работает по модели «запрос — ответ»: вы сами обращаетесь к сервису тогда, когда вам нужны данные. Исходящих вебхуков на вашу сторону сервис не отправляет.

По умолчанию в ответах приходят метаданные сообщения, значения параметров шаблона и статусы доставки — без содержимого переписки. Тексты сообщений передаются, если вы явно запросите их параметром include_text; это сделано для того, чтобы уже написанная интеграция не начала получать переписку без вашего ведома.

Список методов

МетодНазначение
messages.send.templateОтправить одно сообщение по шаблону
messages.status.getСтатусы доставки по идентификаторам сообщений или по номеру
messages.history.listИстория сообщений линии за период с фильтрами и пагинацией
messages.stats.getСчётчики за период: отправлено, доставлено, прочитано, ошибки, ответы
templates.listШаблоны линии, одобренные провайдером
templates.analytics.getАналитика провайдера по шаблонам рядом с нашими счётчиками
campaigns.createСоздать черновик рассылки
campaigns.recipients.addЗагрузить получателей в черновик
campaigns.startЗапустить рассылку
campaigns.cancelОстановить выполняющуюся рассылку
campaigns.listСписок рассылок портала
campaigns.stats.getВоронка по рассылке
campaigns.recipients.listПострочный отчёт по получателям рассылки
line.status.getСостояние одной линии
portal.status.getСостояние всех линий портала

Пустой метод (обращение к базовому адресу) отдаёт этот же список в машинном виде — с обязательными и необязательными параметрами каждого метода и действующими лимитами.

Получение токена

Токен выдаётся в приложении Олчат в Битрикс24: «Настройки приложения» — вкладка «REST API» — кнопка «Выдать / перевыпустить токен». Рядом показывается базовый адрес API.

Выдать, посмотреть или отозвать токен может только администратор портала Битрикс24: право проверяется в самом Битрикс24 в момент запроса. У остальных сотрудников вкладка показывает надпись «Токен доступен администратору портала».

Токен принадлежит порталу целиком, а не отдельной линии: одним токеном вы работаете со всеми подключёнными номерами портала, указывая нужный в параметре line_number.

Повторное нажатие «Выдать / перевыпустить токен» выдаёт новое значение и одновременно обесценивает прежнее — все интеграции на старом токене сразу начнут получать ошибку 401. Кнопка «Отозвать» отключает доступ полностью.

Формат запросов

Базовый адрес:

https://waba.olchat.io/rest/client/v2/<метод>/

Токен передаётся заголовком OLChat-Api-Token. В адресе и в query-строке токен не принимается.

Поддерживаются GET и POST. Простые параметры можно передавать query-строкой или формой, составные (списки получателей, параметры шаблона) — только JSON-телом с Content-Type: application/json.

Пример:

curl -X POST 'https://waba.olchat.io/rest/client/v2/messages.stats.get/' \
  -H 'OLChat-Api-Token: ВАШ_ТОКЕН' \
  -H 'Content-Type: application/json' \
  -d '{"line_number": 12, "date_from": "2026-07-01", "date_to": "2026-07-31"}'

Даты принимаются в формате ISO-8601 (2026-07-01 или 2026-07-01T10:00:00+03:00) либо числом секунд epoch. Все даты в ответах — ISO-8601.

Список доступных методов и действующие лимиты отдаёт сам сервис по базовому адресу без указания метода.

Ограничения

ОграничениеЗначение
Частота запросов5 запросов за 3 секунды на пару «токен + метод»
Глубина статистики92 дня
Размер страницыдо 500 записей, по умолчанию 100
Получателей в одном запроседо 1000
Аналитика провайдерадо 90 дней, обновляется раз в сутки
Одновременно выполняющихся рассылокдо 5 на портал
Окно ожидания ответаот 1 до 720 часов

Лимит частоты считается отдельно для каждого метода: обращение к messages.stats.get не расходует лимит campaigns.start. Ответ 429 означает, что запрос не выполнен — его нужно повторить, а не считать неудачей операции.

Отправка сообщений

Одно сообщение по шаблону

messages.send.template отправляет одно сообщение по одобренному шаблону. Заводить ради одного получателя рассылку не нужно.

ПараметрТипОписание
line_number*intНомер линии
phone*strНомер абонента в любой записи
template_name*strИмя шаблона
template_languagestrЯзык шаблона, если одно имя используется в нескольких языках
template_paramslistЗначения подстановок в порядке их следования в шаблоне

В ответе — блок message в том же виде, что и в истории: идентификатор сообщения, номер, время создания, имя и язык шаблона, значения подстановок и блок статусов. Идентификатор из ответа используйте дальше в messages.status.get.

Число переданных подстановок должно совпадать с числом подстановок в шаблоне, иначе метод ответит ошибкой template_params_mismatch и сообщение отправлено не будет. Отправка на линию с просроченной оплатой или без подключения отклоняется с line_not_active.

Отчётность

История сообщений

messages.history.list — сообщения линии за период с пагинацией и фильтрами.

ПараметрТипОписание
line_number*intНомер линии
date_from*dateНачало периода
date_to*dateКонец периода
directionstrincoming, outgoing или all
phonestrНомер абонента
template_namestrИмя шаблона
sent, delivered, readboolФильтр по статусу
errors_onlyboolТолько сообщения с ошибкой
page, page_sizeintСтраница и её размер
include_textboolДобавить текст сообщения и описание вложения

Параметр include_text: true добавляет к каждому сообщению его текст. Работает и для входящих, и для исходящих. У сообщения с вложением приходит блок attachment с типом вложения и именем файла; само содержимое файла и ссылка на скачивание через API не передаются. Без этого параметра поля text и attachment в ответе отсутствуют.

В ответе — total, page, page_size и массив messages. Каждое сообщение содержит message_id, line_number, direction, phone, created_at, имя, язык и значения параметров шаблона, блок status со значениями sent/delivered/read и временем каждого, status_source, текст ошибки, признак тарификации и модель тарификации.

Статус конкретных сообщений

messages.status.get — состояние доставки по идентификаторам либо по паре «номер абонента + период».

ПараметрТипОписание
line_number*intНомер линии
message_idsstrИдентификаторы через запятую
phonestrНомер абонента, если идентификаторы не известны
date_from, date_todateПериод, обязателен при запросе по номеру
include_textboolДобавить текст сообщения и описание вложения

Идентификатор, не принадлежащий линиям вашего портала, просто отсутствует в ответе — запрос при этом успешен. За один раз принимается не более 500 идентификаторов: на большем количестве метод отвечает ошибкой too_many_message_ids, а не отдаёт часть молча.

Агрегированная статистика

messages.stats.get — счётчики за период: отправлено, доставлено, прочитано, ошибок, ответов.

Обратите внимание на базы счётчиков: sent, delivered, read, errors и total считаются по всем исходящим сообщениям линии — операторским, роботным и рассылочным. replied считается только по получателям рассылок: ответы отслеживаются в окне ответа кампании. Чтобы доля ответов была осмысленной, рядом отдаётся campaign_sent — база именно для replied. Оба поля есть при group_by=total.

ПараметрТипОписание
line_number*intНомер линии
date_from*, date_to*dateПериод, не длиннее 92 дней
group_bystrtotal (по умолчанию), day или template

Счётчик replied считается по получателям рассылок: сообщения вне рассылок в него не попадают.

Состояние линий

line.status.get (параметр line_number) и portal.status.get (без параметров) отдают номер телефона, статус подключения, признак активности, признак демонстрационного режима и дату оплаты. Ключи доступа к провайдеру в ответах не передаются.

Список шаблонов

templates.list (параметр line_number) — доступные шаблоны линии: имя, идентификатор, язык, статус согласования, категория и число параметров.

Список берётся из того же источника, против которого проверяется отправка, поэтому шаблон из этого метода гарантированно пригоден для рассылки. Если линия не подключена к провайдеру, метод отвечает line_not_connected.

Рассылки

Рассылка проходит четыре шага: создание черновика, загрузка получателей, запуск, наблюдение за воронкой.

Создание рассылки

campaigns.create

ПараметрТипОписание
line_number*intНомер линии
template_name*strИмя шаблона
namestrНазвание рассылки
template_languagestrЯзык шаблона, по умолчанию ru
template_paramslistЗначения параметров шаблона по умолчанию
reply_window_hoursintОкно ожидания ответа, по умолчанию 72 часа

Число значений в template_params проверяется по составу шаблона: несовпадение отклоняется с ошибкой template_params_mismatch.

Загрузка получателей

campaigns.recipients.add — до 1000 получателей за запрос, черновик можно наполнять несколькими запросами.

ПараметрТипОписание
campaign_id*intИдентификатор рассылки
recipients*listСписок получателей

Персональные параметры получателя передаются списком в том же порядке, что и подстановки шаблона. Значение другого типа (например объект \{"1": "Иван"\}) отклоняется с причиной invalid_params: раньше такой получатель принимался и получал текст с параметрами кампании вместо своих.

Получатель — либо номер строкой, либо объект:

{
  "campaign_id": 17,
  "recipients": [
    "79001234567",
    {"phone": "79007654321", "external_id": "CRM-4821", "params": ["Иван", "12 августа"]}
  ]
}

Персональные значения params замещают значения рассылки по умолчанию. Поле external_id возвращается обратно в отчётах — по нему удобно сопоставлять получателей со своими записями.

Ответ содержит число принятых и список отклонённых с причиной: invalid_phone (номер не похож на телефон) или duplicate (номер уже есть в этой рассылке). Повторная загрузка того же номера дубля не создаёт, поэтому запрос можно безопасно повторить после обрыва связи.

Запуск и отмена

campaigns.start (параметр campaign_id) переводит рассылку в работу. Перед запуском проверяются подключение и оплата линии; повторный запуск отвечает 409.

Отправка идёт порциями в фоне, поэтому метод возвращает управление сразу, не дожидаясь конца рассылки.

campaigns.cancel (параметры campaign_id, reason) останавливает рассылку: неотправленные получатели переводятся в skipped, следующая порция не запускается. Уже отправленные сообщения отменить нельзя — они у абонентов.

В ответе кроме skipped приходит in_flight — число получателей, по которым обращение к провайдеру было разрешено до того, как отмена дошла. Только по ним сообщение ещё может уйти: отозвать отправленный по сети запрос нельзя. Получатели, просто взятые обработчиком в работу, но не дошедшие до отправки, в это число не входят — они переводятся в skipped без обращения к провайдеру. Если in_flight больше нуля, окончательные статусы этих получателей смотрите в campaigns.recipients.list через минуту-другую.

Наблюдение

campaigns.stats.get (параметр campaign_id) отдаёт воронку: total, pending, sent, delivered, read, replied, errors, skipped, no_whatsapp, unknown, а также статус рассылки и время запуска и завершения.

campaigns.recipients.list (параметры campaign_id, status, page, page_size) — построчный отчёт: номер, external_id, статус, ошибка, идентификатор сообщения, время отправки, доставки, прочтения и ответа.

campaigns.list (параметры line_number, status, page, page_size) — список рассылок портала.

Статусы рассылки: draft, running, completed, cancelled.

Статусы получателя: pending (ожидает), processing (в обработке), success (отправлено), error (ошибка), skipped (пропущен при отмене), no_whatsapp (на номере нет WhatsApp), unknown (результат неизвестен).

Статус unknown появляется, если обработчик прервался между отправкой и получением ответа провайдера. Автоматически такой номер повторно не отправляется: сообщение могло уйти и уже быть оплачено, а повтор означал бы второе сообщение абоненту и второй счёт. Решение по таким номерам принимаете вы.

Аналитика шаблонов

templates.analytics.get показывает значения провайдера рядом с нашими за один и тот же период.

ПараметрТипОписание
line_number*intНомер линии
date_from*, date_to*dateПериод
template_namestrОдин шаблон вместо всех

Данные провайдера выгружаются фоновой задачей раз в сутки, поэтому за сегодняшний день их может ещё не быть. Признак has_provider_data и поле fetched_at показывают, есть ли выгрузка и насколько она свежая; наши счётчики отдаются в любом случае.

Фоновая выгрузка забирает у провайдера последние 30 дней, а запросить можно период до 92 дней. Чтобы частичное покрытие не выглядело полным, в ответе есть блок provider_coverage с фактическими границами дат, за которые выгрузка у нас есть. Наши счётчики покрывают весь запрошенный период.

Небольшое расхождение между колонками — норма: провайдер считает по своим суткам и включает переходы по кнопкам, которых в нашей статистике нет.

Коды ошибок

Ошибка возвращается телом \{"error": "<код>"\} с соответствующим HTTP-статусом.

КодСтатусПричина
unauthorized401Токен отсутствует, неизвестен или отозван
rate_limit_exceeded429Превышена частота запросов
unknown_method404Метод не существует
line_not_found404Линия не найдена или принадлежит другому порталу
campaign_not_found404Рассылка не найдена или принадлежит другому порталу
line_number_required400Не передан номер линии
period_required400Не передан период
invalid_period400Начало периода позже его конца
period_too_long400Период длиннее 92 дней
invalid_datetime400Дата не разобрана
invalid_direction400Недопустимое значение direction
invalid_group_by400Недопустимое значение group_by
invalid_pagination400Недопустимые page или page_size
message_ids_or_phone_required400Не передан ни идентификатор, ни номер
line_not_connected400Линия не подключена к провайдеру
template_not_found400Шаблон не найден среди доступных линии
template_params_mismatch400Число значений не совпадает с числом параметров шаблона
recipients_required400Не передан список получателей
batch_too_large400Больше 1000 получателей в одном запросе
no_recipients400Запуск рассылки без получателей
line_not_paid400Линия не оплачена
campaign_not_draft409Получателей можно добавлять только в черновик
campaign_already_started409Рассылка уже запущена
campaign_not_running409Отменить можно только запущенную рассылку
too_many_running_campaigns409Больше пяти одновременно выполняющихся рассылок на портал
invalid_reply_window400Окно ожидания ответа вне диапазона 1–720 часов
invalid_params400Параметры шаблона переданы не списком
phone_required400Не передан номер абонента
template_name_required400Не передано имя шаблона
invalid_phone400Номер не распознан
template_params_mismatch400Число подстановок не совпадает с шаблоном
template_not_found404Шаблон не найден среди одобренных на линии
line_not_active403Линия не подключена или оплата просрочена
templates_unavailable503Список шаблонов у провайдера временно недоступен, повторите позже
provider_error502Провайдер отклонил отправку
send_failed502Сбой связи с провайдером
too_many_message_ids400Больше 500 идентификаторов в одном запросе статусов
invalid_datetime400Дата не разобрана: нужен ISO‑8601 или epoch в секундах
internal_error500Внутренняя ошибка сервиса

Линия или рассылка другого портала неотличима от несуществующей — это сделано намеренно, чтобы по ответам API нельзя было выяснить чужие настройки.

О чём стоит знать заранее

Время статусов. С 3 августа 2026 года время доставки и прочтения записывается таким, каким его сообщил провайдер, а не временем обработки события на нашей стороне. У каждого сообщения есть поле status_source: provider — время провайдера, internal — время обработки. Сообщения, отправленные до этой даты, остались со значением internal; при сравнении периодов «до» и «после» это стоит учитывать.

Сопоставление ответа с рассылкой. Ответ абонента засчитывается получателю рассылки, если он пришёл после отправки и внутри окна ожидания (по умолчанию 72 часа). Если один и тот же номер участвует в нескольких рассылках с пересекающимися окнами, ответ засчитывается ближайшей по времени отправке — разделить, на какую именно рассылку ответил абонент, по одному входящему сообщению невозможно.

Приостановка рассылки. Отдельного метода паузы нет. Останавливает рассылку только campaigns.cancel, и возобновить отменённую нельзя — оставшихся получателей переносят в новую рассылку.

Фильтр по имени шаблона и старая переписка. Отбор истории и группировка статистики по template_name опираются на структурированные данные сообщения. Сообщения старше 10 июля 2024 года хранятся в прежнем формате и под такой отбор не попадают: за периоды до этой даты запрашивайте историю без фильтра по шаблону.

Срок хранения истории. Сообщения хранятся год. Данные старше года удаляются, поэтому история и статистика доступны за последние 12 месяцев. Если вам нужна более длинная история, выгружайте её к себе регулярно.

Формат номера и дат. Номер в фильтрах принимается в любой записи — +7 999 123-45-67 и 79991234567 дают один результат. Даты принимаются в ISO‑8601 (2026-08-01, 2026-08-01T10:00:00Z), в сжатом виде (20260801) и как epoch в секундах.

На этой странице