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

Контакты

Контакты (они же подписчики) — это люди, которые получают уведомления. Каждый контакт принадлежит одному приложению и идентифицируется вашим собственным externalId. Контактами управляют через REST (/api/v1/contacts, ниже) и GraphQL API (дашборд использует те же операции).

Как связаны контакты и устройства

Устройство, зарегистрированное с user_id: "user-123", принадлежит контакту с externalId = user-123 в том же приложении. Эта единственная связь определяет всё:

  • target.user_ids в REST-отправке доставляет на устройства этих контактов;
  • канальные отправки (email / SMS / MAX / in-app) берут адрес из контакта;
  • отписки (updateContactPreference) действуют на каждый канал, включая push;
  • eraseContact (право на забвение) и exportSubscriberData охватывают устройства контакта.

Используйте один и тот же идентификатор с обеих сторон.

Создание контакта

Дашборд

Откройте Приложения → Контакты → Новый контакт и заполните поля.

REST

POST /api/v1/contacts — идемпотентный upsert по external_id: первый вызов создаёт контакт (201), повторный — обновляет переданные поля (200); поля, которых нет в теле, не трогаются, metadata заменяется целиком. Поля: external_id, name, email, phone, max_user_id, locale, metadata.

bash
curl -X POST https://api.pushdata.ru/api/v1/contacts \
  -H "Authorization: ApiKey pd_ВАШ_СЕКРЕТНЫЙ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{"external_id":"user-123","email":"user@example.com","name":"Иван Петров","phone":"+79991234567","locale":"ru","metadata":{"plan":"pro"}}'

GET /api/v1/contacts/user-123 возвращает контакт, DELETE /api/v1/contacts/user-123 стирает его вместе с устройствами, настройками и inbox (то же, что eraseContact). Заявки из форм Tilda превращаются в контакты приёмником POST /api/v1/integrations/tilda (см. Интеграции); серверные SDK делают всё это методами upsertContact / getContact / deleteContact.

GraphQL

bash
curl -X POST https://api.pushdata.ru/api/graphql \
  -H "Authorization: ApiKey pd_ВАШ_СЕКРЕТНЫЙ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation($input: CreateContactInput!) { createContact(input: $input) { id externalId email } }",
    "variables": { "input": { "appId": "APP_ID", "externalId": "user-123", "email": "user@example.com", "name": "Иван Петров", "phone": "+79991234567", "locale": "ru" } }
  }'

Пара (appId, externalId) уникальна: создание уже существующего контакта возвращает ошибку 409 (conflict). Существующий контакт меняется через updateContact(id, input).

Поля контакта

ПолеТипОписание
externalIdstringId пользователя в вашей системе (обязателен, уникален в приложении)
namestringОтображаемое имя
emailstringEmail (нужен для канала Email)
phonestringТелефон (нужен для канала SMS); пробелы и дефисы допустимы, перед отправкой номер приводится к цифрам
maxUserIdstringId пользователя в мессенджере MAX (нужен для канала MAX); обычно заполняется сам, когда человек открывает бота по ссылке контакта (maxLink)
localestringПредпочитаемый язык; используются шаблоны с подходящим переводом
metadataobjectЛюбые дополнительные данные

Предпочтения (отписка)

graphql
mutation {
  updateContactPreference(input: { subscriberId: "CONTACT_ID", category: "marketing", channelType: EMAIL, enabled: false }) {
    id
  }
}

Отправка с category: "marketing" пропускает контакты, отключившие эту категорию для канала, на любом пути: API-отправки, отложенные отправки и SEND-шаги воркфлоу. Отправка без категории не фильтруется.

Право на забвение и экспорт данных

graphql
mutation { eraseContact(contactId: "CONTACT_ID") { contactDeleted devicesDeleted deliveryLogsScrubbed } }
query { exportSubscriberData(contactId: "CONTACT_ID") }

eraseContact доступен только владельцу и необратим: удаляет контакт, его устройства (в том числе связанные только через user_id), предпочтения и in-app сообщения, а журналы доставки и выполнения воркфлоу анонимизирует. exportSubscriberData возвращает всё, что хранится о субъекте, в JSON.

Контакты в воркфлоу

Передайте PushData-id контакта как subscriberId при запуске воркфлоу (в REST — POST /api/v1/workflows/:id/trigger с contact_external_id или contact_id, см. Сценарии):

graphql
mutation {
  triggerWorkflow(input: {
    workflowId: "019c9a99-..."
    subscriberId: "019c9359-..."
    payload: { orderId: "ORD-001" }
    idempotencyKey: "order-ORD-001-placed"
  }) {
    id
    status
  }
}

Воркер воркфлоу определяет получателя для каждого SEND-шага по типу канала: email для Email, phone для SMS, maxUserId для MAX, сам контакт для in-app и устройства контакта (по externalId) для push. idempotencyKey (необязателен, уникален в рамках воркфлоу) делает повторный запуск безопасным: возвращается уже начатый запуск вместо нового.