К содержанию

EVIR API

API для выдачи спонсорских карточек в Telegram-боте

Выберите форматы, отправьте карточки и проверьте результат одной кнопкой. Ключ хранится на сервере вашего бота.

  • Base URL: https://evir.me/api/v1/integrations
  • JSON over HTTPS
  • Повтор delivery без двойного расчёта

Авторизация

Откройте карточку бота → «Подключение», создайте EVIR API key и сохраните его только на backend вашего бота.

Authorization: Bearer EVIR_API_KEY
Content-Type: application/json

В заголовке замените EVIR_API_KEY значением ключа. В командах Bash ниже $EVIR_API_KEY подставляет его из окружения. Чаты подключаются отдельно через @EvirBot и не используют этот ключ.

Запросите выбранные форматы

recipientId — точно Telegram from.id строкой: String(message.from.id) в Node.js или str(message.from_user.id) в Python. chat.id не подходит.

curl -X POST https://evir.me/api/v1/integrations/next \
  -H "Authorization: Bearer $EVIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"recipientId":"123456789","limit":3,"productTypes":["op","impression"],"supportsQualifiedImpressions":true}'

productTypes: 1–3 уникальных значения op, transition, impression в любом порядке. Для новых Показов передайте supportsQualifiedImpressions: true. Явный выбор возвращает только выбранные платные форматы, без legacy-рекомендаций; отключённые способы заработка он не включает. Без productTypes сохраняется прежний подбор. limit — 1–10, по умолчанию 1: карточек может быть меньше, наличие каждого выбранного формата не гарантируется.

Пример полного ответа next

Отправьте title, description и Telegram-кнопку ctaLabel → actionUrl. Дальше следуйте флагам requiresServedAck и requiresQualification.

{
  "data": {
    "assignments": [{
      "deliveryId": "AbCdEfGhIjKlMnOpQrStUvWxYz012345",
      "title": "Заголовок",
      "description": "Текст карточки",
      "ctaLabel": "Открыть",
      "actionUrl": "https://t.me/EvirBot/delivery?startapp=ia_AbCdEfGhIjKlMnOpQrStUvWxYz012345&mode=compact",
      "allowSkip": false,
      "topicCode": "technology",
      "targetType": "channel",
      "targetUsername": "example_channel",
      "expiresAt": "2026-09-04T12:05:00.000Z",
      "productType": "impression",
      "requiresServedAck": true,
      "requiresQualification": true,
      "billingMode": "qualified_action",
      "outcomeType": "membership"
    }]
  },
  "meta": { "requestId": "http-request-id" }
}

productType: recommendation | impression | transition | op; ctaKind: subscribe | start | open. Эти поля и requiresServedAck / requiresQualification могут отсутствовать у legacy-рекомендаций. assignments: [] — нормальный успешный ответ: продолжите обычный сценарий бота.

Подтвердите успешную отправку

Только при requiresServedAck: true и после успешного ответа Telegram. EVIR_DELIVERY_ID — deliveryId полученной карточки, EVIR_API_KEY — ключ того же бота.

curl -sS -X POST "https://evir.me/api/v1/integrations/deliveries/$EVIR_DELIVERY_ID/served" \
  -H "Authorization: Bearer $EVIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

data: { "served": true, "settled": false, "alreadySettled": false } — отправка подтверждена. Новые Показы оплачиваются после подписки или запуска бота. Повтор запроса не создаёт второго начисления.

Одна кнопка «Проверить»

Передайте 1–10 уникальных deliveryIds одного бота и получателя. Сервер проверяет весь список до изменения состояния; чужой или неизвестный ID отклоняет запрос целиком.

curl -sS -X POST https://evir.me/api/v1/integrations/deliveries/check \
  -H "Authorization: Bearer $EVIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"recipientId":"123456789","deliveryIds":["AbCdEfGhIjKlMnOpQrStUvWxYz012345"]}'

Используйте from.id нажавшего «Проверить»: он должен совпадать с recipientId из next. Проверка не подтверждает отправку автоматически. Показы ждут подтверждённой подписки или /start; переход — авторизованного открытия; ОП — подписки, подходящей заявки или запуска бота.

Результат общей проверки

completed

Результат подтверждён: completed и settled равны true.

already_member

Подписка уже была: completed: true, settled: false; нового начисления нет.

pending / visit_required

Действие пока не подтверждено / сначала откройте actionUrl. Оба флага false.

expired / unavailable

Срок незавершённой карточки истёк / карточка недоступна. Оба флага false.

{ "data": { "allCompleted": true, "remaining": 0, "results": [{ "deliveryId": "AbCdEfGhIjKlMnOpQrStUvWxYz012345", "productType": "impression", "status": "completed", "completed": true, "settled": true }] }, "meta": { "requestId": "http-request-id" } }

allCompleted означает, что все results[].completed равны true; remaining — число незавершённых карточек. Каждый результат содержит deliveryId, productType, status, completed, settled и необязательный proof. Статусы карточек приходят в успешном ответе; pending не означает HTTP 409.

Совместимость: одиночный qualify

Старый метод остаётся без изменений для requiresQualification: true. После открытия actionUrl передайте from.id пользователя, совпадающий с recipientId из next.

curl -sS -X POST "https://evir.me/api/v1/integrations/deliveries/$EVIR_DELIVERY_ID/qualify" \
  -H "Authorization: Bearer $EVIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"recipientId":"123456789"}'

Успешный data: { "qualified": true, "settled": true, "alreadySettled": false, "proof": "membership" }. proof: join_request означает подтверждённую заявку. Повтор served, check или qualify не создаёт второго начисления.

Ошибки и повторы

INVALID_REQUEST

400 · Проверьте запрос

recipientId — строка; limit — целое 1–10; productTypes — 1–3 уникальных формата; deliveryIds — 1–10 уникальных ID. Лишние поля отклоняются.

401

Ключ отсутствует, неверный или был заменён.

RECOMMENDATIONS_NOT_ALLOWED

403 · Подключите заработок

Бот подключён только для продвижения. Добавьте его в «Заработок».

404

deliveryId не найден или принадлежит другому боту/получателю. Для served и qualify: также истёк срок подтверждения; check возвращает expired в результате карточки.

DELIVERY_NOT_READY

409 · Предыдущая выдача

Нельзя сменить выбранные форматы, пока предыдущий набор не завершён. Повторите next позже, не отправляя карточки заново.

OP_VISIT_REQUIRED / OP_NOT_CONFIRMED / OP_ALREADY_MEMBER

409 · Только qualify

Нужно открыть ссылку, подписка ещё не подтверждена или уже существовала. В check эти состояния возвращаются в results, а не HTTP 409.

DELIVERY_CHECK_UNAVAILABLE

503 · Проверка недоступна

Повторите check для того же набора с задержкой. Не отправляйте карточки заново.

429 / 5xx

Учтите Retry-After и повторите запрос для того же recipient или delivery. Не создавайте новую отправку при неизвестном результате Telegram.

{ "error": { "code": "OP_NOT_CONFIRMED", "message": "The OP action is not confirmed yet.", "requestId": "http-request-id" } }

Диагностика ключа: ping

Необязательный POST /api/v1/integrations/ping с телом {} возвращает data: { "connected": true }. Первый успешный next сам активирует API.

Помощь

Частые вопросы

Все вопросы
Можно вызывать API из frontend?

Нет. EVIR API key должен оставаться на сервере вашего бота.

Какие форматы доступны через API?

ОП, переходы и показы можно включить сразу после подключения в «Способах заработка». Выберите любую непустую комбинацию в конструкторе интеграции или передайте productTypes в next. Это фильтр среди включённых форматов.

Можно подключить чат через API?

Нет. Чат подключается в разделе «Заработок» через @EvirBot; API key используется только сервером подключённого бота.

API-бот получает Premium-таргетинг?

Нет. Сервер издателя не может доказать Premium пользователя. Такой фильтр работает только там, где статус приходит в EVIR напрямую от Telegram.

Что делать, если assignments пустой?

Сначала проверьте, что в «Способах заработка» включён хотя бы один формат. Затем покажите обычный сценарий бота или настроенный empty state: пустой результат также возможен, когда подходящих предложений сейчас нет.

Можно повторить served?

Да. Повторите POST для того же delivery id. Уже рассчитанный результат не создаёт второе списание или начисление.