WhatsApp API не работает: что проверить по шагам
Сообщения перестали уходить, вебхук молчит, клиент говорит, что ничего не получил. Обычно причина находится за пару минут: API почти всегда сообщает, что случилось, — в поле code ответа или в статусе номера.
Ниже — порядок проверки, коды ошибок, разбор частых ситуаций и скрипт мониторинга по расписанию.
Диагностика по шагам
Шаг 1. Посмотрите статус номеров
curl https://wapi.kz/api/v1/status -H "Authorization: Bearer $WAPI_KEY"У каждого номера смотрите status и wa_status: нужны active и WORKING. paused — кончился баланс, FAILED или STOPPED — номер отключился от WhatsApp, SCAN_QR_CODE — ждёт привязки, STARTING — запускается, подождите минуту.
Шаг 2. Проверьте баланс
В том же ответе — balance и days_left. Отдельно баланс отдаёт GET /balance: там ещё число активных номеров и номеров на паузе.
Шаг 3. Проверьте лимиты номера
curl "https://wapi.kz/api/v1/limits?from=1" -H "Authorization: Bearer $WAPI_KEY"Сравните used с limits: не исчерпан ли суточный лимит. cold_blocked_until покажет, не приостановлены ли первые сообщения новым людям, warmup: true — что номер ещё на прогреве.
Шаг 4. Найдите само сообщение
Если запрос на отправку прошёл, у сообщения есть id. GET /messages/{id} покажет его status и error.
Коды ошибок: причина и что делать
Ошибка всегда приходит как {"error": "…", "code": "…"}. В error — подсказка по-русски, её стоит писать в лог целиком.
| code | HTTP | Причина | Что делать |
|---|---|---|---|
unauthorized | 401 | Нет заголовка с ключом | Добавить Authorization: Bearer <API_KEY> |
invalid_key | 401 | Ключ неверный, перевыпущен или отозван | Взять актуальный ключ в кабинете |
forbidden_for_number_key | 403 | Ключ номера запрашивает баланс или данные аккаунта | Использовать ключ аккаунта |
invalid_json | 400 | Тело — не JSON-объект | Проверить Content-Type и сериализацию |
invalid_to, invalid_phone | 400 | Номер не из 10–15 цифр | Привести к виду 77011234567 |
empty_text, text_too_long | 400 | Текст пустой или длиннее 4096 символов | Исправить или разбить на части |
invalid_param | 400 | Неверный since, until, direction или format | Проверить формат параметра |
from_required | 400 | Номеров несколько, from не указан | Передавать from всегда |
invalid_from | 400 | В from не id и не телефон | Взять id из GET /numbers |
invalid_media, media_too_large, media_fetch_failed | 400 | Проблема с вложением | См. гайд про отправку файлов |
number_paused | 402 | Номер на паузе: закончился баланс | Пополнить — номер включится сам |
number_not_found | 404 | Номера нет в аккаунте или он недоступен этому ключу | Проверить from и ключ |
not_found | 404 | Сообщения нет в вашем аккаунте | Проверить id |
no_numbers | 409 | В аккаунт не добавлен номер | Добавить номер в кабинете |
not_connected | 409 | Номер не подключён к WhatsApp | Переподключить по QR-коду или коду |
rate_limited | 429 | Слишком часто: больше 1 сообщения или проверки в секунду | Очередь с паузами |
daily_limit, new_contacts_limit, checks_limit | 429 | Исчерпан лимит на сегодня | Ждать полуночи по Алматы |
cold_blocked, spam_detected | 429 | Отправка похожа на рассылку | Ждать 24 часа; отвечать клиентам можно |
send_failed, check_failed | 502 | WhatsApp не принял сообщение или проверку | Повторить позже, проверить номер |
capacity | 503 | Номер перезапускается | Повторить через пару минут |
На 502 и 503 делайте 2–3 повтора с паузой в минуты. Из ошибок 429 быстрый повтор помогает только при rate_limited. Ошибки вложений разобраны в гайде как отправить фото и файлы, полный справочник — в документации.
Номер отключился
Признаки: ответы not_connected (409), wa_status FAILED или STOPPED, вебхук session.status. Мы тоже пришлём уведомление. Частые причины:
- Телефон долго был без интернета: по правилам WhatsApp связанные устройства отключаются, если телефон не в сети около 14 дней.
- На телефоне удалили связанное устройство: WhatsApp → Настройки → Связанные устройства.
- WhatsApp переустановили или перенесли на другой телефон — связанные устройства в таком случае обычно приходится привязывать заново.
Что делать: переподключите номер в кабинете по QR-коду или коду по номеру — так же, как при первом подключении. Держать телефон всё время онлайн не нужно, но надолго без сети его оставлять нельзя.
Номер на паузе
Код number_paused (402) и status: "paused" значат, что на балансе не хватило денег на сутки: номер стоит 330 ₸ в сутки, списание — в 00:05 по Алматы. На паузе номер не отправляет и не принимает сообщения через сервис, но привязка WhatsApp сохраняется, а на телефоне всё работает как обычно.
После пополнения номер включится сам. Мы предупреждаем, когда баланса остаётся на 3 дня или меньше; следить автоматически поможет days_left из GET /balance. Как пополнить — на странице цен.
Ошибки 429: лимиты
rate_limited— слишком часто. С номера — не чаще 1 сообщения в секунду, первые сообщения новым людям — не чаще раза в 5 секунд. Нужна очередь, пример есть в гайде про отправку сообщений.daily_limit,new_contacts_limit— исчерпан лимит на сутки. Он зависит от индекса доверия, а в первые две недели номер на прогреве: дни 1–3 — 200 сообщений и 20 новых контактов в сутки, дни 4–7 — 400 и 40, дни 8–14 — 700 и 80.cold_blocked,spam_detected— отправка похожа на рассылку: один текст ушёл 25+ новым людям за час или за час появилось 40+ новых контактов. Первые сообщения новым людям закрыты на 24 часа, время окончания — вcold_blocked_until. Отвечать тем, кто пишет вам, можно.checks_limit— больше 200 проверок номеров за сутки. Сохраняйте результаты проверок у себя.
Не пытайтесь обойти защиту — перефразировать текст или переключаться на другой номер. Такой поток выглядит как рассылка и для WhatsApp, а это главная причина блокировок. Что делать вместо этого — в гайде как снизить риск блокировки.
Вебхук не приходит
- Адрес начинается с
https://и доступен из интернета: неlocalhost, не внутренний IP, не адрес за VPN. - Нет перенаправлений. Мы не следуем за 301 и 302, поэтому
httpвместоhttps, адрес безwwwили без слеша на конце, который сервер перенаправляет, — частые причины. - Токен в адресе совпадает с тем, что проверяет обработчик, — иначе ваш же сервер отвечает 403.
- Обработчик отвечает
200быстрее 10 секунд. Если ИИ думает дольше, отвечайте сразу, а работайте после. - Сертификат действителен, а защита от ботов не режет запросы с
User-Agent: wapi.kz-webhook. - Адрес задан у нужного номера, а сам номер подключён и не на паузе.
Свои отправки через API в вебхук не приходят — так задумано. Проверить адрес снаружи:
curl -i -X POST "https://crm.example.kz/whatsapp/webhook?token=СЕКРЕТ" \
-H "Content-Type: application/json" -H "User-Agent: wapi.kz-webhook" \
-d '{"event":"message","payload":{"from":"77011234567@c.us","body":"тест"},"wapi":{"number_id":1}}'В первой строке ответа должен быть код 200, а не 301, 302 или 403. Повторной отправки событий нет: пропущенное заберите через GET /messages?since=…. Подробнее о приёме — в гайде про вебхуки.
«Отправлено», но не доставлено
Ответ 200 значит, что сообщение ушло в WhatsApp. Дальше смотрите статус в GET /messages/{id} или в вебхуке message.ack:
- Долго
sent(одна галочка) — получатель не в сети, сменил номер или номера нет в WhatsApp. Перед первым сообщением проверяйте номер черезPOST /contacts/check(документация). failed— вerrorпричина:send_failed,capacity,number_paused— не ушло;not delivered— WhatsApp сообщил, что не доставил.delivered, но клиент «не видел» — сообщение на его телефоне; возможно, чат в архиве. «Прочитано» не приходит, если получатель отключил отчёты о прочтении.- Номер записан через 8:
87011234567— формально 11 цифр, но для WhatsApp это другой номер. Приводите к виду77011234567.
Мониторинг: скрипт для cron
Вебхук session.status сообщает об отключении сразу, но если упал ваш обработчик, вы об этом не узнаете. Подстрахуйтесь скриптом: раз в 10 минут он проверяет GET /status и пишет в Telegram, если номер отключился, встал на паузу или баланса осталось на 3 дня и меньше. Нужен ключ аккаунта: с ключом номера /status не отдаёт баланс.
#!/usr/bin/env python3
import os
import requests
API = "https://wapi.kz/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['WAPI_KEY']}"}
def alert(text):
token = os.environ["TG_BOT_TOKEN"]
requests.post(f"https://api.telegram.org/bot{token}/sendMessage",
json={"chat_id": os.environ["TG_CHAT_ID"], "text": text}, timeout=10)
def main():
try:
r = requests.get(f"{API}/status", headers=HEADERS, timeout=15)
s = r.json()
r.raise_for_status()
except (requests.RequestException, ValueError) as e:
alert(f"wapi.kz: не удалось получить статус — {e}")
return
problems = []
for n in s["numbers"]:
name = n.get("label") or n.get("phone") or f"#{n['id']}"
if n["status"] == "paused":
problems.append(f"{name}: на паузе, пополните баланс")
elif n["wa_status"] != "WORKING":
problems.append(f"{name}: {n['wa_status']}, переподключите в кабинете")
if n.get("cold_blocked_until"):
problems.append(f"{name}: первые сообщения новым людям закрыты до {n['cold_blocked_until']}")
days = s.get("days_left")
if days is not None and days <= 3:
problems.append(f"Баланса хватит на {days} дн. (остаток {s['balance']} ₸)")
if problems:
alert("wapi.kz:\n" + "\n".join(problems))
if __name__ == "__main__":
main()Запуск каждые 10 минут — ключи лежат в файле с переменными, а не в самой строке crontab:
*/10 * * * * set -a; . /etc/wapi-monitor.env; set +a; /usr/bin/python3 /opt/wapi-monitor.pyКуда писать
Если по шагам выше причина не нашлась, напишите в поддержку в Telegram — @wapi_kz_support_bot, отвечаем в рабочее время. Чтобы разобраться быстрее, пришлите email аккаунта, id номера, id сообщения или время запроса, а также code и error из ответа. API-ключ не присылайте никогда.
Если вы только выбираете сервис, начните с регистрации и подключения номера — это около 5 минут.
Частые вопросы
Почему API отвечает not_connected, хотя WhatsApp на телефоне работает?
Телефон работает сам по себе, а связанное устройство, через которое работает сервис, отключилось. Переподключите номер в кабинете по QR-коду или коду по номеру.
Как понять, что WhatsApp заблокировал номер?
Об этом сообщит само приложение WhatsApp на телефоне. Снять блокировку может только WhatsApp — через запрос на проверку в приложении; мы на это повлиять не можем.
Есть ли у вас SLA?
Отдельного SLA и процентов доступности мы не обещаем. Если от WhatsApp зависят заказы, настройте мониторинг (скрипт выше) и запасной канал уведомлений.
Почему в вебхук не приходят сообщения, отправленные через API?
Так задумано: о своей отправке вы знаете из ответа на запрос. В вебхук приходят её статусы — событием message.ack.
Подключите WhatsApp к своим системам
9 900 ₸ в месяц за номер, без платы за сообщения. Сервер в Казахстане, оплата Kaspi или счётом на ТОО/ИП. Подключение — около 5 минут.