API AIMen Inbox
Отправляйте и получайте сообщения WhatsApp, Instagram и Telegram из своей CRM, сайта или сервиса. Inbox сам работает с Meta и Telegram: вам не нужны токены Meta, своё приложение в Meta и приём их вебхуков — только ключ Inbox и адрес для событий.
Начало работы
Все адреса — от https://inbox.aimen.kz, данные — JSON в UTF-8. Есть два способа работы:
- Своя интеграция. У вас аккаунт в Inbox, вы подключаете к нему CRM, сайт или бота. Нужен ключ организации и, если хотите получать входящие, вебхук.
- Партнёр. Ваш продукт подключает WhatsApp своим клиентам: создаёт для каждого организацию в Inbox и показывает наш виджет подключения у себя. Нужен партнёрский ключ — см. Партнёрам.
Ключи
Ключ организации создаёт владелец аккаунта: Настройки → API-ключи → Создать ключ. Ключ показывается один раз — сохраните его в секретах своего сервера. Ключ действует только для своей организации; отозвать его можно там же.
Передавайте ключ в заголовке каждого запроса:
Authorization: Bearer aimen_live_...Ответы и ошибки
Успешный ответ — объект с полем data. Ошибка — объект с полем error (текст на русском, его можно показать пользователю) и HTTP-статусом:
{ "data": { ... } }
{ "error": "Шаблон не найден или ещё не одобрен" }| Поле | Тип | Описание |
|---|---|---|
400 | — | Неверные параметры или их сочетание |
401 | — | Нет ключа, ключ неверный или отозван |
404 | — | Диалог или организация не найдены |
409 | — | Свободный текст вне 24-часового окна WhatsApp (нужен шаблон) или запрос с этим idempotencyKey ещё выполняется |
429 | — | Превышен лимит запросов |
502 | — | Meta или Telegram не приняли сообщение — причина в error |
500 | — | Ошибка на нашей стороне — повторите позже |
Лимиты
300 запросов в минуту на ключ. При превышении — 429, повторите через минуту. Контакты загружайте пачками до 100 в одном запросе, а не по одному.
Каналы
/api/v1/channelsключ организацииПодключённые каналы организации и их состояние.
{
"data": [
{
"id": "8f0c…",
"type": "whatsapp",
"displayName": "+7 701 123 45 67",
"status": "connected",
"restrictionStatus": null,
"restrictionDetail": null
}
]
}| Поле | Тип | Описание |
|---|---|---|
type | string | whatsapp, instagram, telegram или website (чат на сайте) |
status | string | connected — работает; error — нужно переподключить; disconnected — отключён |
restrictionStatus | string | null | Не null — Meta ограничила или заблокировала аккаунт; подробности в restrictionDetail. Покажите это своим пользователям. |
Сообщения
/api/v1/messagesключ организацииОтправка в существующий диалог (любой канал) по conversationId или новому клиенту WhatsApp по номеру телефона — тогда контакт и диалог создаются сами. Сообщение появляется во «Входящих», как отправленное сотрудником.
| Поле | Тип | Описание |
|---|---|---|
conversationId | uuid | Диалог — из события вебхука или прошлого ответа API |
channel + phone | string | Вместо conversationId: "whatsapp" и номер в любом формате (+77011234567, 8 701 …) |
body | string | Текст |
templateId | uuid | Одобренный шаблон WhatsApp (см. Шаблоны) |
templateParams | object | bodyParams — значения {{1}}, {{2}}…; headerParam; buttonUrlParam |
mediaUrl, mediaType | string | Файл по ссылке; mediaType — image, video, audio, document |
mediaFilename | string | Имя файла для document |
replyToMessageId | uuid | Ответ с цитатой на сообщение |
idempotencyKey | string | Защита от двойной отправки при повторе запроса |
В одном запросе — что-то одно: body, templateId или mediaUrl.
{ "data": { "conversationId": "…", "messageId": "…" } }Текст
curl https://inbox.aimen.kz/api/v1/messages \
-H "Authorization: Bearer $INBOX_KEY" \
-H "Content-Type: application/json" \
-d '{ "conversationId": "8f0c…", "body": "Здравствуйте! Заказ готов к выдаче." }'409, и нужно отправить шаблон. В Instagram окно тоже 24 часа, в Telegram и чате на сайте ограничений нет.Шаблон (WhatsApp)
Первое сообщение клиенту, напоминание или ответ после 24 часов — только одобренным шаблоном.
{
"channel": "whatsapp",
"phone": "+77011234567",
"templateId": "c2a1…",
"templateParams": { "bodyParams": ["Айгерим", "15:00", "12 октября"] }
}В существующий диалог WhatsApp — { "conversationId": "…", "templateId": "…", "templateParams": {…} }. Шаблонные сообщения Meta оплачивает отдельно, по своим тарифам.
Файлы
Разместите файл по публичной ссылке — Inbox скачает его и отправит в канал.
{
"conversationId": "8f0c…",
"mediaUrl": "https://example.com/files/invoice-1042.pdf",
"mediaType": "document",
"mediaFilename": "Счёт 1042.pdf"
}Ответ на конкретное сообщение
replyToMessageId — id сообщения клиента из вебхука. В WhatsApp и Telegram клиент увидит цитату; в Instagram цитата видна только в Inbox.
Повторы запроса
Передайте idempotencyKey — свою уникальную строку, например id напоминания в вашей базе. Повторный запрос с тем же ключом (после таймаута) не отправит сообщение второй раз, а вернёт результат первого. Если первый ещё выполняется — 409. Если отправка не удалась, ключ освобождается и запрос можно повторить.
Контакты
/api/v1/contactsключ организацииЗагрузка своей базы клиентов — до 100 за запрос. Совпадение ищется по номеру телефона: существующий контакт не перезаписывается, ему только добавляются теги. Новые теги создаются сами — по ним потом удобно делать рассылки в разделе «Маркетинг».
{
"contacts": [
{ "name": "Айгерим Сапарова", "phone": "+77011234567", "email": "a@example.com", "tags": ["VIP", "Макияж"] }
]
}{
"data": {
"created": 1,
"updated": 0,
"contacts": [{ "id": "…", "phone": "+77011234567", "created": true }],
"errors": [{ "index": 3, "error": "Укажите корректный phone" }]
}
}Шаблоны WhatsApp
/api/v1/templatesключ организации/api/v1/templatesключ организации/api/v1/templates/{id}/submitключ организации/api/v1/templates/{id}ключ организацииШаблон создаётся черновиком, затем отправляется на проверку в Meta. Проверка занимает от нескольких минут до пары дней; статус меняется сам.
{
"name": "Напоминание о записи",
"category": "utility",
"body": "Здравствуйте, {{1}}! Напоминаем о записи {{2}} в {{3}}.",
"exampleParams": ["Айгерим", "12 октября", "15:00"],
"footerText": "Салон «Ажар»",
"buttons": [{ "type": "quick_reply", "text": "Подтверждаю" }]
}| Поле | Тип | Описание |
|---|---|---|
category | string | utility — уведомления о заказе, записи; marketing — акции; authentication — коды входа |
body | string | Текст с параметрами {{1}}, {{2}}… (не в начале и не в конце текста) |
exampleParams | string[] | Примеры значений параметров — Meta требует их для проверки |
headerText, footerText | string | Заголовок и подпись (необязательно) |
buttons | array | quick_reply (до 10), url (до 2), phone_number (1) |
Статусы в списке: draft — черновик, pending — на проверке, approved — можно отправлять, rejected — отклонён (причина в rejection_reason), paused — Meta приостановила за жалобы клиентов. Покажите статус своим пользователям — иначе непонятно, почему новый шаблон нельзя отправить сразу.
Вебхуки
Inbox отправляет события POST-запросом на ваш адрес. Укажите его в Настройки → API-ключи → Вебхук (только https) — там же выдаётся секрет для проверки подписи и есть кнопка тестового события. Партнёрам адрес настраиваем мы, он общий для всех их организаций.
События
{
"event": "message.created",
"organizationId": "…",
"conversationId": "…",
"isNewConversation": true,
"message": {
"id": "…",
"direction": "inbound",
"channel": "whatsapp",
"body": "Здравствуйте, есть размер M?",
"createdAt": "2026-10-10T09:15:00.000Z"
},
"contact": { "id": "…", "name": "Айгерим", "phone": "+77011234567" }
}{
"event": "message.status_updated",
"organizationId": "…",
"conversationId": "…",
"message": { "id": "…", "status": "delivered", "errorDetail": null }
}Статусы: sent, delivered, read, failed (причина в errorDetail). Тестовая кнопка в Настройках присылает { "event": "ping", … }. Неизвестные события пропускайте — со временем их станет больше.
Проверка подписи
В заголовке X-Inbox-Signature — sha256= и HMAC-SHA256 тела запроса вашим секретом. Проверяйте её на каждом запросе, по сырому телу, до разбора JSON:
import crypto from "node:crypto";
export function isFromInbox(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}import hmac, hashlib
def is_from_inbox(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header or "")Повторы доставки
Отвечайте 2xx в течение 5 секунд, а тяжёлую обработку делайте в фоне. Если ваш сервер не ответил, событие не теряется: Inbox повторит его через 1 мин, 5 мин, 30 мин, 2 ч, 6 ч и 24 ч. Событие может прийти повторно — проверяйте message.id, чтобы не обработать его дважды.
Партнёрам
Для продуктов, которые подключают WhatsApp и Instagram своим клиентам: ваш клиент нажимает «Подключить WhatsApp» у вас, проходит вход Facebook в нашем виджете — и вы отправляете и получаете его сообщения через API. Интерфейс Inbox и отдельный логин вашему клиенту не нужны. Партнёрский ключ и вебхук выдаём по запросу на inbox_support@aimen.kz.
1. Организация для клиента
/api/partner/v1/organizationsпартнёрский ключ{ "externalId": "clinic-42", "name": "Клиника «Шипагер»" }{ "data": { "organizationId": "…", "created": true, "apiKey": "aimen_live_…" } }externalId — id клиента в вашей системе. Повторный вызов с тем же externalId вернёт ту же организацию с created: false и apiKey: null. Ключ организации выдаётся один раз — сохраните его сразу и дальше работайте с этим клиентом через разделы выше.
2. Виджет подключения канала
/api/partner/v1/embed-tokensпартнёрский ключ{ "organizationId": "…", "channel": "whatsapp" }{ "data": { "embedUrl": "https://inbox.aimen.kz/embed/connect?token=…", "expiresAt": "…" } }channel — whatsapp или instagram. Ссылка живёт 30 минут. Покажите её в iframe на странице настроек:
<iframe src="{embedUrl}" style="border:0;width:100%;height:120px" allow="popups"></iframe>
<script>
window.addEventListener("message", (event) => {
if (event.origin !== "https://inbox.aimen.kz") return;
if (event.data?.type === "INBOX_CHANNEL_CONNECTED") {
// event.data.channel: "whatsapp" | "instagram" — обновите статус через GET /api/v1/channels
}
});
</script>Перед виджетом коротко объясните клиенту: откроется окно Facebook; нужен аккаунт, связанный с бизнесом; для WhatsApp — номер, на котором нет обычного приложения WhatsApp, и код из SMS; для Instagram — профессиональный аккаунт.
Первый запуск
- Создайте ключ в Настройках → API-ключи (партнёр — получите партнёрский ключ и создайте организацию).
- Проверьте ключ:
GET /api/v1/channels— подключённый канал со статусомconnected. - Укажите адрес вебхука и нажмите «Отправить тестовое событие» — проверьте подпись на своей стороне.
- Напишите на подключённый номер с телефона — придёт
message.created. - Ответьте через
POST /api/v1/messagesсconversationIdиз события — следом придётmessage.status_updated.