SingularityVPN Partner API · v1
https://api.singularityvpn.ru/api/v1
Partner API · Документация

Перепродажа VPN-ключей через один HTTP API

Один API для обоих тарифов ключей: свой баланс, своя цена за ГБ и списание сразу после каждой успешной операции. Мы старались сделать контракт простым и предсказуемым — одна и та же логика ошибок и биллинга на всех эндпоинтах, — чтобы интеграция заняла у вас часы, а не дни.

Базовый адрес https://api.singularityvpn.ru/api/v1
Формат JSON
Авторизация Bearer-токен

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

Каждый запрос должен нести заголовок Authorization с вашим персональным токеном. Посмотреть его можно в Telegram-боте, на панели партнёра, кнопка «Токен» — токен постоянный и меняется только по вашей команде.

Заголовок
Authorization: Bearer ВАШ_ТОКЕН

Токен один на всю организацию. Если нужно выдать сотрудникам ограниченный доступ именно к API (не к боту) — пока такой возможности нет, но напишите нам, если это для вас важно.

Набор доступных вам действий настроен индивидуально под аккаунт. Если какое-то действие ещё не включено, вызов вернёт FORBIDDEN (см. «Коды ошибок» ниже) — просто напишите нам, и мы его добавим.

Формат ответов

Результат операции по существу мы всегда кладём в поле error тела ответа, а не в HTTP-статус. HTTP-код, отличный от 200, сигнализирует только о транспортной или авторизационной проблеме — не о том, что пошло не так с самой операцией.

Успех — error: null, HTTP 200
{
  "error": null,
  "info": "KEY_EXPANDED",
  "charged": 150.0,
  "balance": 4200.5
}
Бизнес-ошибка — HTTP 200
{
  "error": "INSUFFICIENT_FUNDS",
  "info": "Not enough balance...",
  "required": 150.0,
  "available": 42.5
}

Проверяйте error первым делом, ещё до разбора остального ответа. А вот текст info — это просто человекочитаемое пояснение, он может меняться со временем, так что не стройте на нём логику как на коде ошибки.

Коды ошибок

Ошибки бывают двух независимых уровней: транспортные — это настоящий HTTP-код — и бизнес-ошибки, которые всегда приходят с HTTP 200 и видны в поле error.

HTTP-уровень

КодКогда
401 UNAUTHORIZEDЗаголовок Authorization отсутствует/не в формате Bearer …, либо токен не найден.
403 PARTNER_DISABLEDДоступ к API приостановлен для вашего аккаунта («Работа API» выключена).
403 RENT_OVERDUEПросрочена оплата аренды — доступ заблокирован до оплаты.
422Тело запроса не прошло валидацию (например, limit <= 0 или пропущено обязательное поле). Стандартный ответ FastAPI, форма отличается от бизнес-ошибок ниже.
500 INTERNAL_ERRORВнутренняя ошибка на нашей стороне. Детали не раскрываются в ответе — если повторяется, напишите нам.

Бизнес-уровень (HTTP 200, поле error)

КодКогда
FORBIDDENДействие не разрешено для вашего аккаунта. Список включённых действий настраивается индивидуально — напишите нам, чтобы включить нужное.
INSUFFICIENT_FUNDSНе хватает баланса + кредитного лимита. В ответе есть required и available.
GB_LIMIT_EXCEEDEDЗапрошенный объём превышает разовый лимит на операцию. В ответе есть requested и max.
SERVICE_UNAVAILABLEВысокоскоростной тариф временно не настроен на нашей стороне.
NOTHING_TO_RESETУ ключа нет накопленного трафика — сбрасывать нечего, списания не было.
INVALID_LIMITВ /key/expand новый лимит (limit) меньше или равен текущему лимиту ключа. В ответе есть current_gb и requested_gb.
(другое)Прочие коды — сообщение в info поясняет причину.

Сквозная ошибка апстрима

Есть и третья форма, отдельная от первых двух: если сам провайдер ключа отклонил операцию (например, ключ не найден), поле error приходит числом, а не строкой, а info всегда null:

{ "error": 500, "info": null }

Поэтому проверяйте error просто на null/отсутствие, а не на конкретный тип — строка это или число. Такая форма может встретиться у любого эндпоинта, который обращается к уже существующему ключу: info, expand, edit, renew и так далее.

Тарификация

Цены индивидуальны для вашего аккаунта — актуальные значения price_per_gb, price_fast и price_device всегда можно получить через /balance. Списание происходит только после успешного выполнения операции: если вызов завершается ошибкой, баланс не затрагивается.

ДействиеКлассический тарифВысокоскоростной
createlimit × months × price_per_gbprice_fast (фикс.)
expandдобавляемые ГБ × price_per_gb—
temp_expandдобавляемые ГБ × price_per_gb (без множителя на срок — временно)—
editlimit × months × price_per_gb—
renewтекущий лимит ключа × price_per_gb (читаем сами)price_fast (фикс.)
resetуже использованный трафик × price_per_gb (читаем сами)—
device / addcount × price_device
info / activation / deactivate / revoke / delete / get_trialбесплатно—

Перед любым списанием мы проверяем, что баланс вместе с кредитным лимитом покрывает стоимость операции. Если нет — сразу возвращаем INSUFFICIENT_FUNDS, даже не обращаясь к апстриму, так что никаких побочных эффектов не будет.

Свой домен для ссылок

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

Сама интеграция при этом не меняется — key/username из ответов API остаются теми же, меняется только домен, под которым клиент видит ссылку. Настройка занимает немного времени с нашей стороны (нужен ваш домен с уже настроенным DNS на наш сервер) и делается не через API, а вручную. Подробности и запуск — напишите вашему менеджеру в поддержке.

Механика работы ключей

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

Создание ключа

Оба тарифа на создании возвращают только идентификатор ключа — готовая ссылка на подписку API не отдаётся ни на одном из тарифов. Ссылка формируется нашей системой релинка: идентификатор подставляется в персональную ссылку на нашем домене (или на вашем собственном — см. «Свой домен для ссылок»). На классическом тарифе ответ дополнительно содержит username и number — про них подробнее в разделе «Перевыпуск» ниже.

Пробный ключ

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

Продление

Метод принимает только идентификатор ключа. Точка отсчёта новых 30 дней — текущая дата окончания ключа, а не момент вызова метода: при продлении за неделю до истечения новая дата окончания рассчитывается как «текущая дата окончания + 30 дней», а не «дата вызова + 30 дней». Уже оплаченный период таким образом никогда не укорачивается.

Обнуление счётчика потреблённого трафика — процесс, независимый от продления: оно происходит по собственному циклу, раз в 30 дней от даты создания ключа, а не от даты последнего продления. Поэтому при раннем продлении счётчик трафика не обнуляется сразу в момент оплаты — обнуление наступит в свою обычную дату, и к этому моменту продлённый период уже действует. Для тарифов на несколько месяцев вперёд это означает несколько обнулений в течение оплаченного периода — по одному в месяц, а не одно в конце.

Редактирование

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

Увеличение лимита трафика

Значение лимита в запросе — это итоговый лимит целиком, а не величина добавки. При текущем лимите 2 ГБ и переданном значении 5 итоговый лимит составит 5 ГБ, а спишется только разница — 3 ГБ. Значение, меньшее или равное текущему лимиту, не принимается (см. INVALID_LIMIT в кодах ошибок).

Временное увеличение

В отличие от обычного увеличения лимита, здесь add_gb — величина добавки сверх текущего лимита, а не новый итоговый лимит, и добавка временная: она снимается сама, без отдельного вызова с вашей стороны — либо по истечении заданного срока (hours/days), либо на ближайшем плановом сбросе трафика ключа, смотря что наступит раньше. Списание считается сразу за весь добавленный объём в момент вызова, независимо от того, сколько времени добавка фактически продержится.

Перевыпуск

Перевыпуск заменяет внутренний идентификатор ключа (id) на новый; номер ключа (number) и остальные параметры — лимит, срок действия, тариф — не изменяются. Действие предназначено для смены учётных данных (например, при компрометации существующей ссылки), а не для сброса ключа целиком. Если id утерян, ключ можно найти по number — обратитесь в поддержку.

Включение и выключение

Раздельные методы временной деактивации ключа и его повторной активации. Срок действия ключа при деактивации не приостанавливается — отсчёт до даты окончания продолжается как обычно; ограничивается только доступ клиента к использованию.

Сброс трафика

Обнуляет накопленную статистику потребления трафика по ключу, не изменяя лимит и срок действия. Списание рассчитывается исходя из объёма уже потреблённого трафика — оплачивается именно та часть, что обнуляется. При отсутствии накопленного расхода операция выполняется бесплатно (NOTHING_TO_RESET).

Удаление

Необратимо удаляет ключ. Восстановление удалённого ключа невозможно — только создание нового.

Ключи · классический тариф

Здесь вы явно задаёте объём трафика в ГБ и срок действия. И здесь, и во всех остальных разделах key — это id, который вы получаете при создании ключа. Важно: передавайте именно короткий id, а не полную ссылку-подписку — её эндпоинты не распознают.

Создать ключ
POST/key/create

Выпускает новый ключ с указанным объёмом трафика и сроком действия.

Параметры

ПолеТипОписание
limitintобязательноОбъём трафика в ГБ (1 ГБ = 1 073 741 824 байт), > 0.
monthsintобязательноСрок действия в месяцах, > 0.

Трафик на ключе сбрасывается на полный limit раз в месяц на всё время его действия — ключ на limit=100, months=3 даёт 100 ГБ в первый месяц, ещё 100 ГБ во второй и ещё 100 ГБ в третий (эквивалент созданию ключа на 1 месяц с двумя последующими /key/renew). Поэтому и стоимость считается как limit × months × price_per_gb, а не только за один сброс.

На одну операцию действует индивидуальный лимит ГБ (max_gb_per_purchase). Превысите его — получите GB_LIMIT_EXCEEDED с полями requested/max. Само значение лимита через API не отдаётся, уточняйте его у нас напрямую.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/create \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"limit": 100, "months": 1}'

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

{
  "error": null,
  "info": "KEY_CREATED",
  "id": "N9Wg8t58qNo_azod",
  "username": "Singularity-6676",
  "number": 6676,
  "expireAt": 1755590400,
  "charged": 150.0,
  "balance": 4350.0
}

Сохраните id — это и есть key, который понадобится для всех остальных операций с этим ключом.

Заодно советуем сохранить и number: в отличие от id, он не меняется при перевыпуске ключа — /key/revoke выдаёт новый id, а number/username остаются прежними. Если id всё же потеряется, напишите в поддержку с этим номером — мы найдём ключ по нему.

Выдать пробный ключ
POST/key/get_trial
Бесплатно

Выдаёт пробный ключ с фиксированными условиями: 2 ГБ без сброса трафика, срок действия — около 5 дней. Тело запроса не нужно.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/get_trial \
  -H "Authorization: Bearer ВАШ_ТОКЕН"

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

{
  "error": null,
  "info": "TRIAL_CREATED",
  "id": "Tr1al_9kZpQ2vw",
  "username": "Singularity-95",
  "number": 95,
  "expireAt": 1755158400
}

Как и у платного ключа, сохраните number — он переживает /key/revoke, в отличие от id.

Статус ключа
POST/key/info
Бесплатно

Отдаёт полную информацию о ключе: статус, трафик, срок действия, ссылку-подписку, подключённые устройства и служебные учётные данные протоколов. Доступен всегда, отдельное разрешение не нужно.

Параметры

ПолеТипОписание
keystringобязательноid ключа, полученный при создании.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/info \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"key": "N9Wg8t58qNo_azod"}'

Пример ответа (полный, с одним подключённым устройством)

{
  "error": null,
  "uuid": "fb087fad-e972-4910-94d3-09686663d7b0",
  "id": 194618,
  "shortUuid": "N9Wg8t58qNo_azod",
  "username": "Singularity-6676",
  "status": "ACTIVE",
  "trafficLimitBytes": 107374182400,
  "trafficLimitStrategy": "MONTH_ROLLING",
  "expireAt": "2026-08-19T00:00:00Z",
  "telegramId": null,
  "email": null,
  "description": null,
  "tag": null,
  "hwidDeviceLimit": null,
  "externalSquadUuid": "5519a60b-9b3f-4027-a313-ee94e2ba1fca",
  "trojanPassword": "uzMVSJgfYopp_cEkm3K6KGq2SvXt8eXd",
  "vlessUuid": "cf1d8b03-10e6-48b7-959e-06f35fbf6e5e",
  "ssPassword": "LWyh7R1kXR7XDfJuWKA84Ryh6vVSgea6",
  "lastTriggeredThreshold": 0,
  "subRevokedAt": null,
  "lastTrafficResetAt": null,
  "createdAt": "2026-08-24T08:34:38.870Z",
  "updatedAt": "2026-08-24T08:34:38.870Z",
  "subscriptionUrl": "https://singularityvpn.fun/N9Wg8t58qNo_azod",
  "activeInternalSquads": [
    { "uuid": "3d12d359-05e5-4e9d-b9b0-8a1b643d6244", "name": "Mobile Internet Nodes" },
    { "uuid": "fb518818-bd1b-4ca1-b801-ee8d6f75f284", "name": "Wi-Fi Nodes" }
  ],
  "userTraffic": {
    "usedTrafficBytes": 2147483648,
    "lifetimeUsedTrafficBytes": 2147483648,
    "onlineAt": "2026-08-24T09:10:02.000Z",
    "lastConnectedNodeUuid": "3d12d359-05e5-4e9d-b9b0-8a1b643d6244",
    "firstConnectedAt": "2026-08-20T10:15:00.000Z"
  },
  "devices": {
    "total": 1,
    "devices": [
      {
        "deviceModel": "iPhone 15 Pro",
        "hwid": "a1b2c3d4e5f6",
        "platform": "iOS",
        "osVersion": "17.5",
        "userAgent": "v2rayTun/1.5.2 (iOS)",
        "createdAt": "2026-08-20T10:15:00.000Z",
        "updatedAt": "2026-08-24T07:42:11.000Z"
      }
    ]
  }
}

Как ориентироваться в полях

ПолеЧто это
statusACTIVE / DISABLED (после deactivate) / LIMITED / EXPIRED.
trafficLimitBytes / trafficLimitStrategyЛимит трафика в байтах и стратегия его сброса (например, MONTH_ROLLING — сбрасывается раз в месяц, NO_RESET — не сбрасывается сам, только через /key/reset).
expireAtISO-строка (не unix-время, в отличие от create/renew/get_trial/create_fast — единственное расхождение в формате дат по всему API).
subscriptionUrlСсылка-подписка для клиентских приложений — то же самое, что нужно раздавать клиенту.
trojanPassword / vlessUuid / ssPasswordСырые учётные данные протоколов подключения (то, из чего собирается сама подписка). Обычному использованию не нужны — раздавайте клиенту subscriptionUrl, а не эти поля напрямую.
uuid / id / externalSquadUuid / activeInternalSquadsВнутренние технические идентификаторы. Не используются в других эндпоинтах — для операций с ключом нужен только shortUuid (= ваш key).
userTrafficИспользованный трафик (usedTrafficBytes обнуляется по trafficLimitStrategy или вручную через /key/reset, lifetimeUsedTrafficBytes — никогда).
devicestotal — сколько устройств сейчас подключено к ключу; devices[] — по одной записи на устройство, с моделью/платформой/датами подключения.
Увеличить лимит
POST/key/expand

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

Параметры

ПолеТипОписание
keystringобязательноid ключа.
limitintобязательноНовый лимит трафика в ГБ целиком (абсолютное значение, не сколько добавить), должен быть больше текущего лимита ключа.

Например: у ключа сейчас 2 ГБ, вы вызываете expand с limit: 5 — итоговый лимит станет 5 ГБ, а не 7. Спишется цена только за добавленные 3 ГБ. А если передать limit меньше или равный текущему лимиту, вернётся INVALID_LIMIT.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/expand \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"key": "N9Wg8t58qNo_azod", "limit": 50}'

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

{ "error": null, "info": "KEY_EXPANDED", "charged": 75.0, "balance": 4275.0 }
Изменить лимит и срок
POST/key/edit

В отличие от expand, задаёт и лимит, и срок как абсолютные значения — перезаписывает их, а не добавляет к текущим. При этом id ключа остаётся прежним.

Параметры

ПолеТипОписание
keystringобязательноid ключа.
limitintобязательноНовый лимит трафика в ГБ (абсолютное значение), > 0.
monthsintобязательноНовый срок действия в месяцах, > 0.

Стоимость считается так же, как за новый ключ такого же объёма и срока: limit × months × price_per_gb — просто id остаётся тем же.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/edit \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"key": "N9Wg8t58qNo_azod", "limit": 200, "months": 3}'

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

{ "error": null, "info": "KEY_EDITED", "charged": 900.0, "balance": 3375.0 }
Продлить срок действия
POST/key/renew

Продлевает ключ. Объём ГБ передавать не нужно: перед списанием мы сами смотрим текущий лимит ключа через /key/info и считаем стоимость по нему.

Параметры

ПолеТипОписание
keystringобязательноid ключа.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/renew \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"key": "N9Wg8t58qNo_azod"}'

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

{ "error": null, "info": "KEY_RENEWED", "expireAt": 1758268800, "charged": 150.0, "balance": 3225.0 }
Активировать ключ
POST/key/activation
Бесплатно

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

ПолеТипОписание
keystringобязательноid ключа.
{ "error": null, "info": "KEY_ALREADY_ACTIVE" }

Точный текст info зависит от исходного статуса ключа — например, будет KEY_ACTIVATED, если он реально был на паузе. Ориентируйтесь на error: null как на признак успеха, а не на конкретную строку в info.

Деактивировать ключ
POST/key/deactivate
Бесплатно

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

ПолеТипОписание
keystringобязательноid ключа.
{ "error": null, "info": "KEY_DEACTIVATED" }
Перевыпустить учётные данные
POST/key/revoke
Бесплатно

Название немного вводит в заблуждение — это не отзыв или удаление ключа, а перевыпуск его учётных данных. Старый id перестаёт работать сразу же, вместо него выдаётся новый.

ПолеТипОписание
keystringобязательноТекущий id ключа.

Обязательно сохраните NEW_KEY из ответа и обновите его у себя — старый id больше не сработает ни в одном запросе.

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

{ "error": null, "NEW_KEY": "aB3xQpLk92mZrTs1" }
Сбросить счётчик трафика
POST/key/reset

Обнуляет использованный трафик ключа. Перед сбросом мы смотрим, сколько фактически использовано, и списываем за этот объём — иначе он так и остался бы неоплаченным.

ПолеТипОписание
keystringобязательноid ключа.

Если у ключа использовано 0 байт, запрос отклоняется с NOTHING_TO_RESET и списания не происходит — поэтому и пометка «Платно*»: платит только тот, кому реально есть что списывать.

Пример ответа (если был трафик для списания)

{ "error": null, "info": "…", "charged": 37.5, "balance": 3187.5 }

Пример ответа (трафик не использован)

{ "error": "NOTHING_TO_RESET", "info": "Key has no used traffic to reset" }
Удалить ключ
POST/key/delete
Бесплатно

Удаляет ключ безвозвратно. После этого любой вызов /key/info по этому id будет возвращать ошибку.

ПолеТипОписание
keystringобязательноid ключа.
{ "error": null, "info": "KEY_DELETED" }
Временно увеличить лимит
POST/key/temp_expand

В отличие от expand, добавляет объём временно и сверх текущего лимита — add_gb здесь именно величина добавки, а не новый абсолютный лимит. Прибавка снимается автоматически сама, без обратного вызова с вашей стороны: по истечении заданного срока либо на ближайшем плановом сбросе трафика ключа — что наступит раньше.

Параметры

ПолеТипОписание
keystringобязательноid ключа.
add_gbintобязательноСколько ГБ временно добавить сверх текущего лимита (величина добавки, > 0).
hoursintодно из hours/daysНа сколько часов действует добавка, > 0.
daysintодно из hours/daysНа сколько дней действует добавка, > 0. Передавайте либо hours, либо days — не оба сразу и не ни одного.

Например: у ключа лимит 10 ГБ, вы вызываете temp_expand с add_gb: 5, days: 3 — на 3 дня лимит станет 15 ГБ, спишется цена за все добавленные 5 ГБ сразу. По истечении 3 дней (или раньше, если у ключа как раз наступит плановый сброс трафика) лимит сам вернётся к исходным 10 ГБ — вызывать что-либо для отката не нужно.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/temp_expand \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"key": "N9Wg8t58qNo_azod", "add_gb": 5, "days": 3}'

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

{ "error": null, "info": "KEY_TEMP_EXPANDED", "added_gb": 5, "original_limit_gb": 10, "current_limit_gb": 15, "duration_hours": 72, "expires_at": 1234567890, "charged": 4.0, "balance": 4271.0 }

Ключи · высокоскоростной тариф

Тариф для клиентов, которым важна скорость. Трафик здесь безлимитный, срок фиксированный — 1 месяц, поэтому и цена фиксированная за операцию (price_fast), а не за ГБ.

Создать ключ
POST/key/create_fast

Выпускает новый ключ высокоскоростного тарифа.

ПолеТипОписание
periodstringнеобязательноСейчас поддерживается только "1m" — значение по умолчанию.

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

{
  "error": null,
  "key": "MWI3OGJlZjg0MzhkNDEsMTc4NDQ5NjI5NQPTS8KWejU9",
  "username": "1b78bef8438d41",
  "expireAt": 1787088294,
  "charged": 300.0,
  "balance": 2887.5
}

Ссылку для клиента соберите сами по шаблону https://i.singularityvpn.ru/{key}, например https://i.singularityvpn.ru/MWI3OGJlZjg0MzhkNDEsMTc4NDQ5NjI5NQPTS8KWejU9. И отдельно сохраните username — он понадобится для продления.

Продлить ключ
POST/key/extend_fast

Продлевает высокоскоростной ключ ещё на один период — по той же цене, что и при создании.

ПолеТипОписание
usernamestringобязательноЗначение поля username, полученное при создании ключа.
periodstringнеобязательноСейчас только "1m".

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/key/extend_fast \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"username": "1b78bef8438d41"}'

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

{ "error": null, "status": "extended", "charged": 300.0, "balance": 2587.5 }

Устройства

К каждому ключу по умолчанию привязан лимит в 5 устройств. Через этот эндпойнт можно докупить клиенту дополнительные устройства сверх лимита — прибавка фиксируется для указанного ключа и списывается по вашей цене price_device.

Докупить устройство
POST/device/add

Увеличивает лимит устройств для указанного ключа на count сверх стандартных 5 и списывает price_device × count с вашего баланса.

ПолеТипОписание
keystringобязательноИдентификатор ключа, к которому привязывается докупка.
countintegerнеобязательноСколько устройств докупается за один вызов. По умолчанию — 1.

Пример запроса

curl -X POST https://api.singularityvpn.ru/api/v1/device/add \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"key": "ваш-идентификатор-ключа", "count": 1}'

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

{ "error": null, "charged": 10.0, "balance": 4329.0 }

Лимит действует в рамках текущей активной подписки клиента: докупленные устройства привязаны к одному ключу и учитываются, пока эта подписка активна. При завершении или непродлении подписки лимит возвращается к стандартным 5 устройствам — при следующей покупке докупку нужно оформить заново.

Баланс

Баланс и ваши тарифы
GET/balance
Бесплатно

Тело запроса не нужно — только заголовок авторизации. Удобно вызывать перед крупной операцией, чтобы заранее прикинуть, хватит ли средств.

Пример запроса

curl https://api.singularityvpn.ru/api/v1/balance \
  -H "Authorization: Bearer ВАШ_ТОКЕН"

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

{
  "balance": 2587.5,
  "credit_limit": 500.0,
  "price_per_gb": 1.5,
  "price_fast": 300.0,
  "price_device": 10.0
}

credit_limit показывает, насколько баланс может уйти в минус. Так что реально доступная сумма на операцию — это balance + credit_limit, а не просто balance.

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

Где взять токен?
В Telegram-боте, на вашей панели → кнопка «Токен». Токен постоянный и не меняется, пока вы сами его не перевыпустите.
Что значит "error": null?
Значит, всё прошло успешно. Любое другое значение — это код ошибки, подробнее в разделе «Коды ошибок» выше.
Чем revoke отличается от delete?
revoke не удаляет ключ, а перевыпускает его учётные данные: старый id перестаёт работать, вместо него приходит новый (NEW_KEY), которым нужно заменить сохранённую у клиента ссылку. А delete удаляет ключ безвозвратно.
Почему renew не принимает объём ГБ?
Потому что продление действует на уже установленный лимит ключа — мы сами читаем его перед списанием, так что передавать ГБ не нужно.
Как получить рабочую ссылку для высокоскоростного ключа?
/key/create_fast отдаёт поле key — ссылка для клиента собирается как https://i.singularityvpn.ru/{key}.
Как продлить высокоскоростной ключ, если у меня есть только ссылка?
Для продления нужен не key, а username — это отдельное поле в ответе /key/create_fast. Сохраняйте оба поля при создании: key пригодится для ссылки, username — для /key/extend_fast.
Как понять, включено ли у меня действие X?
Проще всего просто вызвать его: если оно ещё не разрешено, вернётся {"error": "FORBIDDEN"}. Набор доступных действий настроен индивидуально под ваш аккаунт — если нужно больше, напишите нам, и мы включим.
1 ГБ — это сколько байт?
Ровно 1 073 741 824 байта (2³⁰, гибибайт) — эта единица используется во всех полях limit и в расчёте стоимости.
Как работает докупка устройств?
Через /device/add вы увеличиваете лимит устройств для конкретного ключа сверх стандартных 5. Лимит действует, пока активна текущая подписка клиента — если она закончится или не продлится, лимит вернётся к базовым 5 устройствам.
Можно ли показывать клиентам ссылку на своём домене?
Да — и для классического, и для высокоскоростного тарифа можно подключить свой домен вместо нашего. Сама интеграция при этом не меняется, меняется только то, как выглядит ссылка у клиента. Подробнее — в разделе «Свой домен для ссылок» выше или у вашего менеджера в поддержке.
Что делать, если запрос завис и непонятно, прошла ли операция?
Отдельного механизма идемпотентности (защиты от повторной обработки) в API сейчас нет, поэтому слепо повторять платный запрос рискованно — можно случайно списать дважды. Прежде чем повторить, проверьте фактический результат через /key/info (для ключа) или /balance (по изменению баланса), и уже по нему решайте, нужен ли повтор.
Есть ли webhook-уведомления о событиях?
Нет, этот API — только запрос-ответ, мы ничего не шлём вам сами. Все данные вы получаете в ответ на свой вызов, актуальный статус ключа в любой момент — через /key/info.
Как сменить токен, если он мог утечь?
В Telegram-боте, на вашей панели → «Перевыпустить токен». Старый токен перестаёт работать сразу же, новый доступен там же.
Можно ли протестировать интеграцию, не тратя много денег?
Отдельного тестового режима нет — все операции реальные и списывают баланс. Но для проверки интеграции дешевле всего использовать /key/get_trial (бесплатно) или создать классический ключ с минимальным объёмом на 1 месяц.
SingularityVPN Partner API · v1 — вопросы и запрос дополнительных прав: обращайтесь напрямую к вашему менеджеру.