Для AI-агентов: markdown этой страницы — /docs-content/cowork/coupon-redeem.md индекс документации — /llms.txt

Погасить купон

POST /v1/cowork/coupon/redeem

Погашает купон Cowork/Code и выдаёт пользователю подаренный тариф на подаренный срок за счёт платформы, без списания с аккаунта Битрикс24.

Пользователь и аккаунт берутся из привязки ключа, параметров пути нет. Операция необратима: погашенный купон обратно не возвращается.

Поля запроса (body)

Поле Тип Обяз. Описание
code string да Купон в виде ПРЕФИКС-ТЕЛО-СУММА, от 1 до 64 символов. Регистр, пробелы и начертание дефисов приводятся к канонической форме на нашей стороне
action string нет Что выбрал пользователь в развилке: apply, extend, force или resume-and-apply. Значение берётся из decision проверки купона: при kind apply или extend — само это значение, при kind: choosekind выбранного элемента options. Поле опущено — считается apply, то есть поведение до появления развилки

Примеры

Ось авторизации одна: эндпоинт принимает только ключ десктопа Cowork/Code. Личный ключ и ключ приложения получают 403 INSUFFICIENT_SCOPE либо 403 COWORK_DESKTOP_KEY_REQUIRED.

curl — ключ десктопа Cowork/Code

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/cowork/coupon/redeem \
  -H "X-Api-Key: YOUR_COWORK_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code": "PRAKTIKUM-7HKM4TQZ2RVW-45C80C", "action": "force"}'

JavaScript — ключ десктопа Cowork/Code

javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/cowork/coupon/redeem', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_COWORK_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    code: 'PRAKTIKUM-7HKM4TQZ2RVW-45C80C',
    action: 'force',
  }),
})

if (!res.ok) {
  const { error } = await res.json()
  if (error.code === 'CONCURRENT_REDEMPTION') {
    // Единственный код, который повторяют автоматически.
  }
  console.error(error.code)
} else {
  const { data } = await res.json()
  if (data.accessGranted) {
    console.log(`${data.grantedTier} на ${data.grantedTermMonths} мес.`)
  } else {
    // Тариф выдан, доступа ещё нет — заявка ушла администратору аккаунта.
    console.log(`${data.grantedTier} активирован, ждём решения администратора`)
  }
}

Поля ответа

Поле Тип Описание
success boolean true при успешном погашении
data.grantedTier string Выданный тариф: PRO, MAX или ULTRA
data.grantedTermMonths number Срок, на который выдан тариф, в месяцах
data.accessGranted boolean false означает, что тариф выдан, а доступ к Cowork/Code администратор аккаунта ещё не открыл

Пример ответа

JSON
{
  "success": true,
  "data": {
    "grantedTier": "PRO",
    "grantedTermMonths": 3,
    "accessGranted": true
  }
}

Тариф выдан, но доступ к Cowork/Code на аккаунте ещё не открыт:

JSON
{
  "success": true,
  "data": {
    "grantedTier": "PRO",
    "grantedTermMonths": 3,
    "accessGranted": false
  }
}

Пример ответа при ошибке

409 — на месте пользователя уже стоит этот тариф:

JSON
{
  "success": false,
  "error": {
    "code": "COUPON_SEAT_ALREADY_ON_TIER",
    "message": "The coupon cannot be redeemed"
  }
}

Ошибки

Отказ по самому купону приходит статусом 409, а error.code называет причину. Текст в message у всех таких отказов один, разбирать его не нужно — решение принимается по коду.

HTTP Код Описание
400 INVALID_CODE В теле нет строкового поля code, оно пустое, длиннее 64 символов либо рядом лежит поле, которого тело не принимает
400 INVALID_ACTION Поле action есть, но его значение не входит в набор apply, extend, force, resume-and-apply
400 INVALID_JSON_BODY Тело передано, но не читается как JSON
401 MISSING_API_KEY Не передан заголовок X-Api-Key
401 INVALID_API_KEY Ключ не опознан: такой строки на платформе нет
403 INSUFFICIENT_SCOPE У ключа нет скоупа vibe:cowork
403 COWORK_DESKTOP_KEY_REQUIRED Ключ другого класса: личный ключ, ключ приложения, ключ места агента или проектный ключ деплоя
403 COUPON_FEATURE_DISABLED Купоны на аккаунте не включены
403 KEY_NOT_BOUND_TO_USER Ключ не привязан к пользователю аккаунта
403 WRITE_BLOCKED_READONLY_KEY Ключ выпущен только для чтения
409 COUPON_INVALID Купона не существует, он отозван, уже погашен, истёк, кампания закончилась, выбран её штучный потолок либо выбран лимит на пользователя или на аккаунт. Показывать одну формулировку — «Код не подходит»
409 COUPON_TOO_MANY_ATTEMPTS Десять неудач за час. Попытки закрыты на тридцать минут
409 COUPON_ALREADY_REDEEMED_BY_YOU Этот пользователь уже активировал этот купон
409 COUPON_NOT_ASSIGNED_TO_YOU Купон выписан на другой адрес электронной почты
409 COUPON_PORTAL_ACCESS_GATED Доступ к Cowork/Code на аккаунте закрыт
409 COUPON_TARIFF_NOT_ELIGIBLE Кампания ограничена списком тарифов Битрикс24, и тариф аккаунта в него не входит. Отказ терминальный: повторный вызов вернёт то же самое
409 COUPON_TARIFF_UNKNOWN Кампания ограничена списком тарифов Битрикс24, а тариф аккаунта платформа ещё не прочитала. Купон цел, попытка не засчитывается в лимит — повторите вызов позже
409 COUPON_SEAT_PAUSED Место приостановлено из-за нехватки средств. Подарок причину паузы не снимает — сначала пополнить баланс
409 COUPON_SEAT_CANCELLATION_SCHEDULED На месте назначена отмена, а погашение пришло без action: resume-and-apply. Когда тариф подарка не ниже действующего, это действие приходит в options проверки — отправьте его, чтобы снять отмену и применить подарок. Тариф подарка ниже действующего — действия не будет вовсе, отказ терминальный
409 COUPON_TIER_DOWNGRADE_BLOCKED Купон даёт тариф ниже действующего, и пользователь не выбрал force
409 COUPON_SEAT_ALREADY_ON_TIER Этот тариф на месте уже стоит, а погашение пришло без action: extend. Продление кампанией не разрешено либо срок покупки больше месяца — тогда проверка возвращает решение refuse, а не extend
409 COUPON_SEAT_PAID_TERM_ACTIVE У места идёт оплаченный отрезок без автосписания. Подарок перезаписал бы его, поэтому отказ терминальный — направляйте пользователя в поддержку
409 COUPON_SEAT_ALREADY_PAID_LONGER Место оплачено дальше, чем даёт купон, и пользователь не выбрал force
409 COUPON_SELF_PORTAL За порталом стоит сотрудник платформы с правом выдавать купоны — погашение на таком портале закрыто
409 COUPON_SEAT_IS_PAID На месте живое списание, и пользователь не выбрал force
409 COUPON_ACTION_NOT_AVAILABLE Присланное действие устарело: состояние места изменилось между проверкой и погашением. Купон цел и не потрачен
409 CONCURRENT_REDEMPTION За то же место конкурирует другая операция
429 RATE_LIMITED Суммарный лимит платформы — 10 запросов в минуту. Действующее для вашего ключа значение приходит в заголовке x-ratelimit-limit — оно ниже суммарного, поскольку лимит делится между репликами

Полный список общих ошибок API — Ошибки.

Известные особенности

Общий экран успеха на accessGranted: false — самый дорогой класс обращений в поддержку. Операция для пользователя выглядит удачной, а запустить Cowork/Code он не может, и это читается как поломка. Нужен отдельный экран — «Тариф активирован, заявка на доступ отправлена администратору», — а не общий «Готово».

Присланное действие — намерение, а не разрешение. Между проверкой и погашением место могло измениться: пользователь оплатил тариф в другой вкладке, администратор понизил место, сработала отмена. Решение пересчитывается по свежему состоянию, и если выбранного действия там уже нет, приходит COUPON_ACTION_NOT_AVAILABLE — перечитайте проверку и покажите те действия, что вернулись сейчас.

CONCURRENT_REDEMPTION повторяют, остальные отказы купона — никогда. Купон исправен, правила пройдены, подарок не израсходован: к моменту ответа купон уже вернулся в оборот. Делайте до трёх повторов с задержкой 300–800 мс и случайным разбросом — без разброса десятки клиентов повторят синхронно и воспроизведут ту же конкуренцию. Пользователю на это время показывают ожидание, а не ошибку. Автоматический повтор любого другого отказа купона выжигает счётчик неудач за секунды. Отдельно от них стоит 429 RATE_LIMITED — это не отказ купона, счётчик неудач он не трогает, и повтор после паузы уместен.

Действие force сжигает остаток оплаченного срока без возврата. Сколько именно суток сгорит, приходит в losesDays проверки купона и на клиенте не пересчитывается. Подпись кнопки обязана называть это число до нажатия — после погашения вернуть срок нечем.

Купон одноразов на пользователя, но не обязательно на всех. Часть купонов рассчитана на несколько активаций разными людьми. Сколько людей держит один и тот же купон, наружу не сообщается, и в тексте для пользователя это не упоминают.

Счётчик неудачных попыток общий с проверкой купона — пара, на которую он заведён, и условие обнуления описаны в проверке купона.

Суммарный лимит платформы у погашения — 10 запросов в минуту, у проверки — 20 запросов в минуту. Действующие для вашего ключа значения приходят в заголовке x-ratelimit-limit. Они ниже суммарных, поскольку лимиты делятся между репликами.

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

Смотрите также