← Arnex Push

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"). Черновики не входят. Формат каждой — как в ответе на отправку.

ПараметрЗначение
limit1–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Когда
400invalidНет заголовка или ссылки, ссылка не https, неверный сегмент, пуш длиннее 4 КБ. Причина — в message
401unauthorizedНет ключа, ключ неверный или отозван
404not_foundНет такой рассылки у этого сайта
409duplicateТа же ссылка уже уходила всем (из API или вручную) за последние 24 часа — защита от двойной отправки при сбое и повторе запроса. В campaign_id — та рассылка. Повторить осознанно: "allow_duplicate": true
409stateОтмена уже завершённой рассылки
415json_onlyТело не JSON
429rate_limitedПревышен лимит; в retry_after — через сколько секунд повторить
5xx—Сбой у нас: повторите запрос через минуту. Повтор безопасен — второй раз ту же ссылку не пропустит защита от повтора

Лимиты: 120 запросов в минуту на ключ; не больше 12 рассылок всем подписчикам за час на сайт (тестовые не считаются). Рассылка раз в 2,5 часа укладывается с большим запасом.

Вопросы и подключение — заявка на главной или менеджеру Arnex.