Документация
HTTP API
Один эндпоинт для отправки события с сервера и один — для браузера. Всё остальное — необязательные поля.
Ключи доступа
Ключи создаются в кабинете на вкладке «Подключение». Их два типа, и они не взаимозаменяемы.
- sk_live_…
- Секретный. Только для кода на вашем сервере. Показывается один раз при создании.
- pk_live_…
- Публичный. Вставляется в HTML, виден посетителям. Умеет только создавать события и только с разрешённых доменов.
Отправка с сервера
/api/v1/notifyЗаголовок Authorization: Bearer sk_live_…. Тело — JSON.
curl -X POST https://notily.ru/api/v1/notify \
-H "Authorization: Bearer sk_live_ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"title": "Новая заявка",
"body": "Иван, +7 900 000-00-00",
"level": "info",
"source": "Форма на главной",
"url": "https://mysite.ru/zayavka",
"fields": {
"Имя": "Иван",
"Телефон": "+7 900 000-00-00"
}
}'Отправка из браузера
/api/v1/collectИспользуется сниппетом. Ключ передаётся в поле key внутри тела, а не в заголовке: этого требует navigator.sendBeacon, который единственный не теряет запрос при уходе со страницы.
notily.notify({
title: 'Оплата прошла',
body: 'Заказ №4812 · 34 900 ₽',
level: 'success',
fields: { 'Заказ': '4812', 'Сумма': '34 900 ₽' }
})Функция notily.notify появляется после подключения сниппета. Автоматический перехват форм при этом продолжает работать.
Поля запроса
- title
- Обязательное. Заголовок, до 200 символов. Принимается также как message или text.
- body
- Текст под заголовком, до 4000 символов.
- level
- info · success · warning · error. По умолчанию info. Влияет на цвет и на фильтр по важности.
- source
- Откуда пришло: «Форма на главной», «Онлайн-касса».
- url
- Ссылка кнопки «Открыть». Только http и https.
- fields
- Поля формы. Объект или массив пар. До 50 штук. Вложенные объекты и массивы разворачиваются сами.
- items
- Состав заказа. Массив позиций. Принимается также как cart или products.
- amount
- Сумма заказа. Число в рублях либо строка вида «4 900,50 ₽». Если не передать — сложим позиции.
- orderId
- Номер заказа в вашей системе. Принимается также как order_id или orderNumber.
- dedupKey
- Схлопывание дублей в пределах окна, заданного в настройках проекта.
- idempotencyKey
- Защита от повторной отправки при ретрае. Повтор вернёт тот же id события.
Состав заказа
Имя и телефон отвечают на вопрос «кто написал». Состав заказа — на вопрос «что именно заказали», и без него заявку из магазина приходится уточнять звонком.
{
"title": "Заказ звёздного неба",
"orderId": "1043",
"amount": 4900,
"fields": { "Имя": "Иван", "Телефон": "+7 900 000-00-00" },
"items": [
{
"name": "Постер «Звёздное небо»",
"quantity": 1,
"price": 3900,
"options": {
"Дата": "12 мая 1990, 03:40",
"Место": "Липецк",
"Размер": "60 × 90",
"Надпись": "Тот самый вечер"
}
},
{ "name": "Рама, чёрный дуб", "quantity": 1, "price": 1000 }
]
}Ключи позиции распознаются под привычными именами: name или title, quantity или qty, price, sum, sku, url. Всё остальное, что вы положите в позицию, попадёт в её характеристики — объявлять их заранее не нужно.
price и amount — это рубли. Если вы считаете в копейках, используйте priceKopecks и sumKopecks.Корзина из браузера
Сниппет собирает состав заказа сам, если на странице есть что собирать. Четыре способа, от простого к подробному.
// 1. Корзина из кода сайта — уедет с ближайшей отправкой формы
notily.cart(
[{ name: 'Постер 60×90', quantity: 1, price: 3900,
options: { 'Дата': '12.05.1990', 'Место': 'Липецк' } }],
{ amount: 4900, order: '1043' }
)
// 2. Готовый JSON на форме
<form data-notily-items='[{"name":"Постер","price":3900}]'>
// 3. JSON в скрытом поле — так отдают корзину конструкторы
<input type="hidden" data-notily-items value="[...]">
// 4. Разметка корзины прямо на странице
<div data-notily-item data-notily-name="Постер" data-notily-price="3900">
<span data-notily-option="Дата">12.05.1990</span>
<span data-notily-option="Место">Липецк</span>
</div>Сумму и номер заказа можно указать атрибутами data-notily-amount и data-notily-order на форме или на любом элементе внутри неё.
Ответы
{ "ok": true, "id": "evt_...", "status": "created" }status равен duplicate, если событие схлопнулось с предыдущим или пришло с уже использованным idempotencyKey. Это не ошибка — повторять запрос не нужно.
- 400
- Тело не JSON или превышает 64 КБ.
- 401
- Ключ не найден или отозван.
- 403
- Не тот тип ключа либо домен не в списке разрешённых.
- 422
- Не хватает обязательного поля или значение не проходит проверку.
- 429
- Превышен лимит. В заголовке Retry-After — через сколько секунд повторить.
- 402
- Исчерпан месячный лимит тарифа.
Лимиты
- По ключу
- 120 запросов в минуту
- По IP на публичном эндпоинте
- 20 запросов в минуту
- Размер тела
- 64 КБ
- Хранение событий
- зависит от тарифа: от 10 до 60 дней, дольше не хранятся
При штатной работе лимиты незаметны. Они существуют, чтобы ошибка в цикле на одном сайте не мешала остальным.
Проверка ключа
/api/v1/pingcurl https://notily.ru/api/v1/ping \
-H "Authorization: Bearer sk_live_ВАШ_КЛЮЧ"
{ "ok": true, "keyType": "secret" }Отвечает, жив ли ключ, не создавая события в ленте. Удобно для проверки после настройки.
