Каналы
Канал — подключённый источник переписки: WhatsApp, Telegram, Instagram, SIP-телефония и т.д. Через публичный REST API вы читаете список каналов и их состояние подключения, управляете жизненным циклом уже подключённого канала (пауза/возобновление/переподключение/отключение) и настраиваете правила доступа операторов к каналу. Само подключение и первичная настройка выполняются через мастер в личном кабинете, а не через этот API.
Подключение канала
Подключение и первичная настройка канала (QR-код, OAuth с Meta, SIP-провижининг) выполняются через мастер в личном кабинете (my.aisar.app/settings/channels/add), а не напрямую через этот API — мастер использует отдельные, специфичные для каждого провайдера эндпоинты подключения.
Жизненный цикл
Жизненный цикл канала отражают два поля:
setup_state(draft → pairing → ready | failed) — этап первичной настройки.status(connected | disconnected | connecting | reconnecting | paused | expired | banned) — текущее состояние уже настроенного канала.banned— не тупик: если провайдер снял блокировку аккаунта, канал можно переподключить обычным reconnect/пейрингом; если блокировка ещё действует, провайдер отклонит подключение и канал вернётся вbanned.
Профиль WhatsApp-номера
Аватар и тексты профиля читаются и меняются через /v1/channels/{channel}/whatsapp/profile. Набор доступных полей зависит не от типа канала, а от того, что умеет конкретное подключение, поэтому ответ всегда содержит capabilities: у WhatsApp Business доступны about, description, адрес, почта, сайты и категория, у WhatsApp, подключённого по QR, — фото и about, а описание — только если номер работает в приложении WhatsApp Business. Опирайтесь на capabilities и limits из ответа: попытка прислать неподдержанное поле отклоняет запрос целиком, а не применяет его частично.
Заблокированные пользователи WhatsApp (blocked-users)
GET /channels/{channel}/whatsapp/blocked-users (с 2026-09-04) читает список номеров, заблокированных ПРОВАЙДЕРОМ на этом канале — это не список контактов, заблокированных внутри AISAR (тем управляют POST /contacts/{contact}/block и /unblock, см. группу «Контакты»). Формат элементов numbers[] зависит от типа подключения: у WhatsApp Business (Cloud API) это номер в формате провайдера (например +77001111111), у WhatsApp по QR (whatsmeow) — WhatsApp JID (например 77009998877@s.whatsapp.net). Пагинация курсорная: передайте after со значением next_cursor предыдущего ответа за следующей страницей; next_cursor: null означает конец списка. limit — от 1 до 1000, по умолчанию 100.
Доступен только для WhatsApp-каналов (whatsapp/whatsapp_business) — на канале другого типа ответ 422 {error_code: "channel_not_whatsapp"}; отключённый канал — 409 {error_code: "channel_offline"}. Авторизация — право channel:view (а не contact:update, как у block/unblock): это чтение состояния канала, а не действие над контактом; чужой канал — 403.
Временная блокировка исходящих у SIP-транка (`sip_outbound_gated`)
У канала sip_telephony, подключённого по IP-адресу оборудования оператора (см. руководство по подключению каналов, раздел «SIP-телефония (BYO-транк)»), может быть временно закрыт исходящий трафик, если тот же адрес уже используется другой компанией AISAR у того же оператора. Это отражено булевым полем sip_outbound_gated — оно присутствует у КАЖДОГО канала (не только sip_telephony) и равно false, если ограничение не действует. Пока sip_outbound_gated: true, канал по-прежнему принимает входящие звонки, но POST /calls/originate и POST /softphone/external-call для него ведут себя так, будто у компании нет ни одного подключённого SIP-канала. Ограничение снимается автоматически, без вызова какого-либо эндпоинта, как только на номер канала приходит первый подтверждённый входящий звонок.
Архивные каналы
Канал, удалённый с сохранением истории (DELETE /channels/{channel} без keep_history=false — так по умолчанию, см. ниже), не пропадает: он soft-deleted, помечен archived_at, а его переписка остаётся доступной на чтение внутри AISAR. Обычный GET /channels такие каналы не возвращает, и параметра, который включил бы их обратно в общий список, не существует — include_archived в валидации GET /channels не описан, и любое его значение молча игнорируется. Единственный способ увидеть архивный канал — отдельный список GET /channels/archived.
GET /channels/archived отдаёт тот же ChannelListResource, что и обычный список, плюс заполненные archived_at и messages_count (число сообщений канала, включая впоследствии удалённые по отдельности). Момент архивации отмечен вебхук-событием channel.archived (см. справочник событий вебхуков) — этот список и есть то место, где канал, о котором оно уведомило, можно найти позже. GET /channels/{channel} по id архивного канала отдаёт 404 — это штатное поведение (route-model binding не резолвит soft-deleted модель), а не признак того, что канал потерян.
Окончательное, необратимое удаление архивного канала вместе с историей — DELETE /channels/archived/{channelId} (channelId — целое число: soft-deleted канал не резолвится через route-model binding, поэтому путь принимает id напрямую, а не {channel}). Ответ 200 означает, что удаление поставлено в очередь фоновой задачей, а не что оно уже завершилось.
Тела запросов жизненного цикла
Пауза/возобновление/отключение вызываются без тела запроса, а переподключение (POST /channels/{channel}/reconnect) для OAuth/бот-каналов принимает provider-specific тело (Instagram/Threads — { code }, WhatsApp Business — { authorization_code, waba_id, phone_number_id }, Telegram Bot — { bot_token }), иначе 422; для WhatsApp/Telegram по QR и Live Chat тело пустое. Полный контракт по типам приведён в партнёрской документации (гайд о подключении каналов, секция «Прямой API»).
provider_key и тип канала
Поле provider_key — публичный, нейтральный идентификатор провайдера; внутренние имена runtime-библиотек наружу никогда не отдаются. Полный перечень значений и правила маппинга QR-каналов — в справочнике «Типы: мессенджинг», тип Channel. Чтобы различать тип канала в коде, опирайтесь на channel_type.key, а не на отображаемое имя.
Пагинация логов канала
GET /channels/{channel}/logs пагинирован: page/per_page (принимается и алиас perPage), максимум 500, по умолчанию 200. До 2026-08-25 эндпоинт параметры пагинации молча игнорировал и всегда отдавал новейшие 200 строк — заглянуть дальше в историю было нельзя. Сортировка — created_at desc, затем id desc: рантайм пишет пачки логов в пределах одной секунды, и без вторичной сортировки по id одна и та же строка могла повториться на одной странице и пропасть с другой. Ответ обёрнут как у прочих постраничных списков: элементы — в data, служебная информация — в meta (current_page, last_page, per_page, total); формат самого элемента лога не менялся.
Коды сбоя отправки в журнале канала
Помимо кодов подключения (connection.ready, connection.lost и т. п.), GET /channels/{channel}/logs (с 2026-08-26) пишет две записи о судьбе исходящих сообщений. message.send.failed.{error_code} — уровень error: одна запись на исчерпавшую все повторные попытки отправку (не на каждую попытку — иначе рассылка затопила бы журнал канала), {error_code} — код ошибки последней попытки либо unknown; context несёт message_id, attempts, error_code и усечённый response (только reason/status/response из ответа рантайма/провайдера — внутренний адрес рантайма из response исключён по соображениям ИБ). message.status.failed_suppressed — уровень warning: провайдер прислал квитанцию о сбое ПОСЛЕ того, как сообщение уже получило delivered/read/played — статус сообщения не понижается (см. событие message.status.updated), но сам факт провайдерской ошибки фиксируется здесь; context несёт message_id и reason (человекочитаемая причина).
sip_status в ответе eligibility
sip_status внутри eligibility.calling (в ответе GET .../whatsapp-calling, а также POST .../whatsapp-calling/enable|disable) — производное поле AISAR, не сырой статус Meta: ENABLED, когда на канале включены звонки (сохранён config.calling_did), NOT_SET — звонки не включены, UNKNOWN — не удалось получить ответ от Graph API (детали — в unknown_reason/detail на верхнем уровне ответа). Для решения «доступны ли звонки прямо сейчас» надёжнее полагаться на active (true только когда can_receive_call_sip === "AVAILABLE") и сам can_receive_call_sip — они всегда отражают текущее состояние Meta, тогда как sip_status — локальное зеркало последнего успешного enable/disable на стороне AISAR и может не увидеть изменение, сделанное напрямую в WhatsApp Manager.
Эндпоинты
| Метод | Путь | Описание |
|---|---|---|
| GET | /v1/channelsСписок каналов компании (по умолчанию без черновиков настройки). | Список каналов компании (по умолчанию без черновиков настройки). |
| GET | /v1/channels/{channel}Получить канал по id вместе с конфигурацией провайдера. | Получить канал по id вместе с конфигурацией провайдера. |
| POST | /v1/channelsСоздать канал (опционально сразу запустив pairing); обычно каналы подключают через мастер в кабинете. | Создать канал (опционально сразу запустив pairing); обычно каналы подключают через мастер в кабинете. |
| PATCH | /v1/channels/{channel}Обновить настройки канала: name, description, account_name и тумблеры allow_broadcasts / allow_automations / allow_inbound_handling. POST и PUT по этому пути тоже принимаются. | Обновить настройки канала: name, description, account_name и тумблеры allow_broadcasts / allow_automations / allow_inbound_handling. POST и PUT по этому пути тоже принимаются. |
| GET | /v1/channel-typesСправочник типов каналов с их возможностями (capabilities) и провайдерами. | Справочник типов каналов с их возможностями (capabilities) и провайдерами. |
| POST | /v1/channels/{channel}/connect/startЗапустить подключение runtime-канала (WhatsApp/Telegram/Instagram по QR): тело { "mode": "qr" | "code" | "phone", "phone_number"? }. Затем опрашивайте GET /channels/{channel}/connection. | Запустить подключение runtime-канала (WhatsApp/Telegram/Instagram по QR): тело { "mode": "qr" | "code" | "phone", "phone_number"? }. Затем опрашивайте GET /channels/{channel}/connection. |
| GET | /v1/channels/{channel}/connectionСнимок состояния подключения для поллинга собственного QR-UI: connection.status (draft, qr_required, pairing_required, authorizing, 2fa_required, connected, reconnecting, expired, error, disconnected), объект qr, pairing_code (для режима code) и pairing_state. | Снимок состояния подключения для поллинга собственного QR-UI: connection.status (draft, qr_required, pairing_required, authorizing, 2fa_required, connected, reconnecting, expired, error, disconnected), объект qr, pairing_code (для режима code) и pairing_state. |
| POST | /v1/channels/{channel}/auth-codeПередать SMS-код или 2FA-пароль в рантайм (авторизация Telegram Personal). | Передать SMS-код или 2FA-пароль в рантайм (авторизация Telegram Personal). |
| POST | /v1/channels/{channel}/disconnectОтключить канал (прекратить приём/отправку сообщений). | Отключить канал (прекратить приём/отправку сообщений). |
| POST | /v1/channels/{channel}/reconnectПереподключить ранее отключённый канал. Тело запроса зависит от типа канала: для OAuth/бот-каналов обязательны provider-поля (Instagram/Threads — { code }, WhatsApp Business — { authorization_code, waba_id, phone_number_id }, Telegram Bot — { bot_token }), иначе 422; для WhatsApp/Telegram по QR и Live Chat тело пустое. Требуется право channel:update; чужой канал — 404. Подробный контракт по типам — в партнёрской документации (гайд о подключении каналов, секция «Прямой API»). | Переподключить ранее отключённый канал. Тело запроса зависит от типа канала: для OAuth/бот-каналов обязательны provider-поля (Instagram/Threads — { code }, WhatsApp Business — { authorization_code, waba_id, phone_number_id }, Telegram Bot — { bot_token }), иначе 422; для WhatsApp/Telegram по QR и Live Chat тело пустое. Требуется право channel:update; чужой канал — 404. Подробный контракт по типам — в партнёрской документации (гайд о подключении каналов, секция «Прямой API»). |
| POST | /v1/channels/{channel}/pauseПриостановить канал (временно, без разрыва сессии). | Приостановить канал (временно, без разрыва сессии). |
| POST | /v1/channels/{channel}/resumeВозобновить работу приостановленного канала. | Возобновить работу приостановленного канала. |
| DELETE | /v1/channels/{channel}Удалить канал (мягкое удаление). По умолчанию (`keep_history` не передан или `true`) переписка сохраняется и канал становится архивным — доступен через GET /channels/archived; `keep_history=false` удаляет канал вместе с историей безвозвратно. | Удалить канал (мягкое удаление). По умолчанию (`keep_history` не передан или `true`) переписка сохраняется и канал становится архивным — доступен через GET /channels/archived; `keep_history=false` удаляет канал вместе с историей безвозвратно. |
| GET | /v1/channels/archivedАрхивные каналы — удалённые с сохранением истории (см. «Архивные каналы» выше). Обычный список их не возвращает; параметра, включающего их обратно, не существует. | Архивные каналы — удалённые с сохранением истории (см. «Архивные каналы» выше). Обычный список их не возвращает; параметра, включающего их обратно, не существует. |
| DELETE | /v1/channels/archived/{channelId}Окончательно и безвозвратно удалить архивный канал вместе с историей (выполняется фоновой задачей). | Окончательно и безвозвратно удалить архивный канал вместе с историей (выполняется фоновой задачей). |
| GET | /v1/channels/{channel}/logsЛоги канала (события подключения, ошибки) с пагинацией: `page`/`per_page` (принимается и `perPage`; максимум 500, по умолчанию 200), сортировка — `created_at` desc, затем `id` desc. | Логи канала (события подключения, ошибки) с пагинацией: `page`/`per_page` (принимается и `perPage`; максимум 500, по умолчанию 200), сортировка — `created_at` desc, затем `id` desc. |
| GET | /v1/channels/{channel}/whatsapp-callingГотовность WhatsApp-звонков (eligibility): предпосылки Meta и блокирующие проблемы. Только для Meta/WABA-каналов (иначе 404); требует прав на управление телефонией (иначе 403). | Готовность WhatsApp-звонков (eligibility): предпосылки Meta и блокирующие проблемы. Только для Meta/WABA-каналов (иначе 404); требует прав на управление телефонией (иначе 403). |
| POST | /v1/channels/{channel}/whatsapp-calling/enableВключить WhatsApp-звонки на номере. Meta/WABA-каналы, права на телефонию. При невыполненных предпосылках — HTTP 422 с ok:false и error_code. | Включить WhatsApp-звонки на номере. Meta/WABA-каналы, права на телефонию. При невыполненных предпосылках — HTTP 422 с ok:false и error_code. |
| POST | /v1/channels/{channel}/whatsapp-calling/disableОтключить WhatsApp-звонки на номере. Meta/WABA-каналы, права на телефонию. | Отключить WhatsApp-звонки на номере. Meta/WABA-каналы, права на телефонию. |
| GET | /v1/channels/{channel}/whatsapp/profileПрофиль WhatsApp-номера: аватар и тексты, которые собеседник видит в карточке. В ответе есть `capabilities` — набор полей, доступных именно этому каналу, и `limits` с ограничениями длины; ориентируйтесь на них, а не на тип канала. Если провайдер недоступен, вернётся последняя сохранённая копия с `stale: true`. Требует права channel:view. | Профиль WhatsApp-номера: аватар и тексты, которые собеседник видит в карточке. В ответе есть `capabilities` — набор полей, доступных именно этому каналу, и `limits` с ограничениями длины; ориентируйтесь на них, а не на тип канала. Если провайдер недоступен, вернётся последняя сохранённая копия с `stale: true`. Требует права channel:view. |
| POST | /v1/channels/{channel}/whatsapp/profileОбновить профиль номера. Отправляется только то, что меняется; поле, не поддержанное каналом, отклоняет весь запрос с HTTP 422 и кодом `field_not_supported`. Аватар передаётся файлом `picture` в multipart (JPG/PNG/WebP, до 5 МБ, сторона от 192 пикселей) — мы сами обрежем его по квадрату и уберём метаданные съёмки. `about` пустым быть не может. Требует права channel:update; частота изменений ограничена. | Обновить профиль номера. Отправляется только то, что меняется; поле, не поддержанное каналом, отклоняет весь запрос с HTTP 422 и кодом `field_not_supported`. Аватар передаётся файлом `picture` в multipart (JPG/PNG/WebP, до 5 МБ, сторона от 192 пикселей) — мы сами обрежем его по квадрату и уберём метаданные съёмки. `about` пустым быть не может. Требует права channel:update; частота изменений ограничена. |
| DELETE | /v1/channels/{channel}/whatsapp/profile/pictureСнять аватар номера. Поддерживается не всеми провайдерами: смотрите `capabilities.picture_remove` в ответе GET — у WhatsApp Business фото можно только заменить. Требует права channel:update. | Снять аватар номера. Поддерживается не всеми провайдерами: смотрите `capabilities.picture_remove` в ответе GET — у WhatsApp Business фото можно только заменить. Требует права channel:update. |
| GET | /v1/channels/{channel}/whatsapp/blocked-usersСписок номеров, заблокированных провайдером на этом WhatsApp-канале (query: after, limit) — не список контактов, заблокированных внутри AISAR. Только WhatsApp-каналы; требует channel:view. | Список номеров, заблокированных провайдером на этом WhatsApp-канале (query: after, limit) — не список контактов, заблокированных внутри AISAR. Только WhatsApp-каналы; требует channel:view. |
| GET | /v1/channels/{channel}/accessПравила доступа операторов/команд к каналу. | Правила доступа операторов/команд к каналу. |
| POST | /v1/channels/{channel}/accessОбновить правила доступа к каналу (allow/block по команде или пользователю). | Обновить правила доступа к каналу (allow/block по команде или пользователю). |
| GET | /v1/channels/{channel}/templates/sendableШаблоны, доступные для вставки в чат-пикер этого канала. Для WhatsApp Business — привязанные к каналу шаблоны со `status=published` и `meta_status=approved` (отправляются через POST /messages/send-template). Для остальных типов каналов — опубликованные шаблоны компании того же channel_type (без привязки к каналу и без модерации Meta); фронт вставляет их готовый текст в поле ввода как обычное сообщение, а не через template-send API. | Шаблоны, доступные для вставки в чат-пикер этого канала. Для WhatsApp Business — привязанные к каналу шаблоны со `status=published` и `meta_status=approved` (отправляются через POST /messages/send-template). Для остальных типов каналов — опубликованные шаблоны компании того же channel_type (без привязки к каналу и без модерации Meta); фронт вставляет их готовый текст в поле ввода как обычное сообщение, а не через template-send API. |
Примеры
Список подключённых каналов
Запрос
curl -X GET "https://api.aisar.app/v1/channels?status=connected" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": [
{
"id": 3,
"company_id": 1,
"channel_type_id": 1,
"provider_key": "whatsapp",
"name": "Основной WhatsApp",
"account_name": "+77001234567",
"status": "connected",
"setup_state": "ready",
"allow_broadcasts": true,
"allow_automations": true,
"allow_inbound_handling": true,
"connected_at": "2026-01-15T09:00:00Z",
"last_inbound_at": "2026-02-09T18:00:00Z",
"channel_type": { "id": 1, "key": "whatsapp", "name": "WhatsApp" }
}
]
}Приостановка канала
Запрос
curl -X POST "https://api.aisar.app/v1/channels/3/pause" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": {
"message": "Channel status updated.",
"channel": {
"id": 3,
"status": "paused",
"status_changed_at": "2026-02-09T18:30:00Z"
}
}
}Переподключить канал (Instagram — с телом)
Запрос
curl -X POST "https://api.aisar.app/v1/channels/9/reconnect" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "code": "AQB..." }'Ответ
{
"data": {
"message": "Channel reconnected.",
"channel": {
"id": 9,
"status": "connected",
"setup_state": "ready"
}
}
}Переименовать канал и переключить тумблеры
Запрос
curl -X PATCH "https://api.aisar.app/v1/channels/3" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Отдел продаж — WhatsApp",
"allow_broadcasts": false,
"allow_automations": true
}'Ответ
{
"data": {
"message": "Channel updated.",
"channel": {
"id": 3,
"name": "Отдел продаж — WhatsApp",
"allow_broadcasts": false,
"allow_automations": true,
"allow_inbound_handling": true,
"status": "connected",
"setup_state": "ready"
}
}
}Канал с конфигурацией провайдера
Запрос
curl -X GET "https://api.aisar.app/v1/channels/3" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"channel": {
"id": 3,
"company_id": 1,
"channel_type_id": 1,
"provider_key": "whatsapp",
"name": "Основной WhatsApp",
"account_name": "+77000000001",
"status": "connected",
"setup_state": "ready",
"channel_type": { "id": 1, "key": "whatsapp", "name": "WhatsApp" }
},
"provider_config": {
"mark_online_on_connect": {
"value": true,
"label": "Отмечать онлайн при подключении",
"description": "Показывать аккаунт онлайн, пока канал подключён"
}
}
}
}Создание канала с запуском pairing
Запрос
curl -X POST "https://api.aisar.app/v1/channels" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"channel_type_id": 1,
"provider_key": "whatsapp",
"name": "Sales WhatsApp",
"account_name": "+77000000002",
"start_pairing": true,
"pairing_mode": "qr"
}'Ответ
{
"data": {
"message": "Channel created.",
"channel": {
"id": 7,
"provider_key": "whatsapp",
"status": "connecting",
"setup_state": "pairing"
},
"pairing": {
"mode": "qr",
"request_id": "00000000-0000-0000-0000-000000000000"
}
}
}Опрос состояния подключения (QR)
Запрос
curl -X GET "https://api.aisar.app/v1/channels/7/connection" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": {
"channel_id": 7,
"setup_state": "pairing",
"connection": {
"status": "qr_required",
"mode": "qr",
"qr": {
"value": "2@EXAMPLE_QR_PAIRING_PAYLOAD_REDACTED",
"expires_at": "2026-02-09T18:00:20Z",
"expires_in_seconds": 18,
"is_expired": false,
"attempt": 1
},
"pairing_code": null,
"pairing_code_expires_at": null,
"pairing_state": "qr",
"last_error_message": null,
"retry_count": null,
"next_retry_at": null,
"status_message": null,
"updated_at": "2026-02-09T18:00:05Z"
},
"metrics": {}
}
}Передача кода авторизации (Telegram Personal)
Запрос
curl -X POST "https://api.aisar.app/v1/channels/8/auth-code" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "12345",
"phone_code_hash": "EXAMPLE_PHONE_CODE_HASH"
}'Ответ
{
"data": {
"message": "Auth code submitted.",
"channel_id": 8
}
}Логи канала
Запрос
curl -X GET "https://api.aisar.app/v1/channels/3/logs" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": [
{
"id": "1042",
"level": "info",
"code": "connection.ready",
"message": "Channel connected",
"context": {},
"created_at": "2026-02-09T18:00:00Z"
}
],
"meta": { "current_page": 1, "last_page": 1, "per_page": 200, "total": 1 }
}Логи канала — постраничный просмотр истории
Запрос
curl -X GET "https://api.aisar.app/v1/channels/3/logs?per_page=50&page=2" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": [
{
"id": "992",
"level": "error",
"code": "connection.lost",
"message": "Runtime session dropped",
"context": { "reason": "device_removed" },
"created_at": "2026-02-08T21:14:07Z"
}
],
"meta": { "current_page": 2, "last_page": 3, "per_page": 50, "total": 121 }
}Логи канала — сбой отправки сообщения
Запрос
curl -X GET "https://api.aisar.app/v1/channels/3/logs" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": [
{
"id": "1108",
"level": "error",
"code": "message.send.failed.rate_limit_hit",
"message": "Too many messages sent, please wait before sending more",
"context": {
"message_id": 1042,
"attempts": 3,
"error_code": "rate_limit_hit",
"response": "{\"status\":429,\"reason\":\"rate_limited\"}"
},
"created_at": "2026-08-26T10:02:11Z"
},
{
"id": "1107",
"level": "warning",
"code": "message.status.failed_suppressed",
"message": "Delivery failure receipt arrived after the message was already delivered",
"context": {
"message_id": 1039,
"reason": "Message expired (131053)"
},
"created_at": "2026-08-26T09:47:03Z"
}
],
"meta": { "current_page": 1, "last_page": 1, "per_page": 200, "total": 2 }
}Список архивных каналов
Запрос
# GET /channels никогда не возвращает архивные каналы, и параметра
# ?include_archived=1 не существует — если его передать, валидация молча
# его проигнорирует. Единственный способ увидеть архивный канал — этот список.
curl -X GET "https://api.aisar.app/v1/channels/archived" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": [
{
"id": 12,
"name": "WhatsApp — старый номер",
"account_name": "+77001112233",
"status": "disconnected",
"provider_key": "whatsapp",
"setup_state": "ready",
"archived_at": "2026-08-20T09:15:00.000000Z",
"messages_count": 4213,
"channel_type": { "id": 1, "key": "whatsapp", "name": "WhatsApp" }
}
]
}Окончательное удаление архивного канала
Запрос
curl -X DELETE "https://api.aisar.app/v1/channels/archived/12" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": {
"message": "Archived channel purged."
}
}Готовность WhatsApp-звонков (eligibility)
Запрос
curl -X GET "https://api.aisar.app/v1/channels/3/whatsapp-calling" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"eligibility": {
"calling": {
"sip_status": "NOT_SET",
"can_receive_call_sip": null,
"active": false
},
"prerequisites": {
"business_verified": false,
"payment_ok": true,
"name_approved": true,
"number_registered": true
},
"blocking_issues": [
{
"key": "business_verification",
"severity": "error",
"title": "Business is not verified with Meta",
"detail": "The business owner must complete Business Verification in Meta Business Manager.",
"fix_url": "https://business.facebook.com/settings/security"
}
],
"can_enable": false,
"name_status": "APPROVED",
"checked_at": "2026-02-09T18:00:00Z"
}
}
}Включить WhatsApp-звонки
Запрос
curl -X POST "https://api.aisar.app/v1/channels/3/whatsapp-calling/enable" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": {
"ok": true,
"error": null,
"error_code": null,
"outbound_trunk_provisioned": true,
"eligibility": {
"calling": {
"sip_status": "ENABLED",
"can_receive_call_sip": "AVAILABLE",
"active": true
},
"prerequisites": {
"business_verified": true,
"payment_ok": true,
"name_approved": true,
"number_registered": true
},
"blocking_issues": [],
"can_enable": true,
"name_status": "APPROVED",
"checked_at": "2026-02-09T18:05:00Z"
}
}
}Справочник типов каналов и провайдеров
Запрос
curl -X GET "https://api.aisar.app/v1/channel-types?published=true" \
-H "Authorization: Bearer YOUR_API_TOKEN"Ответ
{
"data": [
{
"id": 1,
"key": "whatsapp",
"name": "WhatsApp",
"description": "WhatsApp через QR-сопряжение",
"category": "messaging",
"order_id": 1,
"badge_label": "Popular",
"badge_variant": "primary",
"is_published": true,
"capabilities": { "send_text": true, "send_media": true },
"limits": {},
"provider_config": {
"mark_online_on_connect": {
"value": true,
"label": "Отмечать онлайн при подключении",
"description": "Показывать аккаунт онлайн, пока канал подключён"
}
}
}
]
}Шаблоны для чат-пикера (не-WABA канал)
Запрос
# Для WhatsApp/Telegram/Instagram и т.п. отдаются опубликованные шаблоны
# компании того же channel_type — без привязки к каналу (channel_id: null)
# и без модерации Meta (meta_status: null). Фронт вставляет body как готовый
# текст в поле ввода, а не отправляет через POST /messages/send-template.
curl -X GET "https://api.aisar.app/v1/channels/3/templates/sendable" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": [
{
"id": 58,
"company_id": 1,
"template_group_id": 58,
"channel_type_id": 1,
"channel_type": { "id": 1, "key": "whatsapp", "name": "WhatsApp" },
"channel": null,
"name": "greeting",
"slug": "greeting",
"status": "published",
"meta_status": null,
"meta_status_reason": null,
"last_synced_at": null,
"language": "ru",
"category": null,
"body": "Здравствуйте, {{first_name}}! Чем можем помочь?",
"parameters": [
{ "id": 101, "name": "first_name", "type": "text", "sample_value": "Иван", "position": 1 }
],
"buttons": [],
"uses_count": 12
}
]
}Заблокированные номера (WhatsApp Business/Cloud)
Запрос
curl -X GET "https://api.aisar.app/v1/channels/3/whatsapp/blocked-users?limit=50" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"numbers": ["+77001111111"],
"next_cursor": "CURSOR_1"
}
}Заблокированные номера (WhatsApp по QR)
Запрос
curl -X GET "https://api.aisar.app/v1/channels/7/whatsapp/blocked-users" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"numbers": ["77009998877@s.whatsapp.net"],
"next_cursor": null
}
}