Ваш сайт или программа сама выдаёт подписки из нашего VPN. Нужен разработчик.

Ошибки

Формат отказа, все коды error_code и частые ошибки интеграции.

Отказ приходит с HTTP-статусом 4xx или 5xx и телом {"error": "текст", "error_code": "snake_case"}. Ветвитесь по error_code: он стабилен, а error написан для разработчика и может меняться. Пользователю показывайте своё сообщение.

Часть отказов несёт подробности: у validation_error (422) в details список полей с причинами, у insufficient_balance (402) могут быть required_minor и balance_minor.

Можно ли повторить запрос как есть, подсказывает столбец «Повтор» в таблице ниже. Денежную операцию повторяйте только с тем же custom_id. 429 rate_limited приходит с заголовком Retry-After: подождите столько секунд. 503 и 500 повторяйте с растущей паузой; у 503 upstream_unavailable есть Retry-After, раньше него не повторяйте. Повтор всегда с тем же custom_id: новый custom_id на каждой попытке при сбое поставщика это новая покупка на каждой попытке.

Коды ошибок

unauthorized401

Неверный или отсутствующий API-ключ

Проверьте заголовок Authorization: Bearer <ключ>. Ключ выпускается в кабинете.

Повтор: нет, нужны изменения

key_revoked401

Этот ключ отозван: выпущен новый

Возьмите действующий ключ в кабинете и подставьте его во все свои скрипты. Отозванный ключ не заработает снова.

Повтор: нет, нужны изменения

api_disabled403

Доступ к API для этого аккаунта закрыт

Напишите в поддержку площадки.

Повтор: нет, нужны изменения

key_read_only403

Этот ключ только для чтения

Для покупок, продлений и других изменений возьмите полный ключ. Ключ для чтения принимают только GET-запросы.

Повтор: нет, нужны изменения

ip_not_allowed403

Адрес запроса не входит в список разрешённых

Добавьте адрес сервера в кабинете (раздел «Ключ и вебхук», «Разрешённые адреса») или вызывайте API с разрешённого сервера. Адрес, с которого пришёл запрос, указан в тексте ошибки.

Повтор: нет, нужны изменения

partner_blocked403

Аккаунт партнёра заблокирован

Напишите в поддержку площадки.

Повтор: нет, нужны изменения

forbidden403

Объект принадлежит другому аккаунту

Проверьте идентификатор: бот или подписка не ваши.

Повтор: нет, нужны изменения

trial_disabled403

Пробный период выключен в настройках партнёра

Включите пробный период в кабинете, раздел «Маркетинг».

Повтор: нет, нужны изменения

trial_channel_required403

Пробный период у этого бота только подписчикам канала

Партнёр включил «Пробник только подписчикам канала». Попросите пользователя подписаться на каналы из поля channels и повторите запрос. Пользователю без telegram_id пробник этого бота недоступен.

Повтор: да, тот же запрос

not_found404

Объект не найден

Проверьте идентификатор.

Повтор: нет, нужны изменения

plan_not_found404

Тариф не найден или недоступен

Возьмите plan_uuid из GET /plans.

Повтор: нет, нужны изменения

subscription_not_found404

Подписка не найдена

Проверьте subscription_id. Чужие подписки тоже отвечают этим кодом.

Повтор: нет, нужны изменения

operation_not_found404

Операция с таким custom_id не найдена

Запрос с этим custom_id до нас не дошёл: его можно отправить снова тем же custom_id.

Повтор: нет, нужны изменения

deposit_not_found404

Пополнение не найдено

Проверьте custom_id пополнения.

Повтор: нет, нужны изменения

device_not_found404

Устройство не найдено

Список устройств: GET /subscriptions/{id}/devices.

Повтор: нет, нужны изменения

device_block_not_found404

Отключённое устройство не найдено

Список отключённых: GET /subscriptions/{id}/devices/blocked.

Повтор: нет, нужны изменения

trial_plan_missing404

Пробный тариф временно недоступен

Повторите позже или продайте платный тариф.

Повтор: да, тот же запрос

insufficient_balance402

Недостаточно средств на депозите

Пополните депозит: POST /deposit или кабинет. В ответе есть required_minor и balance_minor.

Повтор: нет, нужны изменения

max_charge_exceeded409

Цена операции выше max_charge_minor

Цена изменилась с момента расчёта. Перечитайте цену (GET /plans, renew-quote, upgrade-quote) и повторите с новым custom_id. В ответе есть charge_minor и max_charge_minor. Деньги не списаны.

Повтор: нет, нужны изменения

custom_id_conflict409

Этот custom_id уже использован с другими параметрами

Для новой операции возьмите новый custom_id.

Повтор: нет, нужны изменения

operation_in_progress409

Операция с этим custom_id ещё выполняется

Повторите тот же запрос через секунду: вернётся результат первой попытки.

Повтор: да, тот же запрос

subscription_state409

Операция не подходит к текущему состоянию подписки

Проверьте статус: GET /subscriptions/{id}.

Повтор: нет, нужны изменения

unsupported_for_product409

Это действие не подходит к этому виду подписки

Бессрочную подписку («Навсегда») не продлевают, не замораживают и не переводят на другой тариф, трафик и устройства к ней докупаются через POST /subscriptions/{id}/addons. Подписке на срок докупки этого вида недоступны, трафик ей докупается через POST /subscriptions/{id}/traffic.

Повтор: нет, нужны изменения

addon_unavailable409

Эту докупку сейчас нельзя оформить

Докупки есть только у действующей платной бессрочной подписки, не у пробной. Проверьте подписку: GET /subscriptions/{id}.

Повтор: нет, нужны изменения

subscription_frozen409

Подписка заморожена

Сначала разморозьте: POST /subscriptions/{id}/unfreeze.

Повтор: нет, нужны изменения

subscription_expired409

Подписка истекла

Продлите подписку, после этого операция станет доступна.

Повтор: нет, нужны изменения

trial_already_used409

Этот пользователь уже получал пробный период

Пробный период выдаётся один раз на external_user_id.

Повтор: нет, нужны изменения

trial_not_renewable409

Пробную подписку нельзя продлить

Купите платный тариф: POST /subscriptions или апгрейд.

Повтор: нет, нужны изменения

trial_not_freezable409

Пробную подписку нельзя заморозить

Заморозка доступна только платным подпискам.

Повтор: нет, нужны изменения

trial_no_traffic409

К пробной подписке нельзя докупить трафик

Пакеты трафика доступны только платным подпискам. Купите тариф: POST /subscriptions или апгрейд.

Повтор: нет, нужны изменения

special_plan_used409

Спецтариф этому пользователю уже выдавался

Выберите обычный тариф.

Повтор: нет, нужны изменения

external_user_conflict409

telegram_id или external_user_id уже привязан к другому пользователю

Используйте тот external_user_id, под которым этот Telegram уже заведён: его видно в GET /clients?telegram_id=…. Если ваш external_user_id уже занят другим человеком, двух клиентов API не склеивает: напишите в поддержку.

Повтор: нет, нужны изменения

webhook_not_configured409

Адрес вебхука не задан

Сохраните URL: PUT /webhook.

Повтор: нет, нужны изменения

too_many_open_deposits409

Слишком много неоплаченных пополнений

Оплатите или дождитесь истечения открытых счетов.

Повтор: да, тот же запрос

validation_error422

Неверные параметры запроса

Смотрите details: там поле и причина.

Повтор: нет, нужны изменения

upstream_rejected422

Поставщик VPN отклонил запрос

Проверьте параметры. Если всё верно, напишите в поддержку.

Повтор: нет, нужны изменения

rate_limited429

Слишком много запросов

Подождите Retry-After секунд. Лимит: 60 запросов в минуту на ключ.

Повтор: да, тот же запрос

upstream_unavailable503

Поставщик VPN временно недоступен

Повторите через минуту с тем же custom_id: двойного списания не будет.

Повтор: да, тот же запрос

provider_unavailable503

Платёжный способ временно недоступен

Выберите другой способ из GET /deposit/providers.

Повтор: да, тот же запрос

maintenance503

API на обслуживании

Повторите через несколько минут.

Повтор: да, тот же запрос

internal_error500

Внутренняя ошибка

Повторите с тем же custom_id. Если повторяется, напишите в поддержку.

Повтор: да, тот же запрос

Частые ошибки интеграции

custom_id это ваш ключ идемпотентности

Придумываете его вы. Ретрай упавшего запроса с тем же custom_id безопасен, новая операция требует новый custom_id. Один custom_id на все типы операций: повторно использовать его для другого действия нельзя.

Проверяйте депозит до продажи

GET /balance перед оформлением у себя: 402 после того, как покупатель у вас уже заплатил, оставляет его без подписки. Держите запас и подписку на deposit.credited.

Ссылка подписки меняется только по вашему вызову

Продление и апгрейд не выдают новую subscription_url: отдайте её один раз и не просите пользователя переустанавливать конфиг. Новую выдаёт только rotate-link, после него старая ссылка перестаёт работать.

Не продлевайте замороженную

Срок замороженной подписки стоит на месте, купленные дни сгорели бы незаметно. API отвечает 409 subscription_frozen: сначала unfreeze.

Считайте в центах

Складывайте *_minor, показывайте *_usd. Арифметика во float даёт 0.30000000000000004 и расхождение в цент с вашим биллингом.

Вебхук не единственный источник

Доставка может опоздать или не дойти. Перед действием по событию перечитайте GET /subscriptions/{id}: там актуальный статус и end_date.

Не показывайте пользователю ошибки API дословно

Поле error написано для интегратора. Переведите error_code в своё сообщение и решите сами, повторять ли запрос (столбец «повтор» в таблице кодов).

Собираем анонимную аналитику посещений. Подробнее