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

Шаблоны сообщений

Шаблоны сообщений (message templates) используются для отправки structured-сообщений с переменными вне 24-часового окна свободной переписки — в первую очередь WhatsApp Business HSM-шаблоны, проходящие модерацию Meta. API покрывает CRUD шаблона, публикацию на модерацию (submit), архивирование и синхронизацию статуса одобрения с Meta.

Отправка и переменные

Готовый одобренный шаблон отправляется контакту через POST /messages/send-template (см. группу Сообщения). В теле переменные задаются именованно{{first_name}}, а не {{1}}, — и каждая должна быть объявлена в parameters с sample_value.

Логический шаблон

Для WhatsApp Business действует модель «логического шаблона»: один шаблон (по имени/slug) можно раскатать сразу на несколько WABA-каналов и языков — под капотом создаётся отдельный экземпляр на каждую пару (канал × язык), и каждый независимо отправляется на модерацию Meta.

Поэтому GET /v1/templates возвращает по одной строке на логическую группу (template_group_id) с агрегатом logical_template: сводным статусом Meta и разбивкой по каждому каналу (meta_status / meta_status_reason / last_synced_at). Редактирование ведётся по мастер-контенту — правки распространяются на дочерние экземпляры того же языка. При удалении шаблона каждый его WABA-экземпляр дополнительно снимается из Meta (best-effort), чтобы последующая синхронизация не восстановила его.

Языковые версии

Языковые версии управляются отдельно от каналов. POST /v1/templates/{template}/languages добавляет к логической группе новый язык (language, до 12 символов; тело — тот же контент, что при создании: body, parameters, buttons, header/footer) и создаёт по экземпляру этого языка на каждый уже назначенный WABA-канал группы; если у группы ещё нет ни одного назначенного канала — 422 («сначала назначьте канал»), а повтор уже существующего языка — тоже 422.

DELETE /v1/templates/{template}/languages/{language} удаляет все экземпляры этого языка (best-effort снимая их из Meta), но не даёт удалить единственный оставшийся язык — для этого удаляйте шаблон целиком. Оба ответа возвращают агрегат versions — плоский список экземпляров группы вида { id, language, channel_id, status, meta_status }.

Эндпоинты

МетодПуть
GET/v1/templates

Список шаблонов (по одной строке на логическую группу) с пагинацией, поиском и фасетами по статусу/языку/типу канала.

GET/v1/templates/channel-types

Типы каналов, для которых можно создавать шаблоны.

GET/v1/templates/{template}

Получить шаблон по id (тело, параметры, кнопки) и его языковые версии.

GET/v1/templates/{template}/channels

Доступность логического шаблона по WABA-каналам: по каждому каналу — статус Meta (`meta_status` / `meta_status_reason` / `last_synced_at`) и признак `added` / `not_added`.

GET/v1/templates/{template}/events

История событий логической группы: создание/правки, отправка в Meta, результаты модерации, публикация/архивирование (с каналом и автором).

POST/v1/templates

Создать черновик шаблона. Для WhatsApp Business можно передать `channel_ids` — Aisar создаст по экземпляру на каждый выбранный WABA-канал и отправит каждый в Meta.

PATCH/v1/templates/{template}

Обновить черновик шаблона (правки распространяются на дочерние экземпляры того же языка).

POST/v1/templates/{template}

Обновить черновик шаблона (POST-вариант PATCH).

POST/v1/templates/{template}/channels

Назначить WhatsApp Business-шаблон на дополнительные каналы; тело `{ channel_ids: number[] }`. Создаёт по экземпляру на каждый новый канал и отправляет опубликованные в Meta.

POST/v1/templates/{template}/languages

Добавить языковую версию логического шаблона (WhatsApp Business): создаёт по экземпляру этого языка на каждый уже назначенный канал.

DELETE/v1/templates/{template}/languages/{language}

Удалить языковую версию (все её экземпляры; единственный язык удалить нельзя). Каждый WABA-экземпляр дополнительно снимается из Meta (best-effort).

DELETE/v1/templates/{template}

Удалить шаблон и все экземпляры логической группы. Для WhatsApp Business каждый экземпляр дополнительно удаляется из Meta (best-effort).

POST/v1/templates/{template}/submit

Отправить/переотправить все назначенные WABA-экземпляры шаблона на модерацию в Meta.

POST/v1/templates/{template}/publish

Опубликовать одобренный шаблон (сделать доступным для отправки).

POST/v1/templates/{template}/archive

Архивировать шаблон.

POST/v1/templates/{template}/unarchive

Разархивировать шаблон.

POST/v1/templates/sync

Синхронизировать статусы модерации всех WABA-шаблонов компании с Meta.

Примеры

Создание WhatsApp Business-шаблона на несколько каналов

Запрос

bash
# channel_ids раскатывает шаблон на выбранные WABA-каналы: Aisar создаёт по
# экземпляру на каждый канал (и язык) и отправляет каждый в Meta. В ответе —
# представитель логической группы (template_group_id). Переменные — именованные.
curl -X POST "https://api.aisar.app/v1/templates" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_type": "whatsapp_business",
    "channel_ids": [44, 45],
    "name": "Order shipped",
    "slug": "order_shipped",
    "language": "ru",
    "category": "utility",
    "body": "Здравствуйте, {{first_name}}! Ваш заказ №{{order_number}} передан в доставку.",
    "parameters": [
      { "name": "first_name", "type": "text", "sample_value": "Иван", "position": 1 },
      { "name": "order_number", "type": "text", "sample_value": "1045", "position": 2 }
    ]
  }'

Ответ

json
{
  "data": {
    "message": "Template created.",
    "template": {
      "id": 12,
      "company_id": 1,
      "template_group_id": 8,
      "channel_type": { "id": 4, "key": "whatsapp_business", "name": "WhatsApp Business" },
      "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34" },
      "name": "Order shipped",
      "slug": "order_shipped",
      "status": "draft",
      "meta_status": "local",
      "meta_status_reason": null,
      "last_synced_at": null,
      "language": "ru",
      "category": "utility",
      "body": "Здравствуйте, {{first_name}}! Ваш заказ №{{order_number}} передан в доставку.",
      "parameters": [
        { "id": 1, "name": "first_name", "type": "text", "sample_value": "Иван", "position": 1 },
        { "id": 2, "name": "order_number", "type": "text", "sample_value": "1045", "position": 2 }
      ],
      "buttons": [],
      "uses_count": 0,
      "created_at": "2026-02-09T18:00:00Z",
      "updated_at": "2026-02-09T18:00:00Z"
    }
  }
}

Список шаблонов с фильтрами, фасетами и агрегатом logical_template

Запрос

bash
curl -G "https://api.aisar.app/v1/templates" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  --data-urlencode "status=published" \
  --data-urlencode "language=ru" \
  --data-urlencode "channelType=whatsapp_business" \
  --data-urlencode "sortBy=updated_at" \
  --data-urlencode "sortDir=desc" \
  --data-urlencode "includeFacets=true"

Ответ

json
{
  "data": {
    "items": [
      {
        "id": 12,
        "template_group_id": 8,
        "name": "Order shipped",
        "status": "published",
        "meta_status": "approved",
        "language": "ru",
        "category": "utility",
        "body": "Здравствуйте, {{first_name}}! Ваш заказ №{{order_number}} передан в доставку.",
        "channel_type": { "id": 4, "key": "whatsapp_business", "name": "WhatsApp Business" },
        "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34" },
        "logical_template": {
          "instances_count": 3,
          "assigned_channels_count": 2,
          "uses_count": 34,
          "languages": ["kk", "ru"],
          "channels": [
            {
              "id": 44,
              "name": "WABA — Sales",
              "account_name": "+7 700 000 12 34",
              "meta_status": "approved",
              "meta_status_reason": null,
              "last_synced_at": "2026-05-15T20:40:00Z"
            },
            {
              "id": 45,
              "name": "WABA — Support",
              "account_name": "+7 700 000 56 78",
              "meta_status": "pending",
              "meta_status_reason": null,
              "last_synced_at": "2026-05-15T20:41:00Z"
            }
          ],
          "meta_status_counts": { "approved": 2, "pending": 1 },
          "meta_overall_status": "pending"
        },
        "labels": ["orders"],
        "uses_count": 34,
        "created_at": "2026-02-09T18:00:00Z",
        "updated_at": "2026-02-10T09:15:00Z"
      }
    ],
    "pagination": { "page": 1, "perPage": 15, "total": 1, "lastPage": 1 },
    "facets": {
      "statuses": { "draft": 2, "published": 1, "archived": 0 },
      "languages": { "ru": 3 },
      "channel_types": { "whatsapp_business": 3 }
    }
  }
}

Доступность логического шаблона по каналам

Запрос

bash
curl -X GET "https://api.aisar.app/v1/templates/12/channels" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "items": [
      {
        "channel": {
          "id": 44,
          "name": "WABA — Sales",
          "account_name": "+7 700 000 12 34",
          "status": "connected",
          "external_ids": {}
        },
        "template": {
          "id": 12,
          "external_id": "1180000000000012",
          "status": "published",
          "meta_status": "approved",
          "meta_status_reason": null,
          "last_synced_at": "2026-05-15T20:40:00Z"
        },
        "availability": "added"
      },
      {
        "channel": {
          "id": 46,
          "name": "WABA — Marketing",
          "account_name": "+7 700 000 90 12",
          "status": "connected",
          "external_ids": {}
        },
        "template": null,
        "availability": "not_added"
      }
    ]
  }
}

Назначение шаблона на дополнительный WABA-канал

Запрос

bash
curl -X POST "https://api.aisar.app/v1/templates/12/channels" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "channel_ids": [46] }'

Ответ

json
{
  "data": {
    "message": "Template channels updated.",
    "items": [
      {
        "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34", "status": "connected", "external_ids": {} },
        "template": { "id": 12, "external_id": "1180000000000012", "status": "published", "meta_status": "approved", "meta_status_reason": null, "last_synced_at": "2026-05-15T20:40:00Z" },
        "availability": "added"
      },
      {
        "channel": { "id": 46, "name": "WABA — Marketing", "account_name": "+7 700 000 90 12", "status": "connected", "external_ids": {} },
        "template": { "id": 27, "external_id": null, "status": "published", "meta_status": "local", "meta_status_reason": null, "last_synced_at": null },
        "availability": "added"
      }
    ]
  }
}

История событий логического шаблона

Запрос

bash
curl -X GET "https://api.aisar.app/v1/templates/12/events" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "items": [
      {
        "id": 210,
        "type": "meta_approved",
        "meta_status": "approved",
        "reason": null,
        "metadata": null,
        "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34" },
        "actor": null,
        "created_at": "2026-05-15T20:40:00Z"
      },
      {
        "id": 208,
        "type": "submitted",
        "meta_status": null,
        "reason": null,
        "metadata": null,
        "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34" },
        "actor": { "id": 3, "name": "Айгуль Смагулова" },
        "created_at": "2026-05-15T18:05:00Z"
      },
      {
        "id": 205,
        "type": "created",
        "meta_status": null,
        "reason": null,
        "metadata": null,
        "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34" },
        "actor": { "id": 3, "name": "Айгуль Смагулова" },
        "created_at": "2026-05-15T18:00:00Z"
      }
    ]
  }
}

Шаблон с заголовком, футером и кнопками

Запрос

bash
curl -X POST "https://api.aisar.app/v1/templates" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_type": "whatsapp_business",
    "name": "Appointment reminder",
    "slug": "appointment_reminder",
    "language": "ru",
    "category": "utility",
    "body": "Здравствуйте, {{first_name}}! Напоминаем о записи {{appointment_at}}.",
    "header_enabled": true,
    "header_type": "text",
    "header_text": "Напоминание о визите",
    "footer_enabled": true,
    "footer_text": "Клиника «Ромашка»",
    "buttons_enabled": true,
    "labels": ["reminders"],
    "parameters": [
      { "name": "first_name", "type": "text", "sample_value": "Айгуль", "position": 1 },
      { "name": "appointment_at", "type": "text", "sample_value": "12 марта, 10:00", "position": 2 }
    ],
    "buttons": [
      { "type": "quick_reply", "label": "Подтвердить", "value": null, "position": 1 },
      { "type": "url", "label": "Перенести", "value": "https://example.com/appointments/{{1}}", "position": 2 },
      { "type": "phone", "label": "Позвонить", "value": "+7 700 000 00 00", "position": 3 }
    ]
  }'

Ответ

json
{
  "data": {
    "message": "Template created.",
    "template": {
      "id": 15,
      "company_id": 1,
      "template_group_id": 9,
      "channel_type": { "id": 4, "key": "whatsapp_business", "name": "WhatsApp Business" },
      "channel": null,
      "name": "Appointment reminder",
      "slug": "appointment_reminder",
      "status": "draft",
      "meta_status": null,
      "meta_status_reason": null,
      "last_synced_at": null,
      "language": "ru",
      "category": "utility",
      "body": "Здравствуйте, {{first_name}}! Напоминаем о записи {{appointment_at}}.",
      "header_enabled": true,
      "header_type": "text",
      "header_text": "Напоминание о визите",
      "footer_enabled": true,
      "footer_text": "Клиника «Ромашка»",
      "buttons_enabled": true,
      "labels": ["reminders"],
      "parameters": [
        { "id": 5, "name": "first_name", "type": "text", "sample_value": "Айгуль", "position": 1 },
        { "id": 6, "name": "appointment_at", "type": "text", "sample_value": "12 марта, 10:00", "position": 2 }
      ],
      "buttons": [
        { "id": 7, "type": "quick_reply", "label": "Подтвердить", "value": null, "position": 1 },
        { "id": 8, "type": "url", "label": "Перенести", "value": "https://example.com/appointments/{{1}}", "position": 2 },
        { "id": 9, "type": "phone", "label": "Позвонить", "value": "+7 700 000 00 00", "position": 3 }
      ],
      "uses_count": 0,
      "created_at": "2026-03-01T08:00:00Z",
      "updated_at": "2026-03-01T08:00:00Z"
    }
  }
}

Отправка шаблона на модерацию

Запрос

bash
curl -X POST "https://api.aisar.app/v1/templates/12/submit" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "message": "Template submitted to Meta.",
    "submitted_count": 2,
    "items": [
      {
        "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34", "status": "connected", "external_ids": {} },
        "template": { "id": 12, "external_id": null, "status": "published", "meta_status": "local", "meta_status_reason": null, "last_synced_at": null },
        "availability": "added"
      },
      {
        "channel": { "id": 45, "name": "WABA — Support", "account_name": "+7 700 000 56 78", "status": "connected", "external_ids": {} },
        "template": { "id": 20, "external_id": null, "status": "published", "meta_status": "local", "meta_status_reason": null, "last_synced_at": null },
        "availability": "added"
      }
    ]
  }
}

Публикация, архивирование и разархивирование

Запрос

bash
# Публикация одобренного шаблона (архивирование/разархивирование — аналогично, тело пустое)
curl -X POST "https://api.aisar.app/v1/templates/12/publish" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "message": "Template status updated.",
    "template": {
      "id": 12,
      "status": "published"
    }
  }
}

Добавление языковой версии шаблона

Запрос

bash
curl -X POST "https://api.aisar.app/v1/templates/12/languages" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "en",
    "body": "Hello, {{first_name}}! Your order #{{order_number}} has been shipped.",
    "parameters": [
      { "name": "first_name", "type": "text", "sample_value": "John", "position": 1 },
      { "name": "order_number", "type": "text", "sample_value": "1045", "position": 2 }
    ]
  }'

Ответ

json
{
  "data": {
    "message": "Template language version created.",
    "template": {
      "id": 30,
      "company_id": 1,
      "template_group_id": 8,
      "channel_type": { "id": 4, "key": "whatsapp_business", "name": "WhatsApp Business" },
      "channel": { "id": 44, "name": "WABA — Sales", "account_name": "+7 700 000 12 34" },
      "name": "Order shipped",
      "slug": "order_shipped",
      "status": "draft",
      "meta_status": "local",
      "language": "en",
      "category": "utility",
      "body": "Hello, {{first_name}}! Your order #{{order_number}} has been shipped.",
      "parameters": [
        { "id": 40, "name": "first_name", "type": "text", "sample_value": "John", "position": 1 },
        { "id": 41, "name": "order_number", "type": "text", "sample_value": "1045", "position": 2 }
      ],
      "buttons": [],
      "uses_count": 0,
      "created_at": "2026-03-01T09:00:00Z",
      "updated_at": "2026-03-01T09:00:00Z"
    },
    "versions": [
      { "id": 12, "language": "ru", "channel_id": 44, "status": "published", "meta_status": "approved" },
      { "id": 20, "language": "ru", "channel_id": 45, "status": "published", "meta_status": "pending" },
      { "id": 30, "language": "en", "channel_id": 44, "status": "draft", "meta_status": "local" },
      { "id": 31, "language": "en", "channel_id": 45, "status": "draft", "meta_status": "local" }
    ]
  }
}

Удаление языковой версии шаблона

Запрос

bash
curl -X DELETE "https://api.aisar.app/v1/templates/12/languages/en" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ответ

json
{
  "data": {
    "message": "Template language version deleted.",
    "versions": [
      { "id": 12, "language": "ru", "channel_id": 44, "status": "published", "meta_status": "approved" },
      { "id": 20, "language": "ru", "channel_id": 45, "status": "published", "meta_status": "pending" }
    ]
  }
}