Подключите WhatsApp
Отсканируйте QR-код в панели.
Отправляйте текст и изображения в WhatsApp. Сервис ставит сообщения в очередь, отправляет их по одному и сохраняет результат для каждого получателя.
http://185.113.132.60Отсканируйте QR-код в панели.
Передайте текст или изображение и номера.
Получайте прогресс через API или в панели.
Откройте страницу подключения WhatsApp, войдите с API-токеном и отсканируйте QR-код. Затем укажите токен в заголовке X-Api-Key каждого запроса с данными.
Замените YOUR_API_TOKEN своим токеном. Номера в примерах также замените на номера получателей. Переменные ниже используются во всех примерах cURL.
export MAILING_API_URL='http://185.113.132.60'
export MAILING_API_KEY='YOUR_API_TOKEN'
curl --fail-with-body "$MAILING_API_URL/status" \
-H "X-Api-Key: $MAILING_API_KEY"В ответе session.status: WORKING означает, что WhatsApp подключён. ready: true означает, что сервис готов отправлять сообщения. Если аккаунт ещё не подключён или очередь на паузе, созданные рассылки сохраняются и ждут.
https://broadcast.1game.kz изменится только базовый URL; токен и методы останутся прежними.В панели нажмите «Создать рассылку». Вставьте номера с новой строки, через запятую или точку с запятой, добавьте текст и при необходимости картинку. Переключатель «Сначала поздороваться и дождаться ответа» включает приветствие. Нажмите «Запустить рассылку» — откроются прогресс и получатели.
Если очередь на паузе или WhatsApp не подключён, задание сохранится и будет ждать. При обрыве связи повторите запрос кнопкой в форме: повтор не создаст дубликат рассылки.
POST /broadcasts принимает список recipients и текст. Один номер в списке — отправка одному человеку; несколько — рассылка.
curl --fail-with-body "$MAILING_API_URL/broadcasts" \
-H "X-Api-Key: $MAILING_API_KEY" \
-H 'Idempotency-Key: promo-text-2026-001' \
-H 'Content-Type: application/json' \
-d '{
"recipients": ["+77001234567", "+77001234568"],
"text": "Приглашаем на турнир в 1GAME!"
}'{
"id": "YOUR_BROADCAST_ID",
"created": true,
"status_url": "/broadcasts/YOUR_BROADCAST_ID"
}202 означает, что задание принято в очередь. Сохраните id или status_url, чтобы узнать результат. Получатели обрабатываются по порядку, с паузами.
В панели откройте «Подключение» и нажмите «Отключить WhatsApp». Очередь станет на паузу. Нажмите «Получить QR-код», отсканируйте его другим телефоном и затем нажмите «Продолжить очередь».
Через API используйте POST /session/disconnect, затем POST /session/start и GET /session/qr. После подключения нового номера отправку включает POST /queue/resume. При ответе 409 на отключение очередь уже на паузе: дождитесь текущей отправки и повторите запрос. При ошибке отключения повторите его до успешного завершения.
История сохраняется. Ожидания ответов и ещё не отправленные основные сообщения после приветствий старого аккаунта отменяются: эти разговоры не переносятся на новый номер. Остальные задания остаются в очереди.
Заголовок Idempotency-Key обязателен при создании рассылки. Придумайте уникальный ключ для каждого нового задания, например promo-text-2026-001. При сетевом сбое повторите тот же запрос с тем же ключом: сервис вернёт прежнюю рассылку с кодом 200 и created: false.
Если поменять текст, приветствие, изображение или список получателей, сохранив ключ, сервис вернёт 409. Новый ключ создаёт отдельную рассылку, даже если содержимое совпадает. Допустимы 1–128 символов: латинские буквы, цифры, - _ . :.
Добавьте поле greeting в POST /broadcasts. Сначала получателю отправится только приветствие. Основной text или картинка с подписью отправятся после нового входящего сообщения от этого человека.
curl --fail-with-body "$MAILING_API_URL/broadcasts" \
-H "X-Api-Key: $MAILING_API_KEY" \
-H 'Idempotency-Key: greeting-2026-001' \
-H 'Content-Type: application/json' \
-d '{
"recipients": ["+77001234567"],
"greeting": "Здравствуйте! Можно рассказать о нашем турнире?",
"text": "Турнир состоится в субботу. Вот подробности…"
}'Для картинки добавьте image_id из загрузки файла; она отправится только на втором этапе. Приветствие — непустая строка до 4096 символов. Чтобы отправлять сразу, не передавайте greeting или укажите null.
waiting_reply. Ожидание не блокирует других получателей и сохраняется после перезапуска.В messages[] поле phase показывает этап: greeting или main. Доступны greeting_sent_at, greeting_remote_id, reply_received_at и reply_remote_id. Счётчик sent увеличивается после основного сообщения; ожидающие ответа ещё не включены в обработанный прогресс.
Если результат приветствия оказался unknown, сначала проверьте чат. Подтверждение sent через /messages/{id}/resolve переведёт получателя в ожидание ответа.
Сначала загрузите файл, затем передайте его id в рассылку. Изображение хранится на сервере и может использоваться в нескольких заданиях.
POST /images принимает файл в теле запроса. Для JPG укажите image/jpeg, для PNG — image/png. Используйте --data-binary; здесь не нужны JSON, multipart или Base64. Команда ниже сохраняет идентификатор в IMAGE_ID и использует Python 3 для чтения ответа.
IMAGE_ID=$(curl --fail-with-body "$MAILING_API_URL/images" \
-H "X-Api-Key: $MAILING_API_KEY" \
-H 'Content-Type: image/jpeg' \
--data-binary @poster.jpg \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
echo "$IMAGE_ID"Первая загрузка возвращает 201, повторная загрузка того же файла — 200 и тот же id. В ответе также есть mimetype, size в байтах, width, height и url. Просмотр файла по url тоже требует токен.
curl --fail-with-body "$MAILING_API_URL/broadcasts" \
-H "X-Api-Key: $MAILING_API_KEY" \
-H 'Idempotency-Key: promo-image-2026-001' \
-H 'Content-Type: application/json' \
-d "{
\"recipients\": [\"+77001234567\", \"+77001234568\"],
\"text\": \"Афиша ближайшего турнира\",
\"image_id\": \"$IMAGE_ID\"
}"text становится подписью к картинке, до 1024 символов. Чтобы отправить только изображение, уберите поле text или передайте пустую строку. Каждый получатель получает одно сообщение с картинкой и подписью.
В очереди рассылок такие задания отмечены как «Изображение». Откройте детали, чтобы увидеть картинку, подпись и статусы получателей.
Запрашивайте состояние примерно раз в 4 секунды или следите за ним в панели. Подставьте id, полученный при создании задания.
BROADCAST_ID='YOUR_BROADCAST_ID'
curl --fail-with-body "$MAILING_API_URL/broadcasts/$BROADCAST_ID" \
-H "X-Api-Key: $MAILING_API_KEY"
# Все активные рассылки: до 20 за один запрос
curl --fail-with-body "$MAILING_API_URL/broadcasts?view=active&limit=20&offset=0" \
-H "X-Api-Key: $MAILING_API_KEY"В деталях доступны counts, total, processed, progress и массив messages. progress — процент обработанных получателей: ошибки и отмены тоже учитываются. Для числа отправленных сообщений смотрите counts.sent.
| Статус получателя | Что означает |
|---|---|
pending | Получатель ожидает своей очереди. |
preparing / sending | Подготовка или отправка. Следующий получатель ещё не обрабатывается. |
waiting_reply | Приветствие отправлено; основное сообщение ждёт ответа. |
sent | WhatsApp подтвердил отправку. Это не подтверждение прочтения. |
failed | Ошибка подготовки либо вручную подтверждённая неудачная отправка. |
unknown | Результат неизвестен. Вся очередь ждёт проверки соответствующего чата. |
cancelled | Отправка этому получателю отменена. |
# Пауза для всей очереди
curl --fail-with-body -X POST "$MAILING_API_URL/queue/pause" \
-H "X-Api-Key: $MAILING_API_KEY"
# Продолжить отправку
curl --fail-with-body -X POST "$MAILING_API_URL/queue/resume" \
-H "X-Api-Key: $MAILING_API_KEY"
# Отменить ещё не отправленные сообщения одной рассылки
curl --fail-with-body -X POST "$MAILING_API_URL/broadcasts/$BROADCAST_ID/cancel" \
-H "X-Api-Key: $MAILING_API_KEY"На паузе новые задания продолжают добавляться. Уже начатая отправка может завершиться после паузы или отмены. Отмена не удаляет историю и не отзывает отправленные сообщения.
При таймауте отправки сообщение может уже находиться в WhatsApp. Поэтому статус unknown блокирует всю очередь, а повторная отправка автоматически не выполняется. Откройте нужный чат, проверьте результат и подтвердите его для messages[].id.
MESSAGE_ID='YOUR_MESSAGE_ID'
# Если сообщение действительно отправлено
curl --fail-with-body -X POST "$MAILING_API_URL/messages/$MESSAGE_ID/resolve" \
-H "X-Api-Key: $MAILING_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"outcome":"sent"}'
# Если не отправлено — используйте {"outcome":"failed"}.
# Это фиксирует результат и не отправляет сообщение повторно.После разбора всех таких сообщений очередь продолжится с небольшой паузой. Если включена общая пауза, дополнительно вызовите /queue/resume.
Полные примеры загрузки изображения, создания рассылки и чтения её состояния. Задайте MAILING_API_KEY и, при необходимости, MAILING_API_URL в окружении. Сохраните картинку как poster.jpg рядом со скриптом.
import json
import os
from pathlib import Path
from urllib.request import Request, urlopen
base = os.getenv("MAILING_API_URL", "http://185.113.132.60").rstrip("/")
key = os.environ["MAILING_API_KEY"]
def api(method, path, body=None, *, mime="application/json", idem=None):
headers = {"X-Api-Key": key, "Content-Type": mime}
if idem:
headers["Idempotency-Key"] = idem
data = body if isinstance(body, bytes) else (
json.dumps(body).encode() if body is not None else None
)
request = Request(base + path, data=data, headers=headers, method=method)
with urlopen(request, timeout=90) as response:
return json.load(response)
image = api("POST", "/images", Path("poster.jpg").read_bytes(), mime="image/jpeg")
job = api("POST", "/broadcasts", {
"recipients": ["+77001234567"], # замените номер
"text": "Афиша турнира 1GAME",
"image_id": image["id"],
}, idem="python-image-2026-001")
print("Рассылка:", job["id"])
print(api("GET", job["status_url"]))
# Для обычного текста уберите image_id; загрузка файла тогда не нужна.import { readFile } from "node:fs/promises";
const base = (process.env.MAILING_API_URL || "http://185.113.132.60").replace(/\/$/, "");
const key = process.env.MAILING_API_KEY;
if (!key) throw new Error("Задайте MAILING_API_KEY");
async function api(path, options = {}) {
const response = await fetch(base + path, {
...options,
headers: { "X-Api-Key": key, ...options.headers },
signal: AbortSignal.timeout(90000),
});
if (!response.ok) throw new Error(await response.text());
return response.json();
}
const image = await api("/images", {
method: "POST",
headers: { "Content-Type": "image/jpeg" },
body: await readFile("poster.jpg"),
});
const job = await api("/broadcasts", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "node-image-2026-001",
},
body: JSON.stringify({
recipients: ["+77001234567"], // замените номер
text: "Афиша турнира 1GAME",
image_id: image.id,
}),
});
console.log("Рассылка:", job.id);
console.log(await api(job.status_url));
// Запуск: node send.mjsДля нового задания используйте новый Idempotency-Key. Для повторения прервавшегося запроса сохраняйте прежний ключ и содержимое.
Все методы с данными требуют X-Api-Key. Полная схема параметров и интерактивные запросы — в Swagger.
| Метод | Путь | Назначение |
|---|---|---|
| GET | /status | Подключение WhatsApp, готовность и счётчики очереди |
| POST | /session/disconnect | Отключить текущий WhatsApp и поставить очередь на паузу для смены номера |
| POST | /session/start | Подготовить QR-код для привязки аккаунта |
| GET | /session/qr | PNG с QR-кодом; проще отсканировать его в панели |
| POST | /session/qr/refresh | Сгенерировать новый QR для незавершённой привязки |
| POST | /images | Загрузить JPG/PNG, получить id |
| GET | /images/{id} | Скачать ранее загруженное изображение |
| POST | /broadcasts | Создать текстовую рассылку или рассылку с изображением |
| GET | /broadcasts | Список: limit 1–100, offset, view=all/active/attention |
| GET | /broadcasts/{id} | Счётчики, прогресс и результат по каждому номеру |
| POST | /broadcasts/{id}/cancel | Отменить ещё не отправленные сообщения |
| POST | /queue/pause | Приостановить всю очередь |
| POST | /queue/resume | Продолжить очередь |
| POST | /messages/{id}/resolve | Подтвердить результат unknown: sent или failed |
| GET | /healthz | Проверка сервиса без токена; не проверяет подключение WhatsApp |
+77001234567. Допускаются пробелы, скобки и дефисы. Повторы внутри списка объединяются.| HTTP | Что делать |
|---|---|
| 401 | Неверный токен или отсутствует X-Api-Key. |
| 404 | Рассылка или изображение не найдены. Сначала загрузите файл. |
| 409 | Ключ идемпотентности уже использован с другим содержимым; либо сообщение не в статусе unknown. |
| 413 | Файл больше 5 МиБ или JSON-запрос больше 128 КБ. |
| 415 | Для файла нужен Content-Type: image/jpeg или image/png. |
| 422 | Проверьте номера, обязательные поля, размер подписи и целостность картинки. |
| 429 | Очередь заполнена: до 10 000 ожидающих и активных сообщений. Повторите запрос позже с тем же ключом. |
| 503 | WhatsApp или QR-код пока недоступен. Проверьте подключение в панели. |
Описание ошибки находится в поле detail. Для ошибок полей оно может содержать список с указанием loc и msg. Ошибки размера запроса от прокси могут приходить обычным текстом.