SwiftShop API v2
API для каталога, покупок и управления цифровыми товарами. Здесь собраны примеры запросов, статусы заказов и правила доставки событий.
Быстрый старт
Ключ создаётся в основном боте: Информация → API V2. Ключ используется только на вашем сервере.
curl -X POST https://swift-shop.xyz/api/v2/market/accounts/buy \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acc-20260825-0001" \
-d '{
"category": "physical_new",
"registration_period": "days_7_14",
"country": "UA",
"quantity": 1
}'
import uuid
import requests
response = requests.post(
"https://swift-shop.xyz/api/v2/market/accounts/buy",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"category": "physical_new",
"registration_period": "days_7_14",
"country": "UA",
"quantity": 1,
},
timeout=20,
)
response.raise_for_status()
order = response.json()["data"]
const response = await fetch(
"https://swift-shop.xyz/api/v2/market/accounts/buy",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
category: "physical_new",
registration_period: "days_7_14",
country: "UA",
quantity: 1,
}),
},
);
if (!response.ok) throw new Error(`SwiftShop: ${response.status}`);
const { data: order } = await response.json();
Правила API
Эти правила действуют одинаково для всех production-маршрутов v2.
Bearer <api_key> во всех запросах. Ключ не передаётся в query string.
Обязательный Idempotency-Key для покупок, выгрузок и пополнений. TTL — 24 часа.
Строка с двумя знаками: "12.50". Валюта всегда возвращается отдельным полем.
ISO 8601 UTC: 2026-08-25T21:30:00Z. Unix time используется только в подписи webhook.
limit от 1 до 100 и opaque cursor. Offset в v2 не используется.
ID являются строками с префиксами: ord_, req_, evt_, dep_.
Успешный envelope
{
"ok": true,
"data": {},
"meta": { "next_cursor": null, "has_more": false },
"request_id": "req_01J66CT9Y7MZ3TQ5R8J2H4K6NP"
}
Одинаковый ключ и body возвращают первоначальный результат. Одинаковый ключ с другим body возвращает 409 idempotency_conflict.
Профиль
Баланс, количество покупок и приобретённых товаров владельца API-ключа.
idintegerID пользователя SwiftShopbalancemoneyДоступный баланс в USDTpurchasesintegerКоличество завершённых покупокphysical_accountsintegerАккаунты в разделе «Мои аккаунты»active_proxiesintegerДействующие Proxy{
"ok": true,
"data": {
"id": 123456789,
"balance": "58.20",
"purchases": 172,
"physical_accounts": 31,
"active_proxies": 4
},
"request_id": "req_01J66D1A9Y7V6M2Q0N4X8F3KBP"
}
Баланс и пополнения
Баланс, история транзакций и счета Send/xRocket используют общие денежные правила.
Создание счёта
providerenumsend или xrocketamountmoneyМинимум "0.10"В запросе amount — сумма к зачислению. В ответе amount содержит итог к оплате с комиссией провайдера, а credit_amount — сумму, которая поступит на баланс.
{
"ok": true,
"data": {
"id": "dep_01J66D...",
"provider": "send",
"status": "pending",
"amount": "10.30",
"credit_amount": "10.00",
"currency": "USDT",
"pay_url": "https://...",
"expires_at": "2026-08-25T22:15:00Z"
},
"request_id": "req_01J66D..."
}
Каталог и наличие аккаунтов
Клиент всегда получает категории, страны и цены из API. Жёстко прошивать ассортимент в интеграции не нужно.
Физический | Новый: days_7_14, month_1, month_3, month_6, year_1…year_13.
Физический | Тень СЗ: month_1, month_6, year_1…year_13.
Доступен только для physical_new.
Месячные и годовые подразделы возвращаются только при наличии аккаунтов.
{
"ok": true,
"data": {
"items": [{
"category": "physical_new",
"registration_period": "days_7_14",
"country": "UA",
"country_label": "Украина",
"quantity": 18,
"unit_price": "6.40",
"currency": "USDT"
}]
},
"request_id": "req_01J66E..."
}
Покупка аккаунта
Покупка асинхронная: после резервирования средств API подготавливает сессию, проверяет её и добавляет аккаунт пользователю.
categoryenumphysical_new или physical_shadowregistration_periodenumdays_7_14, month_1, month_3, month_6, year_1…year_13countrystringISO-код из /optionsquantityintegerОт 1 до 10, по умолчанию 1{
"category": "physical_new",
"registration_period": "days_7_14",
"country": "UA",
"quantity": 1
}
{
"ok": true,
"data": {
"id": "ord_01J66F...",
"product_type": "account",
"status": "processing",
"amount": "6.40",
"currency": "USDT",
"quantity": 1,
"result": null
},
"request_id": "req_01J66F..."
}
Сессия авторизована, телефон подтверждён через Telegram, device/language metadata сохранены, аккаунт принадлежит покупателю. Временный Proxy подготовки снимается в течение 2 часов.
Если товар не выдан, резерв освобождается или создаётся компенсирующий refund. Заказ никогда не остаётся списанным без результата или статуса needs_review.
Мои аккаунты
Поставщико-независимая модель аккаунта. Клиент работает с внутренним account_id, а не с номером телефона в URL.
statusenumready, checking, unavailablephonestringНормализованный номер в E.164has_two_fabooleanНаличие пароля 2FAdeviceobjectМодель, ОС, версия приложения и языкиcreated_atdatetimeВремя добавления в библиотеку{
"id": "1842",
"phone": "+380965551355",
"status": "ready",
"country": "UA",
"has_two_fa": true,
"device": {
"device_model": "Desktop",
"system_version": "Windows 11",
"app_version": "6.1.4 x64",
"lang_code": "en",
"system_lang_code": "en-us",
"lang_pack": "tdesktop"
},
"created_at": "2026-08-25T21:40:00Z"
}
Получение кода и выгрузка
Длительные действия представлены отдельными ресурсами. Это убирает зависимость от долгого HTTP-соединения.
Аккаунт онлайн и ожидает сообщение.
Код доступен через polling и webhook.
TTL 5 минут завершён без кода.
Аккаунт не удалось подготовить.
download_url одноразовый, живёт не более 10 минут, не логируется и доступен только владельцу аккаунта.
Telegram Stars
Логика такая же, как у Premium: сначала создайте котировку по username и количеству Stars, затем подтвердите покупку по quote_id.
minimummaximumquote ttl{
"username": "@recipient",
"quantity": 100
}
{
"ok": true,
"data": {
"id": "quote_01J66S...",
"username": "@recipient",
"quantity": 100,
"price": "1.80",
"currency": "USDT",
"expires_at": "2026-08-25T21:55:00Z"
},
"request_id": "req_01J66S..."
}
{
"quote_id": "quote_01J66S..."
}
{
"username": "@recipient",
"quantity": 100,
"delivered_at": "2026-08-25T21:48:00Z"
}
invalid_quantityquote_expiredprovider_wallet_unavailableProxy
Автоматическая выдача через API поставщика. Выделенные IPv4, общие IPv4 и IPv6 поддерживают HTTP(S) и SOCKS5 одновременно. Страны, сроки и лимиты загружаются из актуального каталога.
ipv4ipv4_sharedipv6quantity: 1..10GET /market/proxies/options возвращает versions с доступными periods, min_quantity, max_quantity, protocols и currency. Добавьте ?version=ipv4 для списка стран.
Для расчёта итоговой цены: GET /market/proxies/options?version=ipv4&country=RU&days=7&quantity=1. Поле quote.total_price — сумма в USDT с наценкой магазина. При покупке цена проверяется повторно. IPv4: 7, 14, 30, 60, 90 дней; IPv6 также 3 дня. Актуальные значения берите из каталога.
Покупка возвращает 202 и ID заказа. Проверяйте GET /orders/{order_id} или ожидайте webhook. Данные прокси появятся в result.items и GET /proxies. Передавайте Idempotency-Key при покупке. Старые protocol: socks5_ipv4/http_ipv4 принимаются как version: ipv4; прежний лимит 20 заменён лимитом поставщика.
При подтверждённом отказе поставщика средства возвращаются. Таймаут или неопределённый ответ переводит заказ в needs_review; автоматической повторной покупки нет. При частичной выдаче заказ завершается с выданными прокси и возвратом за недостающие; result содержит requested_count, delivered_count, refunded_amount.
{
"version": "ipv4",
"country": "DE",
"quantity": 2,
"days": 30
}
{
"items": [{
"id": "prx_01J66J...",
"protocol": "socks5",
"version": "ipv4",
"protocols": ["http", "https", "socks5"],
"country": "DE",
"host": "203.0.113.10",
"port": 1080,
"username": "swift_user",
"password": "secret",
"url": "socks5://swift_user:secret@203.0.113.10:1080",
"status": "active",
"expires_at": "2026-09-24T22:00:00Z"
}]
}
Паки
Каталог возвращает только активные позиции, фактический остаток лимита продаж и итоговую цену пользователя.
Ограниченный раздел.
sales_limit: 5Недавно добавленные паки.
sales_limit: 5Паки без лимита продаж.
sales_limit: nullМатериалы для NFT и Trade.
sales_limit: null{
"pack_id": 42,
"title": "Example pack",
"section": "new",
"access_url": "https://t.me/+single_use_invite",
"member_limit": 1
}
Списание, увеличение счётчика продаж и создание invite link выполняются как одна бизнес-операция. Повтор по тому же Idempotency-Key возвращает исходную ссылку.
Единая модель заказов
Все товары возвращают одинаковую оболочку заказа. Различается только объект result.
Запрос принят, средства резервируются.
Провайдер или worker выполняет выдачу.
Результат записан и доступен пользователю.
Выдача завершилась ошибкой.
Средства полностью возвращены.
Нужна ручная проверка без повторного списания.
pendingarrow_forwardprocessingarrow_forwardcompleted
или
failedarrow_forwardrefunded
completed и refunded не могут вернуться в processing. Исправления оформляются отдельной компенсирующей транзакцией с audit trail.
Webhooks
Webhook — основной способ получения результата. Polling остаётся доступным и использует те же ресурсы.
Разрешён только публичный HTTPS endpoint. localhost, credentials в URL, private/link-local адреса и redirect запрещены; DNS проверяется при сохранении и перед доставкой.
События
order.processingЗаказ перешёл в обработкуorder.completedТовар выданorder.failedВыдача завершилась ошибкойorder.refundedСредства возвращеныaccount.code.receivedПолучен Telegram-кодaccount.code.expiredЗапрос кода истёкaccount.code.failedПодготовка аккаунта не удаласьdeposit.completedПополнение зачисленоContent-Type: application/json
User-Agent: SwiftShop-Webhook/2.0
X-Swift-Event-ID: evt_01J66K...
X-Swift-Event: order.completed
X-Swift-Timestamp: 1787695200
X-Swift-Signature: v1=<hex_hmac_sha256>
signed_payload = timestamp + "." + raw_body
signature = HMAC_SHA256(secret, signed_payload)
# Требования получателя:
# 1. Окно timestamp ≤ 5 минут
# 2. Constant-time compare
# 3. Дедупликация по event_id
# 4. HTTP 2xx после фиксации
Retry schedule
Повторы выполняются при timeout, network error, 408, 409, 425, 429 и 5xx. Ответ 410 Gone отключает webhook. Redirect не используется.
{
"event_id": "evt_01J66K...",
"event": "order.completed",
"api_version": "2.0",
"created_at": "2026-08-25T22:00:00Z",
"data": {
"order": {
"id": "ord_01J66F...",
"product_type": "account",
"status": "completed",
"amount": "4.20",
"currency": "USDT"
}
}
}
Ошибки
Код ошибки предназначен для логики клиента, message — для журналов и отладки. Клиент не должен парсить текст message.
{
"ok": false,
"error": {
"code": "out_of_stock",
"message": "Товар по выбранным параметрам закончился",
"details": { "country": "UA" }
},
"request_id": "req_01J66M..."
}
invalid_jsonJSON не читается или тело не является объектомunauthorizedКлюч отсутствует, отозван или неверенinsufficient_balanceНедостаточно доступного баланса*_not_foundРесурс не найден или не принадлежит ключуnot_availableТовар закончился после получения каталогаidempotency_conflictКлюч уже использован с другим bodyquote_expiredСрок котировки истёкrequest_in_progressОперация с этим Idempotency-Key ещё выполняетсяinvalid_*Поле не прошло проверку формата или диапазонаrate_limitedПревышен лимит запросовprovider_unavailableВнешняя выдача временно недоступнаRate limits
Лимиты действуют для сочетания API-ключа и IP-адреса, отдельно для каждого маршрута. Ответы содержат состояние текущего окна.
120 / минПрофиль, списки, заказы и polling60 / минOptions и актуальные остатки20 / минАккаунты, Premium, Stars, Proxy и паки60 / минСоздание code-request20 / минПодготовка архивов сессии20 / минСоздание счетов5 / 5 минТест и ротация секретаX-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-ResetRetry-After