Перейти до основного вмісту

Customer.io

Customer.io — платформа автоматизації маркетингових комунікацій. Готового SMS-каналу для AlphaSMS у ній немає, але на будь-якому тарифі Customer.io вміє викликати зовнішній API дією Send and receive data (у розсилках той самий механізм називається каналом Webhook).

У цій інструкції — як надсилати SMS з кампанії, розсилки або транзакційного повідомлення Customer.io через API AlphaSMS і як отримувати звіти про доставку.

НапрямокЯк працює
Customer.io → AlphaSMSPOST-вебхук із тілом JSON, де type дорівнює sms
AlphaSMS → ваша системаЗвіт про доставку на адресу з параметра hook

Що потрібно перед початком

  1. Активний акаунт AlphaSMS з увімкненою опцією Активувати API — див. Налаштування API.
  2. API-ключ (крок 1 нижче).
  3. Ім'я відправника — буквено-цифровий підпис, який абонент бачить замість номера (від 3 до 11 латинських літер і цифр). Телефонний номер як відправника AlphaSMS не використовує.
  4. Профілі в Customer.io з телефоном у міжнародному форматі (наприклад, +380971234567 або 380971234567).

Крок 1. Створіть API-ключ

У кабінеті AlphaSMS відкрийте Налаштування → API. У таблиці перелічені ключі з датою створення, терміном дії, станом, коментарем і списком дозволених IP.

image1

Customer.io - фото 1

Натисніть ADD, вкажіть коментар (наприклад, Customer.io), позначте Active і натисніть EXECUTE.

image2

Customer.io - фото 2

Повне значення ключа показується один раз — одразу після створення. Скопіюйте його відразу: у таблиці згодом видно лише перші символи.

image3

Customer.io - фото 3

увага

Для ключа, який використовується в Customer.io, залиште поле IP whitelisting порожнім. Customer.io надсилає вебхуки з великого пулу адрес, що постійно змінюється, тому фіксований список IP рано чи пізно почне відбивати трафік помилкою Access denied. Краще завести для Customer.io окремий ключ — його можна відкликати, не зачепивши інші інтеграції.

Крок 2. Оберіть ім'я відправника

Ім'я відправника передається в кожному повідомленні в параметрі sms_signature, тому для різних кампаній можна використовувати різні імена: бренд — для маркетингу, назву сервісу — для транзакційних сповіщень. Імена працюють динамічно: ви не обмежені заздалегідь заданим списком, нове ім'я починає працювати одразу після першої відправки з ним.

Обмеження надходять лише з боку мережі отримувача: частина операторів і країн приймає буквено-цифрові імена тільки після реєстрації та може відхилити або підмінити незнайоме ім'я. Уточніть у підтримки напрямки, на які ви плануєте надсилати.

Імена, які вже використовуються на акаунті, видно в кабінеті — див. Ім'я відправника.

Крок 3. Додайте вебхук у Customer.io

  • Кампанія (journey) — відкрийте workflow, перетягніть блок Send and receive data і натисніть Add Request.
  • Розсилка (broadcast) — на кроці Content оберіть канал Webhook і натисніть Add content.

image4

Customer.io - фото 4

Налаштування запиту:

ПолеЗначення
MethodPOST
Request URLhttps://api-async.alphasms.ua/v1/json
HeaderContent-Type: application/json
увага

Використовуйте саме цю адресу для всіх повідомлень із Customer.io. Endpoint асинхронний: він приймає запит у чергу і відповідає миттєво — саме це й потрібно розсильнику, адже Customer.io робить по вебхуку на кожен профіль, і кампанія легко породжує сотні паралельних запитів.

Заголовки X-CIO-Idempotency-Key та X-CIO-Signature Customer.io додає самостійно. Окремий заголовок авторизації не потрібен — API AlphaSMS авторизує запит за полем auth у тілі.

Крок 4. Складіть тіло запиту

Вставте payload нижче в редактор тіла і замініть YOUR_API_KEY та YOUR_SENDER_ID. Панель Preview праворуч підставляє дані тестового профілю, тому видно точний JSON, який піде в API.

image5

Customer.io - фото 5

{% capture sms_text %}Вітаємо, {{ customer.first_name | default: 'друже' }}! Ваше замовлення вже в дорозі.{% endcapture %}
{
"auth": "YOUR_API_KEY",
"data": [
{
"type": "sms",
"id": "{{delivery_id}}",
"phone": "{{ customer.phone | default: '' | remove: '+' | remove: ' ' | remove: '-' }}",
"sms_signature": "YOUR_SENDER_ID",
"sms_message": {{ sms_text | strip_newlines | json }},
"hook": "https://your-app.example.com/dlr"
}
]
}
ПараметрОбов'язковийОпис
authтакВаш API-ключ
typeтакsms. Інші значення вмикають Viber, RCS, WhatsApp і мультиканальну відправку
idніВаш ідентифікатор повідомлення, повертається в кожному звіті про доставку. {{delivery_id}} — ідентифікатор конкретної відправки в Customer.io
phoneтакНомер отримувача в міжнародному форматі, лише цифри
sms_signatureтакІм'я відправника
sms_messageтакТекст повідомлення
hookніАдреса, на яку надійдуть звіти про доставку цього повідомлення
sms_lifetimeніТермін життя повідомлення в секундах, від 60 до 259200 (3 доби)
short_linkніtrue — скорочувати та відстежувати посилання в тексті (згідно з тарифом)
unsubscribe_linkніtrue — додати посилання відписки (згідно з тарифом)

Повний список параметрів — у розділі Відправка SMS.

Про Liquid
  • {{delivery_id}} у попередньому перегляді порожній (показується unsent) і підставляється в момент відправки. Залиште його: значення має бути унікальним для кожного повідомлення — повтор сприймається як дублікат, і повідомлення не надсилається.
  • Загортайте текст у блок capture і виводьте фільтром json. Фільтр сам ставить лапки та екранує лапки, слеші й керуючі символи, тому емодзі, апострофи та переноси рядків з даних клієнта не зламають JSON.
  • Не застосовуйте до тексту фільтр escape — у Customer.io він робить percent-кодування (@ перетворюється на %40), і абонент отримає закодований текст.
  • До атрибутів, яких може не бути в профілі, завжди додавайте | default: ''. Невизначена змінна для Customer.io — помилка композера (undefined variable: customer.phone), запит іде зі зіпсованим тілом, і API його відхиляє.
  • Змінні {{event.*}} існують лише в кампаніях за подією. У розсилці та в кампанії за сегментом вони дають ту саму помилку невизначеної змінної.
  • Одне повідомлення на профіль. Якщо потрібно надіслати одразу на кілька номерів, додайте об'єкти в масив data.

Крок 5. Обробіть відповідь

Endpoint підтверджує, що пакет прийнято в чергу, і повертає ідентифікатор запиту:

{
"request_id": "cf-ray-1234567890-ABC",
"success": true
}

Ідентифікаторів окремих повідомлень у цій відповіді немає — повідомлення ще йде до шлюзу. request_id повторюється в кожному звіті про доставку, тому його варто зберегти. У розділі Response дії натисніть Add attributes і зіставте:

Атрибут journeyЗначення
sms_request_idresponse.request_id
sms_queuedresponse.success

Проблеми із самим запитом повертаються справжніми HTTP-кодами:

КодЩо означає
400Невалідний JSON або порожній/некоректний масив data
401Не передано, порожній або не прийнято auth
405Метод відмінний від POST
413Завелике тіло запиту
415Content-Type не application/json
503Черга тимчасово недоступна

Customer.io повторює запити з кодами 408, 409, 429 і 5xx до 11 разів приблизно протягом години, тож короткий 503 лікується сам. 400, 401 і 415 — помилки конфігурації, вони не повторюються: стежте за ними в метриках кампанії після запуску.

Прийняте повідомлення все ще може бути відхилене, коли його обробить шлюз. Причина приходить у звіті про доставку і видна в кабінеті в розділі Звіти → API:

ПричинаЩо означає
Error in Alpha-nameІм'я відправника неприпустиме на цьому маршруті або в цього оператора
Not enough moneyНедостатньо коштів на балансі
Duplicate IDЗначення id вже використовувалося на акаунті — воно має бути унікальним
Please enter valid receiver phone numberПорожній або некоректний phone
Receiver blacklistedНомер у вашому чорному списку або відписався
SMS is too longТекст перевищує максимальну довжину
Operator not supportedНемає маршруту до цього оператора

Крок 6. Приймайте звіти про доставку

Кожне повідомлення з параметром hook породжує POST-запит на цю адресу при кожній зміні статусу. Саме там видно підсумковий результат відправки, тому налаштуйте прийом звітів до запуску кампанії.

{
"id": "01HB…",
"msg_id": 123456789,
"type": "sms",
"status": "DELIVERED",
"updated": "2026-08-10T12:34:56+03:00",
"request_id": "cf-ray-1234567890-ABC"
}
  • id — значення, яке ви передали в запиті (у прикладі вище це delivery_id з Customer.io); за ним звіт зіставляється з повідомленням.
  • msg_id — ідентифікатор, присвоєний шлюзом.
  • updated — момент зміни статусу, формат YYYY-MM-DDThh:mm:ss±hh:mm.
  • request_id — ідентифікатор запиту, у якому надійшло повідомлення (асинхронний endpoint).

Запит підписаний: у заголовку X-Signature лежить sha256(json_body + api_key), порахований тим самим ключем, яким надсилалося повідомлення. Запити з розбіжним підписом відкидайте.

$body = file_get_contents('php://input');
if (!hash_equals(hash('sha256', $body . $apiKey), $_SERVER['HTTP_X_SIGNATURE'] ?? '')) {
http_response_code(403);
exit;
}

Відповідайте кодом 200. Статуси перелічені в довіднику Статуси повідомлень; найчастіше трапляються ACCEPTED, QUEUED, DELIVERED, UNDELIVERABLE, EXPIRED, REJECTED.

Спільну для акаунта адресу звітів можна вказати в Налаштування → API → URL для звітів про доставку: вона діє на всі повідомлення акаунта. Докладніше: Webhook.

Крок 7. Тест і запуск

  1. Натисніть Send test… у редакторі та підтвердіть запит. Відповідь з'явиться в панелі Preview — це справжній запит, тому з бойовим ключем SMS дійсно піде.
  2. Перевірте результат у кабінеті: Звіти → API показують повідомлення, його ціну та статус.
  3. Перемкніть дію в режим Send automatically (кампанії) або завершіть майстер розсилки.
Обсяги та аудиторія
  • Жорсткого ліміту запитів на секунду немає. Якщо плануються сплески в десятки тисяч повідомлень, попередьте підтримку заздалегідь — пропускну здатність акаунта переглянуть.
  • Customer.io обриває вебхук через 16 секунд. Наш API відповідає завідомо швидше.
  • Додайте в тригер або аудиторію кампанії умову за телефоном (наприклад, phone exists), щоб профілі без номера взагалі не доходили до вебхука.

Інші канали

Тим самим вебхуком надсилаються Viber, RCS, WhatsApp і голосові дзвінки, зокрема каскадом: наприклад, спочатку Viber, а SMS — тільки якщо Viber не доставлено. Змінюється type і додаються параметри каналу:

typeРезультат
viberViber-повідомлення
viber+smsViber з досилкою SMS
rcs+smsRCS з досилкою SMS
voiceГолосовий дзвінок
hlrПеревірка номера — оператор, роумінг і переносимість, без відправки повідомлення