Сервис отправки уведомлений

Один вызов — и уведомление точно не потеряется

У вас несколько сервисов, и в каждом своём куске кода отправляет уведомления? Senderly забирает это на себя: сервис делает один HTTP-запрос, получает подтверждение, что сообщение сохранено, — и может заниматься своей работой. Доставку, повторы и лимиты мессенджеров берём на себя.

Как это работает

Приём и доставка разделены. Клиенту нужно дождаться только приёма.

  1. POST /v1/messages. Сервис присылает текст, канал отправки и получателя вместе с API-токеном Senderly и ключом идемпотентности.
  2. Сохранение. Сообщение попадает в базу в той же транзакции, что и ответ. Здесь оно уже не потеряется.
  3. 202 Accepted. Вы получаете идентификатор сообщения и ссылку на его статус.
  4. Доставка. Асинхронный обработчик доставляет сообщение через канал отправки, соблюдая лимиты и повторяя при сбоях.

Что гарантирует сервис

Формулировка важна: 202 Accepted означает «мы приняли сообщение и сохранили его для обработки». Это не обещание, что уведомление уже у получателя — статус доставки смотрите по идентификатору сообщения.

Не теряется

Приём сообщения — транзакционная запись в базу. Если Senderly ответил 2xx, сообщение переживёт рестарт, падение процесса и недоступность мессенджера.

Без дублей

Заголовок Idempotency-Key защищает от повторной отправки: два запроса с одним ключом — одно сообщение.

Повторы с умом

Временные сбои повторяются с экспоненциальной задержкой, а ошибки вида «цель не найдена» не долбятся до бесконечности — они заканчиваются понятным терминальным статусом.

Изоляция по тенантам

У каждого тенанта свой бот и свои лимиты. Один шумный сервис не может затопить очереди остальных.

Статус по идентификатору

Состояние каждого сообщения и журнал попыток доступны через API и в личном кабинете.

Понятные лимиты

Limit по частоте запросов на токен и соблюдение лимитов Telegram. За превышение вашего лимита отвечаете вы, за уважение лимитов платформы — мы.

API

Отправка — один запрос. Ответ содержит Location с адресом статуса сообщения.

Отправка

curl -X POST https://api.senderly.ru/v1/messages \
  -H "Authorization: Bearer $SENDERLY_TOKEN" \
  -H "Idempotency-Key: order-7712-failed" \
  -H "Content-Type: application/json" \
  -d '{
        "channel": "ops-telegram",
        "target": "tg:-1001234567890",
        "text": "Платёжный воркер не отвечает 5 минут"
      }'

Ответ

HTTP/1.1 202 Accepted
Location: /v1/messages/0f1c9a2e-6d0b-7a31-9c4e-1b2f3d4e5a60

Статус сообщения

curl https://api.senderly.ru/v1/messages/0f1c9a2e-6d0b-7a31-9c4e-1b2f3d4e5a60 \
  -H "Authorization: Bearer $SENDERLY_TOKEN"

{
  "id": "0f1c9a2e-6d0b-7a31-9c4e-1b2f3d4e5a60",
  "status": "DELIVERED_TO_PROVIDER",
  "attempts": 1,
  "providerMessageId": "4211",
  "createdAt": "2026-11-05T09:14:02Z"
}

Статусы

СтатусЗначение
PENDINGсообщение сохранено, ждёт обработки
SENDINGворкер доставляет сообщение через канал отправки прямо сейчас
RETRYне получилось, будет повтор по backoff
DELIVERED_TO_PROVIDERпровайдер принял сообщение
FAILEDфатальная ошибка: цель недоступна или запрос некорректен
DEADисчерпаны попытки — нужно вмешательство

Каналы отправки

Канал отправки — это сохранённое подключение к провайдеру. Создавайте несколько каналов отправки, каждый со своим Telegram-ботом. Токен бота настраивается в Senderly; сервис передаёт сообщение и получателя.

Доступно

Telegram

Личные чаты и группы. Свой бот на тенанта, очередь с повтором поretry_after, чтобы не упереться в лимиты платформы.

В разработке

Email

Отправка через Notisend по HTTP API. Статусы доставки от провайдера будут уточнять состояние сообщения после принятия.

Дорожная карта

Другие каналы отправки

Модель данных спроектирована под несколько каналов отправки: новый транспорт добавляется реализацией обработчика, а не переписыванием API.

Частые вопросы

202 Accepted — значит, уведомление доставлено?

Нет. Это значит, что сообщение принято и надёжно сохранено. Доставка — асинхронный этап: следите за статусом по Location или получайте сообщения о финальном статусе.

Что если сервис не получил ответ?

Повторите запрос с тем же Idempotency-Key. Дубля не будет: ключ уникален в пределах тенанта.

Могут ли быть дубли у получателя?

Доставка устроена как «не реже одного раза»: если обработчик упал после отправки, но до записи статуса, сообщение уйдёт повторно. Полностью убрать это нельзя — мессенджер не принимает ключ идемпотентности.

Куда обращаться по доступу?

Напишите на hello@example.com.