Soprano Open API Docs
API v1
О продукте В магазин
Официальная документация

Soprano Open API

Подключите оптовый склад Telegram-аккаунтов к своему боту, сайту, CRM или приложению — с живыми остатками, автоматической выдачей и единым REST API.

Базовый адрес https://soprano.host/openapi/v1
Протокол REST · JSON · HTTPS
i
Как устроена оплата

Вы принимаете оплату от покупателей в своём интерфейсе. Open API списывает только финальную цену успешно выданного товара с вашего страхового депозита.

01 Живой каталог

Актуальные товары, финальные цены и остатки одним запросом.

02 Три формата

tdata, sessionjson, phonecode

03 Защита списаний

Idempotency-Key делает повтор покупки безопасным.

01

Быстрый старт

До первого запроса — четыре коротких шага.

  1. 1
    Получите ключ

    Подайте заявку в кабинете Open API. После одобрения вам будет выдан персональный ключ.

  2. 2
    Пополните депозит

    Стоимость покупок списывается с вашего страхового депозита.

  3. 3
    Проверьте подключение

    Вызовите GET /me и убедитесь, что ключ активен.

  4. 4
    Загрузите каталог

    Получите товары через GET /products и покажите их в своём интерфейсе.

cURL
curl "https://soprano.host/openapi/v1/me" \
  -H "X-API-Key: ВАШ_OPEN_API_KEY"
02

Авторизация

Каждый запрос должен передавать API-ключ в заголовке X-API-Key.

обязательно X-API-Key

Персональный ключ доступа из кабинета Open API.

!
Только на backend

Никогда не помещайте Open API key в браузерный JavaScript, мобильное приложение или публичный репозиторий. Запросы должны идти с вашего сервера.

Если для ключа включён IP allowlist, API принимает запросы только с разрешённых серверных IP-адресов.

03

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

Все ответы приходят в JSON. Поле success позволяет быстро отличить успешный результат от ошибки.

Успех
{
  "success": true
}
Ошибка
{
  "success": false,
  "error": "Описание ошибки"
}
API REFERENCE
GET

/me

Проверяет ключ и возвращает состояние клиента, депозит и персональные лимиты.

GEThttps://soprano.host/openapi/v1/me
200 · application/json
{
  "success": true,
  "client": {
    "id": 1,
    "tg_id": 592719492,
    "username": "seller",
    "status": "active",
    "key_hint": "1234abcd",
    "deposit_balance": 25,
    "ip_allowlist_enabled": false,
    "ip_allowlist_count": 0,
    "created_at": "2026-07-07 15:00:00",
    "key_rotated_at": null
  },
  "limits": {
    "max_buy_quantity": 100,
    "rate_limit_per_minute": 120,
    "phonecode_timeout_seconds": 180
  }
}
GET

/products

Возвращает активные товары, вашу финальную цену и текущий доступный остаток.

ПолеТипОписание
idinteger

ID товара для покупки

namestring

Название товара

descriptionstring

Описание товара

pricenumber

Финальная цена списания за один аккаунт

stockinteger

Текущий доступный остаток

200 · application/json
{
  "success": true,
  "products": [
    {
      "id": 24,
      "name": "(+1) 🇺🇸 | 1+ year",
      "description": "Quality Telegram accounts...",
      "price": 1.5,
      "stock": 34
    }
  ]
}
GET

/deposit

Возвращает баланс страхового депозита и последние движения.

topupпополнение purchaseпокупка refundвозврат adjustmentкорректировка
200 · application/json
{
  "success": true,
  "deposit_balance": 22,
  "recent": [
    {
      "type": "purchase",
      "amount": -1.5,
      "balance_after": 22,
      "ref": "660753fc-8d76-461b-89c3-2b30c814dd2a",
      "created_at": "2026-07-07 18:25:27"
    }
  ]
}
POST

/buy

Покупает один или несколько аккаунтов и списывает итоговую сумму с депозита.

Тело запроса

ПараметрТипОписание
product_id *integer

ID товара из /products

quantityinteger

Количество. Для phonecode всегда 1

format *string

tdata · sessionjson · phonecode

ЗАЩИТА ПОКУПКИ

Idempotency-Key

Передавайте уникальный идентификатор вашего заказа при каждой покупке. Повтор запроса с тем же ключом не создаст вторую покупку.

Ваш заказ #93481
Idempotency-Key myshop_order_93481
Безопасный повтор Без второго списания
tdata & sessionjson

Можно покупать несколько аккаунтов за запрос. Ответ содержит ZIP-архив в поле zip_base64.

cURL
curl "https://soprano.host/openapi/v1/buy" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ВАШ_OPEN_API_KEY" \
  -H "Idempotency-Key: order_1001" \
  -d '{"product_id":24,"quantity":1,"format":"tdata"}'
cURL
curl "https://soprano.host/openapi/v1/buy" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ВАШ_OPEN_API_KEY" \
  -H "Idempotency-Key: order_1002" \
  -d '{"product_id":24,"quantity":1,"format":"sessionjson"}'
200 · application/json
{
  "success": true,
  "group_id": "1c783aa2-3ebe-418b-b5ca-42b838993a1b",
  "format": "tdata",
  "quantity": 1,
  "product": "CANADA | 1+ year",
  "price": 1.5,
  "charged": 1.5,
  "deposit_balance": 24,
  "zip_base64": "UEsDBBQAAAA..."
}

Сохранение ZIP на Node.js

JavaScript
const fs = require('fs');

const zipBuffer = Buffer.from(response.zip_base64, 'base64');
fs.writeFileSync('account.zip', zipBuffer);
POST

/buy · phonecode

Двухэтапная выдача: сначала API резервирует аккаунт и возвращает номер, затем ваш backend получает код короткими polling-запросами.

1POST /buyполучить номер
2session_idзапустить таймер
3GET /codepolling до 180 сек.
4code + 2FAвыдать клиенту

Шаг 1. Создать сессию

cURL
curl "https://soprano.host/openapi/v1/buy" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ВАШ_OPEN_API_KEY" \
  -H "Idempotency-Key: order_phone_1003" \
  -d '{"product_id":24,"format":"phonecode"}'
200 · application/json
{
  "success": true,
  "format": "phonecode",
  "session_id": "73591c87-7268-43f1-a437-6b661808098e",
  "group_id": "b4b46ba0-a25f-4e4c-9c16-95f35c6bd9c5",
  "phone": "+79990000000",
  "price": 1.5,
  "charged": 1.5,
  "deposit_balance": 23,
  "code_url": "/openapi/v1/buy/phonecode/73591c87-7268-43f1-a437-6b661808098e/code"
}

Шаг 2. Получить код

GET/buy/phonecode/{session_id}/code?wait_ms=20000

Если код ещё не пришёл, API вернёт HTTP 202. Это нормальное состояние — повторите запрос через 1–3 секунды.

202 {"success":false,"pending":true,"status":"waiting_for_code"}
200 {"success":true,"code":"12345","twoFaPassword":"password123"}
200 {"success":true,"email_required":true}
408

Сессия завершилась без кода; списание возвращается автоматически.

!
Не держите один запрос открытым три минуты

Используйте короткий long polling с wait_ms=20000 и общий таймер примерно на 180 секунд. Для phonecode количество всегда равно 1.

GET

/stats

Возвращает продажи, списания, разбивку по форматам, последние покупки и временной ряд.

ПараметрТипОписание
periodstring

day, today, week, month, halfyear, year

fromdate

Дата начала: YYYY-MM-DD

todate

Дата окончания: YYYY-MM-DD

group_bystring

day · month

cURL
curl "https://soprano.host/openapi/v1/stats?period=week&group_by=day" \
  -H "X-API-Key: ВАШ_OPEN_API_KEY"
GET

/purchases

Возвращает историю покупок с пагинацией и фильтрами.

ПараметрТипОписание
limitinteger

Количество записей, максимум 100

offsetinteger

Смещение для пагинации

product_idinteger

Фильтр по товару

formatstring

tdata · sessionjson · phonecode

period / from / tostring

Фильтр по периоду или датам

cURL
curl "https://soprano.host/openapi/v1/purchases?limit=20&offset=0&period=week" \
  -H "X-API-Key: ВАШ_OPEN_API_KEY"

Детальная покупка

GET/purchases/{group_id}
200 · application/json
{
  "success": true,
  "purchase": {
    "group_id": "660753fc-8d76-461b-89c3-2b30c814dd2a",
    "product_id": 24,
    "product": "CANADA | 1+ year",
    "format": "tdata",
    "quantity": 1,
    "charged": 1.5,
    "created_at": "2026-07-07 18:25:27",
    "last_item_at": "2026-07-07 18:25:27",
    "items": [
      {"item_no": 1, "price": 1.5, "created_at": "2026-07-07 18:25:27"}
    ]
  }
}
INTEGRATION GUIDE
05

Пример на JavaScript

Минимальный серверный клиент и безопасная покупка tdata.

JavaScript · Node.js 20+
const API_BASE = 'https://soprano.host';
const API_KEY = process.env.SOPRANO_API_KEY;

async function openApi(path, options = {}) {
  const response = await fetch(`${API_BASE}${path}`, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': API_KEY,
      ...(options.headers || {}),
    },
  });

  const data = await response.json();
  return { ok: response.ok, status: response.status, data };
}

async function buyTdata(productId, orderId) {
  const result = await openApi('/openapi/v1/buy', {
    method: 'POST',
    headers: { 'Idempotency-Key': orderId },
    body: JSON.stringify({
      product_id: productId,
      quantity: 1,
      format: 'tdata',
    }),
  });

  if (!result.ok || !result.data.success) {
    throw new Error(result.data.error || 'Buy failed');
  }

  return result.data;
}

Phonecode polling

JavaScript · Node.js 20+
async function buyPhonecode(productId, orderId) {
  const start = await openApi('/openapi/v1/buy', {
    method: 'POST',
    headers: { 'Idempotency-Key': orderId },
    body: JSON.stringify({ product_id: productId, format: 'phonecode' }),
  });

  if (!start.ok || !start.data.success) {
    throw new Error(start.data.error || 'Phonecode start failed');
  }

  const deadline = Date.now() + 180_000;

  while (Date.now() < deadline) {
    const poll = await openApi(
      `/openapi/v1/buy/phonecode/${start.data.session_id}/code?wait_ms=20000`
    );

    if (poll.status === 202 && poll.data.pending) {
      await new Promise(resolve => setTimeout(resolve, 1000));
      continue;
    }

    if (poll.ok && poll.data.success) {
      return { phone: start.data.phone, ...poll.data };
    }

    throw new Error(poll.data.error || 'Phonecode failed');
  }

  throw new Error('Phonecode timeout');
}
06

Ошибки и HTTP-статусы

Всегда проверяйте одновременно HTTP-статус и поле success в JSON.

200

Запрос успешно выполнен

202

Phonecode ожидает код — продолжайте polling

400

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

401

Не передан X-API-Key

402

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

403

Ключ неверный, заблокирован, ожидает подтверждения или IP не разрешён

404

Сущность не найдена

408

Phonecode не получил код или сессия завершилась ошибкой

409

Нет товара, недостаточный остаток или Idempotency-Key ещё обрабатывается

413

Тело запроса слишком большое

429

Превышен rate limit; используйте Retry-After

500

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

503

Phonecode-служба временно занята

07

Rate limit

Персональный лимит запросов возвращается в GET /me. При превышении API отвечает 429 и сообщает время до повтора.

Retry-After: 12

Повторите запрос не раньше чем через 12 секунд.

08

Безопасность

Короткие правила, которые защищают ключ, депозит и покупателей.

01Храните ключ в secret/env

Не добавляйте ключ в исходный код и Git.

02Вызывайте API с backend

Не передавайте ключ в браузер или мобильный клиент.

03Включите IP allowlist

Ограничьте ключ адресами своих серверов.

04Используйте Idempotency-Key

Один уникальный ключ на один заказ.

05Сохраняйте результат сразу

Декодируйте и сохраняйте ZIP после покупки.

06Логируйте заказы

group_id, product_id, format, charged

09

Чеклист интеграции

Перед запуском в прод проверьте каждый пункт.

SOPRANO OPEN API

Готовы к интеграции?

Подайте заявку в кабинете — после одобрения получите ключ и доступ к страховому депозиту.

Открыть кабинет
Скопировано