PD Документация ← На главную

Уведомления

Уведомления — это сообщения, которые доставляются на устройства через push-провайдеры (FCM, APNs, Web Push) или контактам через канал (email, SMS, MAX, in-app, Telegram). Здесь описан REST API (/api/v1) в том виде, в котором его реализует сервер; GraphQL API, которым пользуется дашборд, предоставляет те же операции.

Аутентификация

Есть два вида API-ключей (Приложения → Настройки → API-ключи):

КлючЗаголовокГде может хранитьсяОперации
Секретный pd_…Authorization: ApiKey pd_…Только ваши серверыВсё, что описано ниже
Публичный pk_…Authorization: Public pk_…Браузеры, мобильные приложенияРегистрация устройств, события вовлечённости, inbox, VAPID-ключ (/api/v1/public/*)

Публичный ключ на секретном эндпоинте получает 403 forbidden.

Отправка уведомления

bash
curl -X POST https://api.pushdata.ru/api/v1/notifications \
  -H "Authorization: ApiKey pd_ВАШ_СЕКРЕТНЫЙ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-123-placed" \
  -d '{
    "title": "Новый заказ",
    "body": "Ваш заказ №123 оформлен.",
    "target": { "user_ids": ["user-123"] },
    "data": { "orderId": "123", "action": "open_order" },
    "click_action": "https://shop.example/orders/123"
  }'

Ответ 201:

json
{ "id": "0192…", "status": "queued" }

status равен queued для немедленной отправки (веерная рассылка выполняется асинхронно) и scheduled, если задан scheduled_at.

Тело запроса

ПолеТипОбязательноОписание
titlestringЗаголовок (≤ 1024 символов)
bodystringТекст (≤ 4096 символов)
targetobjectРовно один из ключей ниже (для канальной отправки — см. следующий раздел)
target.alltrueВсе активные устройства приложения
target.device_idsstringКонкретные id устройств (≤ 10 000)
target.user_idsstringУстройства, зарегистрированные с этими user_id
target.tagsstringУстройства, у которых в tags есть любой из этих тегов
dataobjectПроизвольные ключ-значение, ≤ 4 КБ в сериализованном виде. Доставляется как есть; сервер добавляет pushdata_notification_id / pushdata_device_id для трекинга
click_actionstringURL / deep link, открываемый по нажатию (deep_link принимается как синоним)
iconstringURL иконки (Android, Web Push)
image / image_urlstringURL большого изображения (FCM, Web Push; в APNs передаётся как pushdata_image_url для service extension)
badgenumberСчётчик на иконке (iOS)
soundstringИмя звука (по умолчанию "default")
scheduled_atISO 8601Отложенная отправка; до этого момента статус scheduled
expires_atISO 8601TTL push-уведомления: после этого момента не доставляется (APNs expiration, FCM ttl, Web Push TTL)
apns_category, actionsСохраняются внутри data

template, vars, recurrence* и email_to этим сервером не поддерживаются и отклоняются с 422.

Отправка через канал

Тот же вызов с channel_type уходит не на устройства, а контактам через канал приложения: email, sms, max, in_app — адрес берётся из контакта (email, phone, maxUserId, сам контакт для inbox), telegram — в чат канала. target для канальной отправки описывает контакты: all (все контакты с адресом для этого канала), user_ids (контакты с этими externalId) или contact_ids (PushData-id); device_ids и tags — понятия push, для канала они отклоняются с 422. У Telegram получателя нет — target можно не передавать.

bash
curl -X POST https://api.pushdata.ru/api/v1/notifications \
  -H "Authorization: ApiKey pd_ВАШ_СЕКРЕТНЫЙ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_type": "email",
    "category": "orders",
    "title": "Заказ №123 оформлен",
    "body": "Собираем заказ, курьер позвонит перед доставкой.",
    "target": { "user_ids": ["user-123"] }
  }'
ПолеТипОписание
channel_typepush | email | sms | telegram | max | in_appБез поля — push. Регистр не важен
channel_idstringКонкретный канал приложения; без него берётся самый ранний активный канал этого типа. Неизвестный или чужой — 404, выключенный — 400
categorystringКатегория подписки (≤ 100 символов): контакты, отключившие её для этого канала в настройках, пропускаются
target.contact_idsstringPushData-id контактов (≤ 10 000); только для канальных отправок

title становится темой письма (или первой строкой SMS / сообщения), body — текстом; data доставляется в in-app-сообщении и в вебхуках. У email, SMS, Telegram и MAX нет подтверждения прочтения, поэтому total_delivered для них остаётся 0 (см. ниже).

Идемпотентность

Передавайте необязательный заголовок Idempotency-Key (≤ 255 символов, уникальный в рамках приложения), чтобы повторы были безопасны: повтор с тем же ключом и телом возвращает исходный ответ с Idempotency-Replayed: true; тот же ключ с другим телом — 409 idempotency_conflict. Завершённые ключи хранятся 24 часа.

Квота

Каждый получатель расходует месячный лимит тарифа. Явный список получателей (device_ids; contact_ids или user_ids канальной отправки) больше остатка отклоняется с 402; аудиторная отправка (all, user_ids, tags для push) урезается до остатка при веерной рассылке.

Чтение и отмена

bash
# Одно уведомление со счётчиками (total_targets, total_sent, total_delivered, total_failed, …)
curl https://api.pushdata.ru/api/v1/notifications/0192… -H "Authorization: ApiKey pd_…"

# Отменить запланированное, ожидающее или поставленное в очередь уведомление
curl -X DELETE https://api.pushdata.ru/api/v1/notifications/0192… -H "Authorization: ApiKey pd_…"

Поля в snake_case (app_id, click_action, scheduled_at, total_sent, …). Отсутствующий или чужой id — 404.

Счётчики означают одно и то же везде (дашборд, App.stats, аналитика): total_sent — то, что провайдер принял, total_failed — то, что отклонил, доставляемость = total_sent / (total_sent + total_failed). total_deliveredподтверждённые доставки по колбэку устройства (эталонный service worker, iOS/Android SDK или POST /api/v1/track с event: "delivered"); у email, SMS, Telegram, MAX и in-app такого сигнала нет, поэтому для них счётчик остаётся 0 и не является показателем доставки.

Регистрация устройства

Устройство нужно зарегистрировать до того, как оно сможет получать push. Одно и то же тело работает с секретным ключом на /api/v1/devices и с публичным на /api/v1/public/devices:

bash
curl -X POST https://api.pushdata.ru/api/v1/public/devices \
  -H "Authorization: Public pk_ВАШ_ПУБЛИЧНЫЙ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "android",
    "token": "fcm-registration-token",
    "user_id": "user-123",
    "tags": ["beta"],
    "timezone": "Europe/Moscow"
  }'

Ответ 201: { "id": "0192…", "created": true } (created: false, если токен уже был известен и обновлён).

ПолеТипОписание
platformios | android | webОбязательно
tokenstringТокен APNs (64 hex), registration token FCM или URL endpoint Web Push
user_idstringВаш id пользователя (≤ 512). Включает target.user_ids; должен совпадать с externalId контакта для стирания/экспорта и отписок
tagsstring≤ 50 тегов для target.tags
metadataobjectПроизвольные данные, ≤ 4 КБ
timezonestringИмя IANA
environmentsandbox | productionОкружение APNs токена
categorychrome | firefox | safari | edge | operaСемейство браузера для web-устройства (дашборд группирует по нему)
web_push_p256dh, web_push_authstringОбязательны для web (ключи PushSubscription в base64url)

Один токен — одно устройство: повторная регистрация под другим user_id переводит устройство новому пользователю (прежний перестаёт получать свои push). При выходе из аккаунта деактивируйте его:

bash
curl -X DELETE https://api.pushdata.ru/api/v1/public/devices \
  -H "Authorization: Public pk_…" -H "Content-Type: application/json" \
  -d '{ "token": "fcm-registration-token" }'

Управление устройствами секретным ключом: GET /api/v1/devices?user_id=&platform=&status=&page=&page_size= (постранично { data, total }, токены никогда не возвращаются), PUT /api/v1/devices/:id ({ "tags": [...] }), DELETE /api/v1/devices/:id, DELETE /api/v1/devices ({ "token": … }).

События вовлечённости

Сообщайте delivered, opened и clicked с устройства. Пара (notification_id, device_id) адресует доставку; оба id есть в payload push-уведомления (pushdata_notification_id, pushdata_device_id).

bash
curl -X POST https://api.pushdata.ru/api/v1/events \
  -H "Authorization: Public pk_…" -H "Content-Type: application/json" \
  -d '{ "type": "opened", "notification_id": "0192…", "device_id": "0192…" }'

Ответ 202 { "accepted": true }. Серверные интеграции могут использовать POST /api/v1/track с секретным ключом и delivery_log_id либо notification_id + device_token.

Формат ошибок

Каждая ошибка — { "error": { "code", "message", "details"? } } с HTTP-статусом.

СтатусcodeЗначение
400invalid_argumentНекорректное тело, target или id
401unauthorizedНет или неверный API-ключ
402payment_requiredЛимит тарифа исчерпан или подписка просрочена
403forbiddenПубличный ключ на секретной операции
404not_foundНеизвестный или чужой ресурс
409idempotency_conflict, app_inactiveКлюч повторён с другим телом; приложение деактивировано
411length_requiredТело без Content-Length (chunked) — API его не принимает
413payload_too_largeТело больше 1 МиБ — разбейте запрос
415unsupported_media_typeТело не application/json
422validation_errorПоле не прошло валидацию или не поддерживается
429rate_limitedПревышен лимит запросов (заголовки X-RateLimit-*)
500internal_errorВнутренняя ошибка сервера
503rate_limiter_unavailableХранилище лимитера недоступно — повторите через Retry-After