BuyCrypt
Разработчикам ботов

Подключите своего торгового бота. Тот же Binance API.

Если ваш бот уже работает с Binance USD-M Futures, просто смените один base URL — и вы в эфире на BuyCrypt. Наши пользователи находят бота в лидерборде, тестируют его на бесплатном демо-счёте $1,000 и переходят на реальные ключи, когда убеждаются в результате.

Никакого переписывания кода. Никаких биржевых специфических костылей. Та же подпись HMAC-SHA256, тот же WebSocket user-data stream, те же типы ордеров — обёрнуты поверх нашего демо-движка, чтобы пользователи могли сравнивать ботов, не рискуя реальным капиталом.

Почему BuyCrypt

Демо-дистрибуция для торговых ботов

Бесплатное демо $1,000 для каждого

Каждый подписчик получает собственный демо-счёт с виртуальным балансом $1,000. Ваш бот торгует на нём. Пользователи видят PnL в реальном времени, просадку, процент прибыльных сделок. Никакого риска для реального капитала — и никаких затрат на привлечение с вашей стороны.

Видимость в лидерборде

Демо-счёт вашего бота отображается в публичном лидерборде со значком 🤖 БОТ. Пользователи видят рейтинг PnL среди реальных трейдеров. Нажимают на строку, жмут «Подключить» — мгновенная подписка.

Нулевой рефакторинг кода

Если ваш бот использует любой Binance Futures SDK (binance-connector-python, python-binance, CCXT и др.), укажите его base_url на https://api.buycrypt.com/fapi. HMAC, recvWindow, типы ордеров — идентичны.

Ключи через вебхук

Когда пользователь подписывается, мы POST-им свежесозданный API key + secret на ваш вебхук — с HMAC-подписью, с повторными попытками при сбое (экспоненциальный бэкофф), с dead-letter для восстановления. Вам не нужно запрашивать учётные данные у пользователя.

Путь пользователя

Как пользователи находят и подключают вашего бота

1

Открытие

Пользователь открывает лидерборд. Аккаунт вашего бота отображается с чипом 🤖 БОТ рядом с именем и счётчиком подписчиков. Нажимает на строку.

2

Тест на демо

На странице профиля бота видит «Подключить к демо-счёту». Один тап создаёт новое демо $1,000 и ваш бот начинает торговать на нём.

3

Наблюдение и решение

Пользователь наблюдает, как бот торгует на его демо дни или недели. PnL, позиции, процент прибыльных сделок — всё в реальном времени в приложении. Если нравится — добавляет реальный Binance API-ключ прямо в BuyCrypt, чтобы перейти с демо на продакшн.

4

Переход на реальное

Пользователь добавляет свой реальный Binance API-ключ в BuyCrypt. Мы передаём его на ваш вебхук тем же способом, что и демо-ключ — тот же ивент subscription.created, только уже с боевыми кредами. Одна интеграция покрывает и демо, и live-флоу.

Онбординг разработчика

Как добавить своего бота в BuyCrypt

1

Регистрация

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

2

Торгуйте на демо через API

Сгенерируйте API-ключи прямо в мобильном приложении BuyCrypt: My Profile → API keys → нажмите на демо-счёт → Generate. Вы получите свежие apiKey + apiSecret — показываются один раз, скопируйте их в бот. Дальше направьте свой существующий Binance USD-M Futures-бот на https://api.buycrypt.com/fapi — он заработает без правок: тот же HMAC, те же эндпоинты, те же типы ордеров.

3

Аккаунт автоматически помечается как бот

Как только мы видим, что на вашем демо идёт API-трейдинг, аккаунт автоматически помечается как бот. Ваш демо появляется в лидерборде с бейджем 🤖 БОТ и публичным профилем — другие пользователи могут найти его и подписаться.

4

(Опционально) Принимайте подписчиков через вебхук

Когда готовы принимать подписчиков — добавьте webhook URL в настройках бот-профиля. Каждый раз, когда пользователь подписывается — на демо или с реальными Binance-ключами — мы шлём POST-ивент subscription.created с API-ключом и секретом для счёта этого пользователя. Сохраняйте (userId, apiKey, apiSecret) и начинайте торговать от его имени.

Drop-in

Ваш существующий Binance Futures бот без переписывания

Большинство Binance Futures SDK принимают кастомный base URL. Вот всё изменение, которое нужно типичному Python-боту:

# before — trading on real Binance
from binance.um_futures import UMFutures
client = UMFutures(key=API_KEY, secret=API_SECRET)

# after — trading on a BuyCrypt user's demo
from binance.um_futures import UMFutures
client = UMFutures(
    key=API_KEY,
    secret=API_SECRET,
    base_url="https://api.buycrypt.com/fapi",   # <- the only line that changes
)

# everything below is identical to your existing code
client.new_order(symbol="BTCUSDT", side="BUY", type="MARKET", quantity=0.01)
client.account()
client.cancel_open_orders(symbol="BTCUSDT")

CCXT, python-binance, Go's go-binance, JS node-binance-api — все работают одинаково. Боты на чистом requests.get(...).headers["X-MBX-APIKEY"] = key тоже работают: правило подписи HMAC побайтно идентично.

Вебхук

Как мы доставляем API-ключи в вашу систему

Когда пользователь BuyCrypt подписывается на вашего бота, мы генерируем пару API key + secret на стороне сервера и отправляем их POST-запросом на ваш зарегистрированный вебхук-URL. Secret никогда не передаётся пользователю — он идёт только вам, по HTTPS, с подписью.

TL;DR: sign up → tap «Generate API key» on your demo → generate a webhook secret → run one Python script → admin approves. ~5 minutes.

Step 1 — Sign up

Open buycrypt.com/terminal (or the mobile app). Sign in via Google or phone. A $1,000 USDT demo account is created automatically — that's the sandbox your bot will trade on.

Step 2 — Generate your trading API key (in the app)

In the app: Profile → API Keys → tap your demo account → «Bot API keys» → Generate. A dialog shows the apiKey + apiSecret once — copy both, you can't recover the secret afterwards.

# what you'll save
API_KEY    = "3fc370a4ac94b9aa756e2a97842dc04c"
API_SECRET = "3WJ86kV_VQzLWaED3hSRlY9R6wQHh_f3UEZ_q-CrwRU"

Same shape as Binance — your existing USD-M Futures bot library reads it as a regular Binance key with base URL https://api.buycrypt.com/fapi.

Step 3 — Generate your webhook signing secret

A second secret, separate from API_SECRET. We use it to sign the events we POST to your webhook URL — so you can verify the request really came from us. You generate it on your side; we encrypt-store it but never reveal back:

# any of these works — pick one. Save the output.
$ openssl rand -hex 32                          # macOS / Linux
$ python3 -c "import secrets; print(secrets.token_hex(32))"   # cross-platform

# sample output
8a31c2f4d5e6789abc01234567890def8a31c2f4d5e6789abc01234567890def

Step 4 — Register the bot (one signed POST)

Drop your three secrets into one signed POST. Save this as register_bot.py and run it once. Works on any OS with Python 3.10+ and pip install requests:

import hmac, hashlib, time, urllib.parse, requests

# ─── fill these in from steps 2 and 3 ─────────────────────
API_KEY        = "3fc370a4ac94b9aa756e2a97842dc04c"
API_SECRET     = "3WJ86kV_VQzLWaED3hSRlY9R6wQHh_f3UEZ_q-CrwRU"
WEBHOOK_SECRET = "8a31c2f4d5e6789abc01234567890def8a31c2f4d5e6789abc01234567890def"

SLUG         = "alpha-trader"                                # lowercase, [a-z0-9-], unique
DISPLAY_NAME = "Alpha Trader"                                # shown to users in the bot list
WEBHOOK_URL  = "https://your-bot.example.com/buycrypt/hook"   # MUST be HTTPS, public
# ──────────────────────────────────────────────────────────

params = {
    "slug":            SLUG,
    "displayName":     DISPLAY_NAME,
    "webhookUrl":      WEBHOOK_URL,
    "webhookSecret":   WEBHOOK_SECRET,
    "defaultLeverage": 10,
    "timestamp":       int(time.time() * 1000),
}
qs  = urllib.parse.urlencode(params)
sig = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()

r = requests.post(
    "https://api.buycrypt.com/fapi/v1/bot/profiles",
    headers={
        "X-MBX-APIKEY":   API_KEY,
        "Content-Type":  "application/x-www-form-urlencoded",
    },
    data=qs + f"&signature={sig}",
)
print(r.status_code, r.json())

Notice no demoKeyPairId — your API_KEY already points to the demo it was generated for. Need to register against a different demo? Generate a separate API key for it (step 2 again).

Expected output:

201 {
  "botId": 42,
  "slug": "alpha-trader",
  "status": "PENDING_REVIEW",
  "webhookUrl": "https://your-bot.example.com/buycrypt/hook",
  "webhookStatus": "ACTIVE",
  "webhookSecretAutoGenerated": false
}

Common errors:

{"code":-2010, "msg":"Slug already in use."}                # pick another slug
{"code":-1102, "msg":"webhookSecret must be at least 32..."}  # too short — use 32+ chars
{"code":-1022, "msg":"Signature for this request is not valid."}  # API_SECRET wrong, or params order changed after signing
{"code":-1003, "msg":"Bot registration rate limit: 1 per hour..."}  # wait it out

Step 5 — Wait for approve, then receive events

Bot lands in PENDING_REVIEW. Our admin sees your request immediately and approves it. To check status anytime:

import hmac, hashlib, time, urllib.parse, requests

API_KEY    = "3fc370a4..."
API_SECRET = "3WJ86kV..."

qs  = urllib.parse.urlencode({"timestamp": int(time.time() * 1000)})
sig = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
r = requests.get(
    f"https://api.buycrypt.com/fapi/v1/bot/profiles?{qs}&signature={sig}",
    headers={"X-MBX-APIKEY": API_KEY},
)
print(r.json())   # [{"botId":42, "status":"ACTIVE", ...}] when approved

Once "status":"ACTIVE": every time a user subscribes we POST to your webhookUrl with the per-subscriber API key your bot will trade with. The events shape and a copy-paste signature-verification snippet are right below this section.

Lost your webhook secret? Pick a new one and rotate (same signing pattern as registration):

params = {
    "webhookSecret": NEW_SECRET,                     # or omit to get backend-generated
    "timestamp": int(time.time() * 1000),
}
qs  = urllib.parse.urlencode(params)
sig = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
requests.post(
    "https://api.buycrypt.com/fapi/v1/bot/profiles/42/webhook/rotate-secret",
    headers={"X-MBX-APIKEY": API_KEY,
             "Content-Type": "application/x-www-form-urlencoded"},
    data=qs + f"&signature={sig}",
)

Old secret invalid the second the new one saves. Rate limit: 10 rotations/hour per bot.

Webhook event shapes (what we POST to you)

subscription.created — пользователь только что подписался

POST https://your-bot.example.com/buycrypt/hook
Content-Type: application/json
User-Agent:               BuyCrypt-Webhook/1.0
X-BuyCrypt-Event:         subscription.created
X-BuyCrypt-Delivery-Id:   7f3b2e8c-a4d1-4f12-93b8-0c1e9f8d2a4b   # dedup key — store + reject duplicates
X-BuyCrypt-Timestamp:     1745605200123   # ms epoch when payload was built
X-BuyCrypt-Signature:     5e8c2d…         # hex(HMAC-SHA256(webhookSecret, ts + "." + body))

{
  "event":        "subscription.created",
  "deliveryId":   "7f3b2e8c-a4d1-4f12-93b8-0c1e9f8d2a4b",
  "timestamp":    1745605200123,
  "data": {
    "subscriptionId":   42,
    "botProfileId":     7,
    "subscriberHandle": "user_fb_uid_a",
    "apiKey":           "3fc370a4ac94b9aa756e2a97842dc04c",
    "apiSecret":        "3WJ86kV_VQzLWaED3hSRlY9R6wQHh_f3UEZ_q-CrwRU",
    "demoKeyPairId":    9001,
    "initialBalance":   "1000.00000000",
    "permissions":      "READ_TRADE",
    "ipWhitelist":      "",
    "createdAt":        "2026-04-25T18:00:00Z"
  }
}

subscription.deleted — пользователь отключился, ключ деактивирован

X-BuyCrypt-Event: subscription.disconnected

{
  "event":      "subscription.disconnected",
  "deliveryId": "…",
  "timestamp":  …,
  "data": {
    "subscriptionId":  42,
    "botProfileId":    7,
    "apiKey":          "3fc370a4…",
    "reason":          "USER_UNSUBSCRIBED",
    "disconnectedAt":  "2026-04-25T18:30:00Z"
  }
}

secret.regenerated — админ ротировал ваш вебхук-секрет

X-BuyCrypt-Event: secret.regenerated

{
  "event":      "secret.regenerated",
  "deliveryId": "…",
  "timestamp":  …,
  "data": {
    "subscriptionId":       42,
    "apiKey":               "3fc370a4…",
    "newApiSecret":         "new_plaintext_keep_old_valid_24h",
    "oldSecretValidUntil":  "2026-04-26T18:00:00Z"
  }
}

Verify the signature (constant-time)

Use the raw request body bytes — DO NOT parse JSON first and re-serialize, you'll lose key order and signatures will diverge. Always compare in constant time.

# Python (FastAPI / Flask)
import hmac, hashlib, time

WEBHOOK_SECRET = "whsec_aGVsbG8gd29ybGQ_..."   # whsec_…43 chars

def verify(headers, body_bytes):
    sig = headers["X-BuyCrypt-Signature"]
    ts  = int(headers["X-BuyCrypt-Timestamp"])

    # anti-replay: reject if too old
    if abs(time.time() * 1000 - ts) > 5 * 60 * 1000:
        return False

    payload = f"{ts}.".encode() + body_bytes
    expected = hmac.new(WEBHOOK_SECRET.encode(), payload, hashlib.sha256).hexdigest()

    return hmac.compare_digest(expected, sig)
// Node.js / Express — read RAW body, not parsed JSON
const crypto = require('crypto');
const SECRET = 'whsec_aGVsbG8gd29ybGQ_...';

app.post('/buycrypt/hook',
  express.raw({ type: 'application/json' }),   // raw, not json()!
  (req, res) => {
    const sig = req.headers['x-buycrypt-signature'];
    const ts  = parseInt(req.headers['x-buycrypt-timestamp'], 10);

    if (Math.abs(Date.now() - ts) > 5 * 60 * 1000) return res.status(401).end();

    const expected = crypto.createHmac('sha256', SECRET)
      .update(`${ts}.`).update(req.body).digest('hex');

    if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) {
      return res.status(401).end();
    }
    // req.body is a Buffer here — JSON.parse(req.body.toString('utf8'))
    res.sendStatus(200);
});

Политика повторных попыток

6 попыток с экспоненциальным бэкоффом: 1м, 5м, 30м, 2ч, 6ч, 12ч. Если все 6 не удались, ивент попадает в нашу dead-letter таблицу — админ может воспроизвести его вручную.

Автоотключение

Если ваш эндпоинт падает 10 раз подряд, мы помечаем его как отключённый и прекращаем отправку ивентов. Свяжитесь с нами для повторного включения. Предотвращает блокировку новых подписчиков мёртвым ботом.

Верификация подписи

Каждое тело запроса подписывается HMAC-SHA256 с секретом, переданным при регистрации. Проверяйте в константном времени перед доверием пейлоаду. Примеры — в нашем партнёрском гайде.

API-поверхность

Все поддерживаемые методы Binance USD-M Futures

Base URL: https://api.buycrypt.com/fapi. Авторизация: заголовок X-MBX-APIKEY + HMAC-SHA256 подпись на подписанных эндпоинтах. Recv window: 5,000 мс по умолчанию, максимум 60,000 мс.

Публичные рыночные данные (без авторизации)

GET
/v1/ping
Проверка доступности. Возвращает {}.
GET
/v1/time
Серверное время в мс — синхронизируйте часы, чтобы избежать несоответствий recvWindow.
GET
/v1/exchangeInfo
Символы, фильтры, точность, уровни плеча.
GET
/v1/ticker/price · /ticker/24hr · /ticker/bookTicker
Цена последней сделки · 24ч статистика · лучший бид/аск.
GET
/v1/depth?symbol=&limit=
Снимок стакана (limit ∈ {5,10,20,50,100,500,1000}).
GET
/v1/klines
OHLCV-свечи для любого интервала (1m, 5m, 1h, 4h, 1d).
GET
/v1/markPrice · /v1/fundingRate · /v1/premiumIndex
Маркировочная цена для расчёта ликвидации · история фандинга · премиум-индекс.
GET
/v1/trades · /v1/aggTrades
Недавние сделки и агрегированные сделки.

Аккаунт & позиции (подписанные)

GET
/v1/account · /v2/account · /v3/account
Полный снимок аккаунта — балансы, общая маржа, по активам, текущие позиции. Все три версии пути возвращают одинаковый пейлоад (совместимость с Binance).
GET
/v2/balance · /v3/balance
Баланс кошелька по активам. Мы отдаём только USDT.
GET
/v2/positionRisk · /v3/positionRisk
Активные позиции с маркировочной ценой, ценой входа, нереализованным PnL, ценой ликвидации.
GET
/v1/userTrades · /v1/income · /v1/commissionRate · /v1/leverageBracket
История сделок · реализованный доход · ставка комиссии по символу · уровни плеча.

Торговля (подписанные)

POST
/v1/order
Выставление ордера. Поддерживает MARKET, LIMIT, STOP_MARKET, TAKE_PROFIT_MARKET, STOP, TAKE_PROFIT (лимитный), TRAILING_STOP_MARKET. Флаги: reduceOnly, closePosition, timeInForce (GTC/IOC/FOK), newClientOrderId для идемпотентности, workingType, callbackRate.
GET
/v1/order
Запрос одного ордера по orderId или origClientOrderId.
DELETE
/v1/order
Отмена одного ордера.
DELETE
/v1/allOpenOrders?symbol=X
Отмена всех открытых ордеров по символу одним вызовом.
GET
/v1/openOrders
Все активные (не исполненные, не отменённые) ордера.
GET
/v1/allOrders
История ордеров. По умолчанию последние 500.
POST
/v1/leverage · /v1/marginType · /v1/positionMargin
Установка плеча (1×–125×) · ISOLATED/CROSS · пополнение изолированной маржи.
GET
/v1/positionSide/dual
Флаг хедж-режима. У нас только one-way — возвращает {dualSidePosition: false}.

User-data WebSocket (приватный)

POST
/v1/listenKey
Создание listenKey на 60 мин. Используется для аутентификации WS-хендшейка.
PUT
/v1/listenKey
Продление аренды listenKey ещё на 60 мин. Вызывайте каждые < 60 мин, чтобы стрим не закрылся.
DELETE
/v1/listenKey
Закрытие listenKey при завершении работы.
WS
wss://api.buycrypt.com/fapi/ws/<listenKey>
Пуш-события по ордерам, балансу, позициям: ORDER_TRADE_UPDATE, ACCOUNT_UPDATE, MARGIN_CALL. Структура пейлоада идентична Binance.

Market-data WebSocket (публичный)

WS
wss://api.buycrypt.com/fapi/stream?streams=btcusdt@trade/btcusdt@kline_1m
Multi-stream подписка. Поддерживает управляющие сообщения subscribe/unsubscribe/list_subscriptions — проксируется напрямую в Binance.
Лимиты & ошибки

Рейт-лимиты и коды ошибок

Бакеты на API-ключ

  • Вес: 2,400 / минута
  • Выставление ордеров: 300 / 10 секунд
  • Подписанные чтения: 1,200 / минута
  • Заголовки в каждом ответе: X-MBX-USED-WEIGHT-1M, X-MBX-ORDER-COUNT-10S, Retry-After при 429.

Частые коды ошибок

  • -1003 Слишком много запросов — бэкофф по Retry-After
  • -1021 Timestamp вне recvWindow
  • -1022 Неверная подпись
  • -1102 Обязательный параметр не передан
  • -1116 Неверный тип ордера
  • -2010 Ордер отклонён (недостаточный баланс и др.)
  • -2011 Ордер не найден
  • -2014 Неверный формат API-ключа
  • -2015 Неверный API-ключ, IP или права доступа
  • -2019 Недостаточно маржи

Готовы подключить своего бота?

Никаких заявок, никакой очереди на ревью, никаких интеграционных сборов. Регистрируешься как обычный юзер, генеришь API-ключи в мобильном приложении, направляешь бота на https://api.buycrypt.com/fapi — это весь онбординг.