Для интеграторов

Приём статусов доставки

Нужно надёжно принимать события доставки в свою платформу: один URL для единичной и пакетной отправки, разный ключ массива в теле.

Контракт

  • Один URL вебхука на ключ; единичная отправка → массив messages, пакетная → xml_messages.
  • До 100 объектов в одном POST.
  • Порядок событий не гарантирован; ориентир — created_at.
  • При ошибке / таймауте / обрыве на вашем URL: повтор того же тела каждые 15 минут в течение суток. После суток попытки прекращаются. Отвечайте 200 быстро; приёмник — идемпотентный (дубль возможен). Порядок событий не гарантирован.
  • Первая доставка события до вашего URL может занять до 15 минут. Даунтайм дольше суток — догон через отчёты, где они есть.

Включение URL: поддержка smtp@samotpravil.ru (домен отправителя + URL) или настройки ключа в API/ЛК, где доступно.

Пример тела (пакет)

{
  "status": "ok",
  "xml_messages": [
    {
      "pack_id": "302251",
      "external_id": "some_id_1776755427",
      "email": "email1@domain.com",
      "status": "accepted",
      "created_at": 1615409261
    },
    {
      "pack_id": "302251",
      "external_id": "some_id_1776755427",
      "email": "email2@domain.com",
      "status": "failed",
      "reason": "user not found",
      "ttl_date": "2025-12-04",
      "created_at": 1615409261
    }
  ]
}

Статусы в модели клиента: accepted, delivered, failed, open, click, fbl, unsubscribe, duplicate.

Разбор в Node

import { parseWebhook } from "samotpravil";

app.post("/webhook", (req, res) => {
  const { source, events } = parseWebhook(req.body);
  // source: "messages" | "xml_messages"
  for (const e of events) {
    // ключ идемпотентности: messageId / xTrackId / packId+email+status+createdAt
  }
  res.status(200).json({ status: "ok" });
});

Скелет приёмника: каталог samotpravil-example/ в репозитории mailganer-mcp (#21208).

Бесплатного тестового ключа нет (#21204). Регистрация в личном кабинете, верификация домена отправителя (DNS), затем боевой ключ для api.samotpravil.ru.