Soprano Open API
Подключите оптовый склад Telegram-аккаунтов к своему боту, сайту, CRM или приложению — с живыми остатками, автоматической выдачей и единым REST API.
Вы принимаете оплату от покупателей в своём интерфейсе. Open API списывает только финальную цену успешно выданного товара с вашего страхового депозита.
Актуальные товары, финальные цены и остатки одним запросом.
tdata, sessionjson, phonecode
Idempotency-Key делает повтор покупки безопасным.
Быстрый старт
До первого запроса — четыре коротких шага.
-
1
Получите ключ
Подайте заявку в кабинете Open API. После одобрения вам будет выдан персональный ключ.
-
2
Пополните депозит
Стоимость покупок списывается с вашего страхового депозита.
-
3
Проверьте подключение
Вызовите
GET /meи убедитесь, что ключ активен. -
4
Загрузите каталог
Получите товары через
GET /productsи покажите их в своём интерфейсе.
curl "https://soprano.host/openapi/v1/me" \
-H "X-API-Key: ВАШ_OPEN_API_KEY"
Авторизация
Каждый запрос должен передавать API-ключ в заголовке X-API-Key.
X-API-Key
Персональный ключ доступа из кабинета Open API.
Никогда не помещайте Open API key в браузерный JavaScript, мобильное приложение или публичный репозиторий. Запросы должны идти с вашего сервера.
Если для ключа включён IP allowlist, API принимает запросы только с разрешённых серверных IP-адресов.
Формат ответов
Все ответы приходят в JSON. Поле success позволяет быстро отличить успешный результат от ошибки.
{
"success": true
}
{
"success": false,
"error": "Описание ошибки"
}
/me
Проверяет ключ и возвращает состояние клиента, депозит и персональные лимиты.
https://soprano.host/openapi/v1/me{
"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
}
}
/products
Возвращает активные товары, вашу финальную цену и текущий доступный остаток.
idintegerID товара для покупки
namestringНазвание товара
descriptionstringОписание товара
pricenumberФинальная цена списания за один аккаунт
stockintegerТекущий доступный остаток
{
"success": true,
"products": [
{
"id": 24,
"name": "(+1) 🇺🇸 | 1+ year",
"description": "Quality Telegram accounts...",
"price": 1.5,
"stock": 34
}
]
}
/deposit
Возвращает баланс страхового депозита и последние движения.
{
"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"
}
]
}
/buy
Покупает один или несколько аккаунтов и списывает итоговую сумму с депозита.
Тело запроса
product_id *integerID товара из /products
quantityintegerКоличество. Для phonecode всегда 1
format *stringtdata · sessionjson · phonecode
Можно покупать несколько аккаунтов за запрос. Ответ содержит ZIP-архив в поле zip_base64.
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 "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"}'
{
"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
const fs = require('fs');
const zipBuffer = Buffer.from(response.zip_base64, 'base64');
fs.writeFileSync('account.zip', zipBuffer);
/buy · phonecode
Двухэтапная выдача: сначала API резервирует аккаунт и возвращает номер, затем ваш backend получает код короткими polling-запросами.
Шаг 1. Создать сессию
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"}'
{
"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. Получить код
/buy/phonecode/{session_id}/code?wait_ms=20000Если код ещё не пришёл, API вернёт HTTP 202. Это нормальное состояние — повторите запрос через 1–3 секунды.
{"success":false,"pending":true,"status":"waiting_for_code"}
{"success":true,"code":"12345","twoFaPassword":"password123"}
{"success":true,"email_required":true}
Сессия завершилась без кода; списание возвращается автоматически.
Используйте короткий long polling с wait_ms=20000 и общий таймер примерно на 180 секунд. Для phonecode количество всегда равно 1.
/stats
Возвращает продажи, списания, разбивку по форматам, последние покупки и временной ряд.
periodstringday, today, week, month, halfyear, year
fromdateДата начала: YYYY-MM-DD
todateДата окончания: YYYY-MM-DD
group_bystringday · month
curl "https://soprano.host/openapi/v1/stats?period=week&group_by=day" \
-H "X-API-Key: ВАШ_OPEN_API_KEY"
/purchases
Возвращает историю покупок с пагинацией и фильтрами.
limitintegerКоличество записей, максимум 100
offsetintegerСмещение для пагинации
product_idintegerФильтр по товару
formatstringtdata · sessionjson · phonecode
period / from / tostringФильтр по периоду или датам
curl "https://soprano.host/openapi/v1/purchases?limit=20&offset=0&period=week" \
-H "X-API-Key: ВАШ_OPEN_API_KEY"
Детальная покупка
/purchases/{group_id}{
"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"}
]
}
}
Пример на JavaScript
Минимальный серверный клиент и безопасная покупка tdata.
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
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');
}
Ошибки и HTTP-статусы
Всегда проверяйте одновременно HTTP-статус и поле success в JSON.
Запрос успешно выполнен
Phonecode ожидает код — продолжайте polling
Неверные параметры запроса
Не передан X-API-Key
Недостаточно страхового депозита
Ключ неверный, заблокирован, ожидает подтверждения или IP не разрешён
Сущность не найдена
Phonecode не получил код или сессия завершилась ошибкой
Нет товара, недостаточный остаток или Idempotency-Key ещё обрабатывается
Тело запроса слишком большое
Превышен rate limit; используйте Retry-After
Внутренняя ошибка API
Phonecode-служба временно занята
Rate limit
Персональный лимит запросов возвращается в GET /me. При превышении API отвечает 429 и сообщает время до повтора.
Retry-After: 12Повторите запрос не раньше чем через 12 секунд.
Безопасность
Короткие правила, которые защищают ключ, депозит и покупателей.
Не добавляйте ключ в исходный код и Git.
Не передавайте ключ в браузер или мобильный клиент.
Ограничьте ключ адресами своих серверов.
Один уникальный ключ на один заказ.
Декодируйте и сохраняйте ZIP после покупки.
group_id, product_id, format, charged
Чеклист интеграции
Перед запуском в прод проверьте каждый пункт.
Готовы к интеграции?
Подайте заявку в кабинете — после одобрения получите ключ и доступ к страховому депозиту.