PushOn API — Рассылки и боты по WhatsApp
PushOn • WhatsApp API Docs — dark IDE mode

Рассылки и боты по API WhatsApp от PushOn

Рассылки и боты по API WhatsApp от PushOn.

Аутентификация

Способ
API Key (заголовок)
Заголовок
x-api-key: <YOUR_API_KEY>
Формат
JSON-запросы: Content-Type: application/json

Базовый URL

Base https://api.pushon365.ru/api/v1/

1. Сессионные сообщения POST /send-session-message

Что это такое

Сессионные сообщения — обычные текстовые сообщения WhatsApp, разрешённые только в пределах 24-часового окна после последнего входящего сообщения пользователя (customer care window). Не требуют шаблонов и обычно не тарифицируются как шаблонные.

Тело запроса

{
  "toPhone": "+79991234567",
  "text": "this is a test message",
  "channelId": "aaaaaaaaaa"
}
  • toPhone — международный формат с +.
  • text — UTF-8, допускаются эмодзи и ссылки. Рекомендуется ≤ 1024 символов.
  • channelId — ID канала (ваш WABA-номер в PushOn).

⚠ Отправка возможна только внутри 24 часов с момента последнего входящего сообщения от клиента.

Особенности и ограничения

  • Поддерживается только текст. Для медиа/файлов используйте другие методы.
  • Канал должен быть активным и принадлежать вашему ключу.
  • Соблюдайте согласия (opt-in) и частоту рассылок.

Примеры запросов

curl -X POST "https://api.pushon365.ru/api/v1/send-session-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "text": "this is a test message",
    "channelId": "aaaaaaaaaa"
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-session-message" ^
  -H "x-api-key: {{YOUR_API_KEY}}" ^
  -H "Content-Type: application/json" ^
  --data-raw "{\"toPhone\":\"+79991234567\",\"text\":\"this is a test message\",\"channelId\":\"aaaaaaaaaa\"}"
curl -Method POST "https://api.pushon365.ru/api/v1/send-session-message" `
  -Headers @{ "x-api-key" = "{{YOUR_API_KEY}}"; "Content-Type" = "application/json" } `
  -Body (@{ toPhone = "+79991234567"; text = "this is a test message"; channelId = "aaaaaaaaaa" } | ConvertTo-Json)

Пример успешного ответа

{
  "status": "ok",
  "messageId": "wamid.HBgLMj...EQA",
  "toPhone": "+79991234567",
  "channelId": "aaaaaaaaaa",
  "text": "this is a test message",
  "queuedAt": "2025-09-11T11:52:10.987Z"
}

Типичная ошибка

{
  "status": "error",
  "code": "SESSION_WINDOW_CLOSED",
  "message": "Cannot send session message outside 24-hour customer care window."
}

2. Шаблонные сообщения POST /send-template-message

Что это такое

Шаблонные сообщения (HSM) — заранее утверждённые WhatsApp Business шаблоны для рассылок и инициирования диалога вне 24-часового окна. Имя и язык шаблона должны совпадать с одобренной версией.

Базовое тело запроса

{
  "toPhone": "+79991234567",
  "channelId": "aaaaaaaaaa",
  "templateName": "your_template_name",
  "templateLanguage": "ru"
}
  • toPhone — телефон получателя в международном формате.
  • channelId — идентификатор канала (WABA-номер).
  • templateName — точное имя шаблона из Business Manager.
  • templateLanguage — ISO-код языка (ru, en, es, de...).

Общие правила

  • Работает в любое время, независимо от 24ч окна.
  • Имя и язык должны полностью совпадать с одобренной локалью.
  • Структура components в запросе должна точно соответствовать структуре шаблона.

2.1 Текстовый шаблон без переменных

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "text_static",
    "templateLanguage": "ru"
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"text_static\",\"templateLanguage\":\"ru\"}"

2.2 Текстовый шаблон с переменными (body parameters)

Порядок параметров должен соответствовать порядку плейсхолдеров {{1}}, {{2}} и т.д.

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "order_update",
    "templateLanguage": "ru",
    "components": [
      {
        "type": "body",
        "parameters": [
          {"type":"text","text":"Алексей"},
          {"type":"text","text":"№1452"}
        ]
      }
    ]
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"order_update\",\"templateLanguage\":\"ru\",\"components\":[{\"type\":\"body\",\"parameters\":[{\"type\":\"text\",\"text\":\"Алексей\"},{\"type\":\"text\",\"text\":\"№1452\"}]}]}"

2.3 Кнопки быстрого ответа (button quick_reply)

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "feedback_request",
    "templateLanguage": "ru",
    "components": [
      {
        "type": "body",
        "parameters": [
          {"type":"text","text":"Алексей"},
          {"type":"text","text":"оформление заказа"}
        ]
      },
      {
        "type": "button",
        "sub_type": "quick_reply",
        "index": "0",
        "parameters": [{"type":"payload","payload":"FEEDBACK_GOOD"}]
      },
      {
        "type": "button",
        "sub_type": "quick_reply",
        "index": "1",
        "parameters": [{"type":"payload","payload":"FEEDBACK_BAD"}]
      }
    ]
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"feedback_request\",\"templateLanguage\":\"ru\",\"components\":[{\"type\":\"body\",\"parameters\":[{\"type\":\"text\",\"text\":\"Алексей\"},{\"type\":\"text\",\"text\":\"оформление заказа\"}]},{\"type\":\"button\",\"sub_type\":\"quick_reply\",\"index\":\"0\",\"parameters\":[{\"type\":\"payload\",\"payload\":\"FEEDBACK_GOOD\"}]},{\"type\":\"button\",\"sub_type\":\"quick_reply\",\"index\":\"1\",\"parameters\":[{\"type\":\"payload\",\"payload\":\"FEEDBACK_BAD\"}]}]}"

2.4 Медиа в заголовке (header image)

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "promo_with_image",
    "templateLanguage": "ru",
    "components": [
      {
        "type": "header",
        "parameters": [
          {"type":"image","image":{"link":"https://example.com/promo.jpg"}}
        ]
      }
    ]
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"promo_with_image\",\"templateLanguage\":\"ru\",\"components\":[{\"type\":\"header\",\"parameters\":[{\"type\":\"image\",\"image\":{\"link\":\"https://example.com/promo.jpg\"}}]}]}"

2.5 Карусель (carousel)

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "marketing_carousel",
    "templateLanguage": "ru",
    "components": [
      {
        "type": "carousel",
        "cards": [
          {
            "card_index": 0,
            "components": [
              {
                "type": "header",
                "parameters": [
                  {"type":"image","image":{"link":"https://example.com/img1.jpg"}}
                ]
              }
            ]
          },
          {
            "card_index": 1,
            "components": [
              {
                "type": "header",
                "parameters": [
                  {"type":"image","image":{"link":"https://example.com/img2.jpg"}}
                ]
              }
            ]
          }
        ]
      }
    ]
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"marketing_carousel\",\"templateLanguage\":\"ru\",\"components\":[{\"type\":\"carousel\",\"cards\":[{\"card_index\":0,\"components\":[{\"type\":\"header\",\"parameters\":[{\"type\":\"image\",\"image\":{\"link\":\"https://example.com/img1.jpg\"}}]}]},{\"card_index\":1,\"components\":[{\"type\":\"header\",\"parameters\":[{\"type\":\"image\",\"image\":{\"link\":\"https://example.com/img2.jpg\"}}]}]}]}]}"

2.6 Медиа-документ в заголовке (header document)

Если шаблон одобрен с заголовком «document», укажите ссылку на файл (PDF/DOC и т.п.).

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "invoice_doc_header",
    "templateLanguage": "ru",
    "components": [
      {
        "type": "header",
        "parameters": [
          {"type":"document","document":{"link":"https://example.com/invoice-1452.pdf","filename":"invoice-1452.pdf"}}
        ]
      }
    ]
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"invoice_doc_header\",\"templateLanguage\":\"ru\",\"components\":[{\"type\":\"header\",\"parameters\":[{\"type\":\"document\",\"document\":{\"link\":\"https://example.com/invoice-1452.pdf\",\"filename\":\"invoice-1452.pdf\"}}]}]}"

2.7 Встроенные call-to-action кнопки (url/phone)

Если шаблон одобрен с кнопками «Visit website»/«Call», параметры задаются провайдером; обычно components не требуются. Ниже пример с параметризованным URL (если шаблон это поддерживает).

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "promo_with_cta",
    "templateLanguage": "ru",
    "components": [
      {
        "type": "button",
        "sub_type": "url",
        "index": "0",
        "parameters": [{"type":"text","text":"1452"}]  // подставится в URL-шаблон
      }
    ]
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"promo_with_cta\",\"templateLanguage\":\"ru\",\"components\":[{\"type\":\"button\",\"sub_type\":\"url\",\"index\":\"0\",\"parameters\":[{\"type\":\"text\",\"text\":\"1452\"}]}]}"

2.8 Шаблон с location (геометка в body)

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

curl -X POST "https://api.pushon365.ru/api/v1/send-template-message" \
  -H "x-api-key: {{YOUR_API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "toPhone": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "templateName": "pickup_point_info",
    "templateLanguage": "ru",
    "components": [
      {
        "type": "body",
        "parameters": [
          {"type":"text","text":"55.7522, 37.6156"},  // координаты
          {"type":"text","text":"ул. Примерная, 1"}
        ]
      }
    ]
  }'
curl.exe -X POST "https://api.pushon365.ru/api/v1/send-template-message" -H "x-api-key: {{YOUR_API_KEY}}" -H "Content-Type: application/json" --data-raw "{\"toPhone\":\"+79991234567\",\"channelId\":\"aaaaaaaaaa\",\"templateName\":\"pickup_point_info\",\"templateLanguage\":\"ru\",\"components\":[{\"type\":\"body\",\"parameters\":[{\"type\":\"text\",\"text\":\"55.7522, 37.6156\"},{\"type\":\"text\",\"text\":\"ул. Примерная, 1\"}]}]}"

Подсказки

  • Перед отправкой проверьте, что шаблон одобрен и активен.
  • Параметры и медиа должны соответствовать типам, указанным в шаблоне (text/image/document).
  • Для Windows используйте curl.exe и экранирование \" в JSON.

Вебхук: входящие и статусы POST → ваш сервер

Назначение

PushOn отправляет HTTP POST на ваш Webhook URL при входящих сообщениях от пользователей, а также при изменении статусов исходящих сообщений (queued, sent, delivered, read, failed).

Как настроить

  • Укажите Webhook URL в панели PushOn (публичный HTTPS-адрес вашего сервера).
  • Метод: POST, заголовок: Content-Type: application/json.
  • ВАЖНО: ваш обработчик должен вернуть HTTP 200 OK и пустое тело как можно быстрее.
  • Всю тяжёлую обработку переносите в очередь/воркеры — чтобы не задерживать ответ.

Повторы и таймауты

При отсутствии 200 PushOn может выполнить повторные попытки доставки с нарастающей задержкой. Для устойчивости сразу отвечайте 200 с пустым телом, а бизнес-логику выполняйте асинхронно.

Payload: входящее сообщение

{
  "type": "message",
  "direction": "inbound",
  "timestamp": "2025-09-11T11:58:12.345Z",
  "message": {
    "id": "wamid.HBgLMj...",
    "from": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "payload_type": "text",
    "text": "Здравствуйте!"
  }
}

Поле payload_type может быть text, image, document и т.д.

Payload: статус исходящего

{
  "type": "status",
  "timestamp": "2025-09-11T11:59:03.001Z",
  "messageId": "wamid.HBgLMj...",
  "to": "+79991234567",
  "channelId": "aaaaaaaaaa",
  "status": "delivered",
  "error": null
}

Возможные status: queued, sent, delivered, read, failed. При ошибке заполняется error.

Быстрый тест вебхука

curl -X POST "https://your-server.example.com/webhook" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "status",
    "timestamp": "2025-09-11T11:59:03.001Z",
    "messageId": "wamid.test",
    "to": "+79991234567",
    "channelId": "aaaaaaaaaa",
    "status": "delivered"
  }'

Обработчик должен вернуть 200 OK и пустое тело (\n допустим). Любой другой ответ считается неуспешным и может привести к повтору.

Мини-серверы (возврат 200 и пустое тело)

import express from "express";
const app = express();
app.use(express.json());

app.post("/webhook", (req, res) => {
  // 1) Быстро логируем/кладём в очередь
  // console.log(req.body);
  // queue.push(req.body);

  // 2) Немедленно возвращаем 200 с ПУСТЫМ телом
  return res.status(200).end();
});

app.listen(3000, () => console.log("Webhook on :3000"));
from flask import Flask, request, Response
app = Flask(__name__)

@app.route("/webhook", methods=["POST"])
def webhook():
    # 1) Быстро логируем/кладём в очередь
    # print(request.json)
    # queue.put(request.json)

    # 2) Возвращаем 200 с ПУСТЫМ телом
    return Response(status=200)

if __name__ == "__main__":
    app.run(port=3000)

Безопасность

  • Используйте только HTTPS.
  • Рекомендуется верификация источника: секретный заголовок/подпись (если включено) или IP-allowlist.
  • Делайте обработку идемпотентной (учёт messageId, защита от повторов).

Коды ошибок и статусы

HTTP статусы

  • 200 OK — запрос принят, поставлен в очередь.
  • 400 Bad Request — ошибка валидации параметров/тела.
  • 401 Unauthorized — отсутствует/неверный API Key.
  • 403 Forbidden — доступ запрещён (канал/ключ не совпадает, лимит, блокировка).
  • 404 Not Found — ресурс/канал/шаблон не найден.
  • 429 Too Many Requests — превышен лимит запросов.
  • 5xx — ошибка на стороне сервера.

Коды приложения

  • SESSION_WINDOW_CLOSED — попытка отправки сессионного сообщения вне 24 часов.
  • BAD_REQUEST — неверные параметры (формат телефона, язык, имя шаблона).
  • UNAUTHORIZED — недействительный x-api-key.
  • FORBIDDEN — ключ не привязан к каналу или канал отключён.
  • NOT_FOUND — шаблон/канал не найдены.
  • RATE_LIMITED — превышены лимиты частоты запросов.

На Windows не используйте -k/--insecure для обхода SSL — обновите корневые сертификаты и проверьте цепочку.

Лучшие практики

  • Отправляйте только пользователям с согласиями (opt-in).
  • Проверяйте формат телефонов и локалей шаблонов до отправки.
  • Логируйте messageId для трекинга статусов.
  • Ретраи с экспоненциальной паузой для временных ошибок (429, 5xx).
  • Разделяйте тест/прод ключи и каналы.
  • Следите за 24-часовым окном сессии.