Перейти к содержимому
WbizTool

API v2 (бета)

Сообщения

Отправляйте сообщение сразу или в заданное время на номер телефона, в группу WhatsApp, сохранённому контакту или на имя пользователя Telegram. Отправляйте одно и то же сообщение до 1000 получателям одним запросом, читайте историю, следите за статусом сообщения и отменяйте его, пока оно ожидает.

ОперацияEndpointОбласть доступа
Отправка сообщенияPOST /api/v2/messagesmessages:send
Отправка многим получателямPOST /api/v2/messages/batchmessages:send
Список сообщенийGET /api/v2/messagesmessages:read
Получение сообщенияGET /api/v2/messages/{id}messages:read
Отмена сообщенияDELETE /api/v2/messages/{id}messages:send

Ключи, ошибки, Idempotency-Key и лимиты работают так, как описано в обзоре API v2. Чтобы узнавать об отправке или ошибке без опроса, добавьте webhook endpoint.

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

POSThttps://wbiztool.com/api/v2/messages

Тело запроса: JSON (application/json)

Сообщение ставится в очередь, и ответ приходит раньше, чем оно уйдёт: HTTP 202 и Message в статусе queued (или scheduled, если send_at в будущем). Следите за ним через Получение сообщения или вебхук.

curl -X POST https://wbiztool.com/api/v2/messages \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-ready" \
  -d '{
    "from": 101,
    "to": { "phone": "+919876543210" },
    "text": "Hi Asha, your order #1042 is ready."
  }'

Ответ (202):

{
  "id": 9817263,
  "status": "queued",
  "from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
  "to": { "phone": "+919876543210", "contact_id": 991 },
  "text": "Hi Asha, your order #1042 is ready.",
  "media": null,
  "send_at": null,
  "expires_at": null,
  "created_at": "2026-10-18T10:15:02.311Z",
  "sent_at": null,
  "error": null
}

Тело запроса

toobjectобязательно

Кто получит сообщение: ровно одно из полей phone, group, contact_id или username. См. Получатели.

frominteger or nullОбязателен, если в рабочем пространстве не один подключённый номер

id номера, который отправляет сообщение, из Списка номеров. Если не указан, отправляет единственный подключённый номер: один подключённый номер WhatsApp используется, даже если подключён ещё и аккаунт Telegram, а аккаунт Telegram — только когда не подключено ни одного номера WhatsApp. Номер, вышедший из аккаунта, тоже принимается: его сообщения ждут, пока он снова подключится.

textstringОбязателен, если не отправляется медиафайл

Текст сообщения, до 3000 символов. С media это подпись, и её можно не указывать. Форматирование WhatsApp работает: *bold*, _italic_, ~strikethrough~. В JSON переносы строк пишутся как \n.

mediaobject or nullнеобязательно

Изображение или файл для отправки. См. Медиафайлы.

send_atstring or nullнеобязательно

Отправить в это время, а не сейчас: ISO 8601 со смещением, например 2026-10-20T09:30:00+05:30. Время должно быть в будущем. См. Планирование и срок действия.

expires_atstring or nullнеобязательно

Не отправлять после этого времени: вместо этого сообщение становится expired. ISO 8601 со смещением, в будущем и позже send_at.

Заголовки

Authorizationheaderобязательно

Bearer wbz_live_…, ключ с областью доступа messages:send.

Idempotency-Keyheaderнеобязательно

Любая уникальная строка, чтобы повтор никогда не отправил второе сообщение. См. Idempotency-Key.

Ошибки при отправке#

HTTPКодКогда
400validation_failedПоле отсутствует, имеет неверный тип или неизвестно; в to нет ни одного поля или их несколько; в media указаны оба поля url и media_id или ни одного; expires_at не позже send_at
400text_requiredНет ни text, ни media
400text_too_longtext длиннее 3000 символов
400invalid_datetimesend_at или expires_at не в формате ISO 8601 со смещением
402no_creditsУ рабочего пространства закончились сообщения по тарифу
403number_not_allowedКлюч ограничен другими номерами
403account_disabledАккаунт владельца рабочего пространства отключён
422invalid_phoneto.phone — не номер телефона в международном формате с +
422invalid_usernameto.username — не имя пользователя Telegram, не ссылка и не ID tg:
422username_needs_telegramto.username с номером WhatsApp в from
422contact_not_foundНет контакта с таким to.contact_id
422media_not_foundНет файла с таким media.media_id
422invalid_media_urlmedia.url — не публичная ссылка http(s)
422time_in_pastsend_at или expires_at уже прошло
422number_not_foundfrom — не номер этого рабочего пространства
422from_requiredНет from, а в рабочем пространстве нет подключённых номеров или их несколько
422message_rejectedСообщение не удалось поставить в очередь; причина — в message
429number_daily_cap_reachedНомер отправил 1000 сообщений за последние 24 часа

Отклонённая отправка ничего не оставляет: сообщение не сохраняется, и отменять нечего. Ошибки, которые возможны в любом запросе (ключи, области доступа, лимиты запросов, Idempotency-Key), описаны на странице ошибок.

Отправка многим получателям#

POSThttps://wbiztool.com/api/v2/messages/batch

Тело запроса: JSON (application/json)

Отправляет одно и то же сообщение до 1000 получателям. Тело запроса такое же, как в Отправке сообщения, только to — это список получателей.

  • Всё или ничего. Каждый получатель проверяется до того, как что-либо ставится в очередь, и весь список должен уложиться в оставшиеся сообщения тарифа и в запас номера-отправителя на ближайшие 24 часа. Если хотя бы один получатель указан неверно, в очередь ничего не ставится, а field называет его, например to[3].phone.
  • Один и тот же получатель, указанный дважды, получит одно сообщение.
  • Ответ — 202 с data: по одному Message на получателя, в порядке to.
curl -X POST https://wbiztool.com/api/v2/messages/batch \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: opening-hours-2026-10-20" \
  -d '{
    "from": 101,
    "to": [
      { "phone": "+919876543210" },
      { "phone": "+447700900123" },
      { "group": "Bakery staff" }
    ],
    "text": "We open at 10 tomorrow."
  }'

Ответ (202), по одному Message на получателя; второй и третий выглядят как первый, с to, равным {"phone": "+447700900123", …} и {"group": "Bakery staff", …}:

{
  "data": [
    {
      "id": 9817264,
      "status": "queued",
      "from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
      "to": { "phone": "+919876543210", "contact_id": 991 },
      "text": "We open at 10 tomorrow.",
      "media": null,
      "send_at": null,
      "expires_at": null,
      "created_at": "2026-10-19T16:02:40.118Z",
      "sent_at": null,
      "error": null
    }
  ]
}

Ошибки при отправке пакета#

Те же, что при отправке одного сообщения, с позицией получателя в field (to[0].phone), а также:

HTTPКодКогда
400too_many_recipientsВ to больше 1000 элементов
400validation_failedto пуст или не является списком
402no_creditsСписок не умещается в оставшиеся сообщения: requested и remaining показывают, насколько
429number_daily_cap_reachedСписок не умещается в запас номера на ближайшие 24 часа: requested и room показывают сколько

Список сообщений#

GEThttps://wbiztool.com/api/v2/messages

Сообщения рабочего пространства за последние 90 дней, сначала самые новые, страницами. Сюда входят сообщения, отправленные из панели, кампаниями, напоминаниями, интеграциями и через API v1, а не только через API v2. Ключ, ограниченный некоторыми номерами, видит только их сообщения.

Параметры запроса

numberintegerнеобязательно

Только сообщения с номера с этим id.

statusstringнеобязательно

Только сообщения с этим статусом: queued, scheduled, sent, delivered, read, failed, cancelled или expired.

sincestringнеобязательно

Только сообщения, созданные в это время или позже (ISO 8601 со смещением).

untilstringнеобязательно

Только сообщения, созданные раньше этого времени (ISO 8601 со смещением).

limitintegerнеобязательно

Сообщений на странице, от 1 до 100 (по умолчанию 25).

cursorstringнеобязательно

next_cursor предыдущей страницы, с теми же фильтрами.

Фильтры можно сочетать. В строке запроса пишите + смещения как %2B (обычный + приходит как пробел, который тоже читается как +) или используйте Z.

curl -G https://wbiztool.com/api/v2/messages \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  --data-urlencode "status=failed" \
  --data-urlencode "since=2026-10-01T00:00:00+05:30" \
  --data-urlencode "limit=100"

Ответ — {"data": [Message, …], "next_cursor": "…" or null}.

Ошибки при получении списка#

HTTPКодКогда
400validation_failednumber — не ID номера, status — не один из статусов, или limit не от 1 до 100
400invalid_datetimesince или until не в формате ISO 8601 со смещением
400invalid_cursorКурсор повреждён или создан с другими фильтрами

Получение сообщения#

GEThttps://wbiztool.com/api/v2/messages/{id}

Одно сообщение и его текущий статус.

curl https://wbiztool.com/api/v2/messages/9817263 \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"

Ответ (200), доставленное сообщение:

{
  "id": 9817263,
  "status": "delivered",
  "from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
  "to": { "phone": "+919876543210", "contact_id": 991 },
  "text": "Hi Asha, your order #1042 is ready.",
  "media": null,
  "send_at": null,
  "expires_at": null,
  "created_at": "2026-10-18T10:15:02.311Z",
  "sent_at": "2026-10-18T10:15:09.870Z",
  "error": null
}

Сообщение, которого не существует, которое принадлежит другому рабочему пространству или (для ключа, ограниченного некоторыми номерами) было отправлено с другого номера, возвращает 404 message_not_found.

Отмена сообщения#

DELETEhttps://wbiztool.com/api/v2/messages/{id}

Отменяет сообщение, которое ещё ожидает (queued или scheduled), кто бы его ни создал. Ответ — 200 с Message, теперь в статусе cancelled. Webhook endpoint получает message.cancelled.

Ушедшее сообщение отозвать нельзя. Сообщение, которое номер-отправитель забирает именно в этот момент, ещё может уйти, поэтому, если это важно, проверьте его статус после отмены.

curl -X DELETE https://wbiztool.com/api/v2/messages/9817263 \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"

Ошибки при отмене#

HTTPКодКогда
404message_not_foundДля этого ключа такого сообщения нет
409not_cancellableОно больше не ожидает; status в ошибке показывает, в каком оно состоянии сейчас, например sent

Объект Message#

Все операции на этой странице возвращают объекты Message, а события вебхуков передают такой объект в data.message.

ПолеТипОписание
idintegerID сообщения. По нему сообщение можно получить или отменить.
statusstringГде оно сейчас. См. Статусы.
fromobjectНомер-отправитель: id, phone (цифры с кодом страны, без +) и platform (whatsapp или telegram).
toobjectПолучатель: phone (с +), group или username, а также contact_id — сохранённый контакт, которому ушло сообщение. Номер телефона или группа, которым вы пишете впервые, сохраняются как контакт. (contact_id равен null, только если это тестовое сообщение на несохранённый номер.)
textstringТекст или подпись; "", если их нет.
mediaobject or nulltype (image или file), url и file_name (null для изображений). url может быть ссылкой, которая работает ограниченное время; не сохраняйте её.
send_atstring or nullВремя, на которое запланирована отправка, или null для «сейчас».
expires_atstring or nullВремя, после которого сообщение не отправляется, или null.
created_atstringКогда оно создано.
sent_atstring or nullКогда оно ушло, после отправки (sent, delivered или read).
errorobject or nullДля сообщения failed или expired message объясняет причину, например File exceeds WhatsApp size limit (16MB max). Иначе null.

Статусы#

СтатусЗначение
queuedОжидает отправки.
scheduledОжидает своего send_at.
sentОтправлено с вашего номера (одна галочка в WhatsApp).
deliveredДоставлено на телефон получателя (две галочки).
readПрочитано получателем (синие галочки).
failedОтправить не удалось; причина — в error.message.
cancelledОтменено до отправки: через Отмену сообщения, в панели или потому, что его номер или кампания были удалены.
expiredНе отправлено до своего expires_at.

queued и scheduled можно отменить. sent ещё может стать delivered, а затем read. failed, cancelled, expired и read — окончательные. Вебхуки сообщают о sent, failed, cancelled и expired; чтобы увидеть delivered и read, получите сообщение.

Получатели#

to принимает ровно одно из этих полей:

ПолеПримерКто получит
phone{"phone": "+919876543210"}Номер телефона в международном формате с + (E.164). Пробелы и дефисы допустимы.
group{"group": "Bakery staff"}Группа WhatsApp, в которой состоит номер-отправитель, по её точному названию (до 200 символов).
contact_id{"contact_id": 991}Контакт, сохранённый в рабочем пространстве, по его ID (например, contact_id более раннего сообщения). Сообщение уходит на номер или в группу этого контакта.
username{"username": "@asha_bakes"}Пользователь Telegram: @name, ссылка t.me/name или tg: и ID пользователя. Только с аккаунта Telegram, поэтому укажите его в from (или подключите ровно один).

Для отправки в группы и в Telegram номер-отправитель должен состоять в этой группе или иметь возможность написать этому пользователю; проблемы с этим проявляются как сообщение failed, а не как ошибка при отправке запроса.

Медиафайлы#

media отправляет изображение или файл, а text становится подписью. Укажите ровно одно из url или media_id:

media.urlstringЛибо url, либо media_id

Публичная ссылка http или https на файл, до 1000 символов. Ссылки на частные или локальные адреса отклоняются с invalid_media_url.

media.media_idintegerЛибо url, либо media_id

Файл из Медиакаталога рабочего пространства, полученный через Загрузку файла. Загрузите файл один раз и отправляйте его сколько угодно.

media.typestringнеобязательно

image или file. Если не указан, ссылка, оканчивающаяся на .jpg, .jpeg, .png, .gif или .webp, отправляется как изображение, а всё остальное — как файл; для media_id используется тип, с которым файл был загружен.

media.file_namestringнеобязательно

Для file: имя, которое видит получатель, например invoice-1042.pdf (до 100 символов). Если не указано, имя берётся из ссылки или загруженного файла. От расширения зависит, как будет отправлен файл, поэтому обязательно укажите его. Для изображений игнорируется.

{
  "to": { "phone": "+919876543210" },
  "text": "Your invoice for order #1042",
  "media": { "url": "https://example.com/invoices/1042.pdf", "type": "file", "file_name": "invoice-1042.pdf" }
}

Файл скачивается в момент отправки сообщения, а не при вызове API, поэтому нерабочая ссылка или слишком большой файл проявляются как сообщение failed с причиной в error.message. Ограничения на размер и тип такие же, как в v1: см. Отправка изображений и файлов.

Планирование и срок действия#

  • send_at планирует сообщение. До этого времени оно остаётся scheduled, и его можно отменить, пока оно не ушло. Указывайте время со смещением: 2026-10-20T09:30:00+05:30 означает 09:30 по времени Индии. Для повторяющихся сообщений используйте напоминания.
  • expires_at — крайний срок: если сообщение к этому времени не ушло (например, номер вышел из аккаунта), оно становится expired и не уходит с опозданием. Используйте это для одноразовых кодов, времени доставки и предложений. Фоновая задача помечает сообщение как истёкшее не раньше чем через 30 секунд после срока, поэтому не полагайтесь на сроки меньше минуты.
  • Оба времени должны быть в будущем, а expires_at — позже send_at.

Связанные материалы#