API для автоматической отправки
Версия 1 · обновлено 25 октября 2026 года
Ваш сервер отправляет пуш подписчикам сайта одним запросом — сразу, без подтверждения в панели. Через API же видны все рассылки сайта (в том числе отправленные вручную из панели) и их статистика.
1. Ключ и авторизация
Адрес API: https://push.arnextech.kz/api/v1/. Ключ выпускается в панели: сайт → «Настройки» → «API для автоматической отправки» → «Выпустить ключ». Ключ показывается один раз; у нас хранится только его хеш.
Каждый запрос — с заголовком:
Authorization: Bearer ak_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Ключ привязан к одному сайту и сам не меняется — срока действия нет. Если ключ утёк или нужно сменить его по графику: выпустите новый, переключите сервер на него, затем отзовите старый (кнопка «Отозвать») — отозванный перестаёт работать сразу. Одновременно у сайта может быть до 5 действующих ключей.
Запросы с телом — Content-Type: application/json, кодировка UTF-8. Ключ держите только на сервере: не вставляйте его в код страниц и в приложения.
2. Отправить пуш
POST/api/v1/campaigns
curl -X POST https://push.arnextech.kz/api/v1/campaigns \
-H "Authorization: Bearer $ARNEX_PUSH_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Главная новость дня",
"body": "Короткое описание, которое увидит подписчик",
"url": "https://reposta.kz/ru/news/12345?utm_source=push&utm_medium=arnex&utm_campaign=auto",
"image": "https://reposta.kz/media/12345-1024x512.jpg",
"ttl": 9000,
"segment": { "lang": "ru" }
}'
Ответ 201 Created — рассылка поставлена в очередь и начинает уходить в течение пары секунд:
{
"id": 214,
"source": "api",
"status": "scheduled",
"test": false,
"segment": { "lang": "ru" },
"title": "Главная новость дня",
"body": "Короткое описание, которое увидит подписчик",
"url": "https://reposta.kz/ru/news/12345?utm_source=push&utm_medium=arnex&utm_campaign=auto",
"icon": null,
"image": "https://reposta.kz/media/12345-1024x512.jpg",
"ttl": 9000,
"created_at": "2026-10-24T09:30:00.000Z",
"send_at": "2026-10-24T09:30:00.000Z",
"started_at": null,
"finished_at": null,
"stats": { "recipients": 128, "delivered": 0, "failed": 0, "unsubscribed": 0, "shown": 0, "clicked": 0 },
"error": null
}
id — идентификатор рассылки, по нему читается статистика. stats.recipients — сколько подписчиков попало в рассылку на момент создания. Все времена — в UTC (ISO 8601, суффикс Z).
Отложенная отправка: поле "send_at": "2026-10-24T12:00:00Z" (не дальше 30 дней). Без него — сразу.
3. Поля пуша и ограничения
| Поле | Обязательно | Ограничение | Что видит подписчик |
|---|---|---|---|
title | да | до 120 символов | Жирная строка. Целиком видно примерно 40–50 символов (Windows, Android), на macOS — около 40; дальше браузер обрезает многоточием |
body | нет | до 300 символов | Текст под заголовком: на Android и Windows — 2–3 строки (около 100–120 символов), на macOS — около 80 |
url | да | https://… | Открывается по клику ровно в том виде, как вы передали: со всеми вашими UTM-метками, без подмены, без переадресации через нас. В пушах из API мы свои метки не добавляем |
icon | нет | https://…, квадрат, лучше PNG 192×192 | Иконка слева. Если не указать — иконка сайта из настроек |
image | нет | https://…, 2:1, лучше 1024×512 JPG/PNG | Крупная картинка. Показывают Chrome, Edge и Яндекс на Windows и Android; Safari и macOS её не показывают |
ttl | нет | секунды, от 60 до 2 419 200 (28 дней); по умолчанию 21 600 (6 часов) | Сколько служба пушей хранит уведомление для выключенного устройства. Устройство включилось позже — пуш не придёт |
segment.lang | нет | "ru" или "kk" | Только подписчики этого языка, см. ниже |
test | нет | true | Только тестовым браузерам, см. ниже |
allow_duplicate | нет | true | Разрешить повтор той же ссылки в течение суток, см. «Ошибки» |
Весь пуш вместе со ссылками должен уложиться в 4 КБ (ограничение браузеров) — при превышении ответ 400 «Слишком длинный пуш». Обычной новости это не грозит.
4. Сегменты по языку
Язык подписчика — это атрибут <html lang="…"> страницы, на которой он подписался или которую открывал последней: на /ru/ у вас стоит lang="ru", на /kk/ — lang="kk", так что подписчики сами разделяются по версиям сайта. Ничего дополнительно ставить не нужно.
При отправке укажите "segment": { "lang": "kk" } — уйдёт только казахской аудитории. Без segment — всем подписчикам сайта.
Часть подписчиков, перешедших со SendPulse, переехала без открытой страницы, и язык у них пока не известен. Он определяется при следующем заходе такого подписчика на сайт. Сколько таких сейчас — в GET /api/v1/site, поле by_lang.unknown.
Таких подписчиков можно отнести к одному языку: в панели, сайт → «Настройки» → «Подписчики без языка» → «Считать русскоязычными» (или казахоязычными). Тогда рассылка с "segment": { "lang": "ru" } уйдёт и им, менять запросы не нужно. Когда человек откроет казахскую версию, его язык станет kk и он перейдёт в казахский сегмент. Сколько получит каждый сегмент с учётом настройки — поле subscribers.segments.
5. Тестовая отправка
Добавьте "test": true — пуш уйдёт только тестовым браузерам сайта. Чтобы браузер стал тестовым, откройте в нём ссылку тестировщика из панели (сайт → «Установка» → «Ссылка тестировщика», вида https://reposta.kz/?arnexpush_test=…) и разрешите уведомления. Тестовых браузеров может быть сколько угодно; список и удаление — в панели.
Тестовые рассылки видны в списке с "test": true и не попадают под защиту от повтора — можно гонять одну и ту же ссылку сколько нужно.
6. Список рассылок
GET/api/v1/campaigns?limit=20
Последние рассылки сайта, новые сначала — все: из API ("source": "api"), отправленные вручную из панели ("manual") и автопуши из RSS ("rss"). Черновики не входят. Формат каждой — как в ответе на отправку.
| Параметр | Значение |
|---|---|
limit | 1–100, по умолчанию 20 |
since | только созданные не раньше этого времени, ISO 8601: 2026-10-24T00:00:00Z |
before_id | для следующей страницы: рассылки с id меньше указанного |
Чтобы автоматика не отправила пуш сразу после ручного, берите последнюю рассылку с "test": false и статусом sending или done и смотрите её started_at:
curl -s "https://push.arnextech.kz/api/v1/campaigns?limit=5" -H "Authorization: Bearer $ARNEX_PUSH_KEY"
{ "campaigns": [
{ "id": 215, "source": "manual", "status": "done", "test": false,
"started_at": "2026-10-24T08:02:11.120Z", "finished_at": "2026-10-24T08:02:13.480Z", ... },
{ "id": 214, "source": "api", "status": "done", ... }
] }
Статусы: scheduled — ждёт времени отправки, sending — уходит, done — отправлена, canceled — отменена, failed — ошибка (текст в error).
7. Статистика рассылки и отмена
GET/api/v1/campaigns/{id}
Поле stats | Что значит |
|---|---|
recipients | сколько подписчиков в рассылке |
delivered | принято службами пушей (Google, Mozilla, Apple, Microsoft) для доставки |
failed | служба пушей отказала (временная ошибка) |
unsubscribed | подписка больше не действует — человек отписался или удалил браузер; такие подписчики выбывают |
shown | уведомление показано на устройстве |
clicked | кликов по уведомлению |
Показы и клики дособираются ещё несколько часов после отправки — пока устройства подписчиков выходят в сеть (в пределах ttl).
POST/api/v1/campaigns/{id}/cancel — отменить запланированную или ещё уходящую рассылку. Уже доставленные уведомления не отзываются.
8. Подписчики сайта
GET/api/v1/site
{
"id": 7, "slug": "reposta", "name": "Reposta.kz", "domains": ["reposta.kz"],
"subscribers": {
"active": 291,
"by_lang": { "ru": 128, "kk": 46, "other": 1, "unknown": 116 },
"testers": 0,
"unknown_lang_as": "ru",
"segments": { "ru": 244, "kk": 46 }
}
}
9. Ошибки и лимиты
Ошибка — код HTTP и тело:
{ "error": "duplicate", "message": "Эта ссылка уже уходила всем за последние сутки…", "campaign_id": 214 }
| Код | error | Когда |
|---|---|---|
| 400 | invalid | Нет заголовка или ссылки, ссылка не https, неверный сегмент, пуш длиннее 4 КБ. Причина — в message |
| 401 | unauthorized | Нет ключа, ключ неверный или отозван |
| 404 | not_found | Нет такой рассылки у этого сайта |
| 409 | duplicate | Та же ссылка уже уходила всем (из API или вручную) за последние 24 часа — защита от двойной отправки при сбое и повторе запроса. В campaign_id — та рассылка. Повторить осознанно: "allow_duplicate": true |
| 409 | state | Отмена уже завершённой рассылки |
| 415 | json_only | Тело не JSON |
| 429 | rate_limited | Превышен лимит; в retry_after — через сколько секунд повторить |
| 5xx | — | Сбой у нас: повторите запрос через минуту. Повтор безопасен — второй раз ту же ссылку не пропустит защита от повтора |
Лимиты: 120 запросов в минуту на ключ; не больше 12 рассылок всем подписчикам за час на сайт (тестовые не считаются). Рассылка раз в 2,5 часа укладывается с большим запасом.
Вопросы и подключение — заявка на главной или менеджеру Arnex.