Перейти к содержимому
AISARAISAR
REST API

Рассылки

Массовые рассылки сообщений сегменту контактов по одному или нескольким каналам (WhatsApp/Telegram/Instagram). Группа покрывает весь жизненный цикл: создание черновика, публикацию и запуск(и), A/B-варианты, контроль скорости и окно отправки, отписки, отслеживание кликов, управление запусками и повторную отправку неудавшимся получателям. Все эндпоинты требуют активную подписку и фичу плана broadcasts.

Жизненный цикл и расписание

Рассылка может быть черновиком (is_draft: true) и позднее запускаться одним из способов:

  • немедленно — schedule.mode = now;
  • по расписанию — later + scheduledAt;
  • по recurring-правилу — recurrence.

Жизненный цикл: draft → publish → запуск(и) (run); каждый запуск отслеживает свой прогресс отдельно (sent/delivered/read/failed/skipped).

Статус рассылки (status): draftscheduled/activecompleted либо failed (cancelled при отмене). Для одноразовой рассылки (без recurring-расписания) статус failed выставляется, когда её запуск завершается с провалом или пропуском всех получателей — это же значение принимается фильтром statuses[] в GET /broadcasts. Повторная отправка неудавшимся получателям (retry-failed) возвращает такую рассылку обратно в scheduled.

A/B-варианты

Контент канала поддерживает A/B-варианты (2–3 на канал, content.channels[].variants): вариант назначается получателю детерминированно, разбивка статистики — в stats.byVariant.

Скорость отправки и окно

Скорость отправки регулируется через schedule.rateControl (messagesPerMinute, jitter, dailyLimit, skipContactedWithinHours) и окно sendWindow (режим smart шлёт каждому получателю в его исторически активный час).

Отписки (opt-out)

Контакты с opted_out_at всегда исключаются из аудитории; входящее сообщение-стоп-слово (stop/стоп/unsubscribe/отписаться) автоматически ставит opt-out.

Отслеживание кликов

При content.settings.trackClicks = true ссылки переписываются на трекинговые /r/{code} (публичный редирект без аутентификации учитывает клик и делает 302 на оригинал).

Управление запусками

Запуски можно ставить на паузу/возобновлять/отменять (pending-получатели → skipped), а неудавшихся получателей — отправлять повторно (retry-failed).

Валидация шаблона перед отправкой

Для записей content.channels[] с type = "template" перед стартом отправки проверяется, что на канале есть approved-версия выбранного шаблона. Проверка выполняется на трёх точках входа: POST /broadcasts (когда schedule.mode = "now"), POST /{broadcast}/run и POST /{broadcast}/publish. Если approved-шаблона нет, запрос отклоняется с 422, и errors.content[0] содержит сообщение вида Channel "..." has no approved template "..." (language ru). Approve this template for the channel or pick a channel where it is approved.

AI-помощник по тексту

AI-помощник текста (POST /broadcasts/assist, generate/improve) делит лимит 60/час с прочим AI-ассистом.

Эндпоинты

МетодПуть
GET/v1/broadcasts/meta

Метаданные конструктора рассылки (сегменты, переменные, шаблоны)

GET/v1/broadcasts

Список рассылок (пагинация, фильтр по статусу)

GET/v1/broadcasts/{broadcast}

Получение рассылки

POST/v1/broadcasts

Создание рассылки (поддерживает is_draft)

PATCH/v1/broadcasts/{broadcast}

Обновление рассылки

POST/v1/broadcasts/{broadcast}

Обновление рассылки (POST-алиас PATCH)

DELETE/v1/broadcasts/{broadcast}

Удаление рассылки

POST/v1/broadcasts/estimate

Оценка размера аудитории рассылки

POST/v1/broadcasts/{broadcast}/duplicate

Дублирование рассылки

POST/v1/broadcasts/{broadcast}/publish

Публикация черновика (запуск/постановка на расписание)

POST/v1/broadcasts/{broadcast}/cancel

Отмена разовой рассылки

POST/v1/broadcasts/{broadcast}/run

Ручной запуск рассылки

GET/v1/broadcasts/{broadcast}/messages

Получатели запуска (пагинация, фильтр по статусу)

GET/v1/broadcasts/{broadcast}/runs

Список запусков рассылки

GET/v1/broadcasts/{broadcast}/runs/{run}

Получение конкретного запуска

POST/v1/broadcasts/{broadcast}/pause-recurring

Пауза recurring-расписания

POST/v1/broadcasts/{broadcast}/resume-recurring

Возобновление recurring-расписания

POST/v1/broadcasts/test

Отправка тестового сообщения конкретному получателю

POST/v1/broadcasts/assist

AI-помощник по тексту рассылки (generate/improve)

POST/v1/broadcasts/{broadcast}/runs/{run}/pause

Пауза запуска

POST/v1/broadcasts/{broadcast}/runs/{run}/resume

Возобновление запуска

POST/v1/broadcasts/{broadcast}/runs/{run}/cancel

Отмена запуска (pending-получатели → skipped)

POST/v1/broadcasts/{broadcast}/runs/{run}/retry-failed

Повторная отправка только failed-получателям

Примеры

Создание и немедленный запуск рассылки

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "February promo",
    "is_draft": false,
    "audience": { "segmentId": "12" },
    "channels": { "mode": "specific", "channelIds": [7] },
    "content": {
      "channels": [
        { "type": "text", "channelId": 7, "accountType": "whatsapp", "text": "Hi {{first_name}}, 20% off this week!" }
      ]
    },
    "schedule": { "mode": "now" }
  }'

Ответ

json
{
  "data": {
    "id": 88,
    "company_id": 1,
    "name": "February promo",
    "status": "active",
    "audience": {
      "conditions": [],
      "group_logic": "and"
    },
    "channels": [{ "id": 7, "mode": "specific" }],
    "content": [],
    "schedule": { "mode": "now", "scheduledAt": null },
    "recurring_schedule": null,
    "runs": [
      { "id": 201, "broadcast_id": 88, "status": "processing", "total": 340, "sent": 0, "failed": 0, "delivered": 0, "read": 0, "started_at": "2026-03-15T10:00:00.000000Z", "completed_at": null }
    ],
    "created_at": "2026-03-15T10:00:00.000000Z",
    "updated_at": "2026-03-15T10:00:00.000000Z"
  }
}

Оценка аудитории рассылки

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts/estimate \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment_id": 12,
    "channel_ids": [7]
  }'

Ответ

json
{
  "data": {
    "total_contacts": 340,
    "reachable_contacts": 312,
    "excluded_contacts": 28,
    "estimated_duration_seconds": 312,
    "estimated_completion": "2026-03-15T10:05:12.000Z"
  }
}

Черновик с A/B-вариантами, контролем скорости и окном отправки

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spring reactivation",
    "is_draft": true,
    "audience": { "segmentId": "12" },
    "channels": { "mode": "specific", "channelIds": [7] },
    "content": {
      "channels": [
        {
          "type": "text",
          "channelId": 7,
          "accountType": "whatsapp",
          "text": "Hi {{first_name}}, we miss you!",
          "variants": [
            { "key": "A", "text": "Hi {{first_name}}, we miss you — here is 15% off." },
            { "key": "B", "text": "{{first_name}}, come back for 15% off this week." }
          ]
        }
      ],
      "settings": {
        "trackClicks": true,
        "includeOptOut": true,
        "optOutText": "Reply STOP to unsubscribe"
      }
    },
    "schedule": {
      "mode": "later",
      "scheduledAt": "2026-04-01T09:00:00Z",
      "rateControl": {
        "enabled": true,
        "messagesPerMinute": 30,
        "jitterMinSeconds": 2,
        "jitterMaxSeconds": 8,
        "dailyLimit": 5000,
        "skipContactedWithinHours": 48
      },
      "sendWindow": {
        "enabled": true,
        "mode": "smart",
        "startTime": "09:00",
        "endTime": "20:00",
        "timezone": "recipient"
      }
    }
  }'

Ответ

json
{
  "data": {
    "id": 89,
    "company_id": 1,
    "name": "Spring reactivation",
    "status": "draft",
    "audience": { "conditions": [], "group_logic": "and" },
    "channels": [{ "id": 7, "mode": "specific" }],
    "content": [],
    "schedule": { "mode": "later", "scheduledAt": "2026-04-01T09:00:00.000000Z" },
    "recurring_schedule": null,
    "runs": [],
    "created_at": "2026-03-20T12:00:00.000000Z",
    "updated_at": "2026-03-20T12:00:00.000000Z"
  }
}

Публикация черновика (draft → scheduled)

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts/89/publish \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "id": 89,
    "status": "scheduled",
    "schedule": { "mode": "later", "scheduledAt": "2026-04-01T09:00:00.000000Z" },
    "runs": [],
    "updated_at": "2026-03-20T12:05:00.000000Z"
  }
}

Ошибка: на канале нет approved-шаблона

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts/90/run \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "message": "Channel \"WhatsApp Main\" has no approved template \"spring_promo\" (language ru). Approve this template for the channel or pick a channel where it is approved.",
    "errors": {
      "content": [
        "Channel \"WhatsApp Main\" has no approved template \"spring_promo\" (language ru). Approve this template for the channel or pick a channel where it is approved."
      ]
    }
  }
}

Тестовое сообщение перед запуском

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts/test \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": 7,
    "recipient": "+77000000001",
    "content": { "type": "text", "text": "Test: 15% off this week!" }
  }'

Ответ

json
{
  "data": {
    "message": "Test message queued.",
    "message_id": "b1f2c3d4-EXAMPLE"
  }
}

AI-помощник по тексту рассылки

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts/assist \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "improve",
    "text": "hey buy our stuff now big sale",
    "locale": "en"
  }'

Ответ

json
{
  "data": {
    "text": "Big news, {{first_name}} — our best sale of the season is live. Save 20% this week only.",
    "action": "improve",
    "tokens_used": 128
  }
}

Получатели запуска (фильтр по статусу failed)

Запрос

bash
curl "https://api.aisar.app/v1/broadcasts/89/messages?status=failed&per_page=2" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": [
    {
      "id": 7001,
      "contact_id": 123,
      "identifier": "+7700000XXXX",
      "status": "failed",
      "error_message": "recipient_not_on_whatsapp",
      "attempts": 2,
      "variant_key": "A",
      "delivered_at": null,
      "read_at": null,
      "replied_at": null,
      "clicked_at": null,
      "contact": { "id": 123, "display_name": "Aylin Weber", "first_name": "Aylin", "last_name": "Weber" },
      "channel": { "id": 7, "name": "WhatsApp Main" }
    },
    {
      "id": 7002,
      "contact_id": 124,
      "identifier": "+7700000YYYY",
      "status": "failed",
      "error_message": "message_send_timeout",
      "attempts": 3,
      "variant_key": "B",
      "delivered_at": null,
      "read_at": null,
      "replied_at": null,
      "clicked_at": null,
      "contact": { "id": 124, "display_name": "Marco Ricci", "first_name": "Marco", "last_name": "Ricci" },
      "channel": { "id": 7, "name": "WhatsApp Main" }
    }
  ],
  "meta": { "current_page": 1, "last_page": 1, "per_page": 2, "total": 2 }
}

Повторная отправка неудавшимся получателям

Запрос

bash
curl -X POST https://api.aisar.app/v1/broadcasts/89/runs/201/retry-failed \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "id": 201,
    "broadcast_id": 89,
    "status": "processing",
    "total": 340,
    "sent": 300,
    "failed": 0,
    "delivered": 280,
    "read": 190,
    "started_at": "2026-04-01T09:00:00.000000Z",
    "completed_at": null
  }
}