DARKBOOST API / v1

Интеграция без догадок

Два независимых режима: обязательная подписка списком и последовательные задания. Ниже — контракт запросов, ответы и рабочие примеры на cURL, Python и JavaScript.

01 / START

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

Обязательная подписка

Запрашиваете до 10 спонсоров одним списком, показываете их пользователю, затем проверяете сессию через /api/v1/check.

Режим заданий

Запрашиваете ровно одно текущее задание. После check или skip сразу можно получать следующее — без cooldown между заданиями.

API-ключ берётся у подключённого бота: Продать трафик → В ботах → Интеграция (API). Передавайте ключ только в заголовке Auth.
Python — общий helper для примеров ниже
import os
import aiohttp

BASE_URL = "https://darkboosts.com"
API_KEY = os.environ["DARKBOOST_API_KEY"]

async def post_json(path, payload):
    headers = {"Auth": API_KEY, "Content-Type": "application/json"}
    async with aiohttp.ClientSession(headers=headers) as session:
        async with session.post(BASE_URL + path, json=payload) as response:
            response.raise_for_status()
            return await response.json()
POST/api/v1/sponsors

Получить список обязательных спонсоров

Передавайте Telegram-профиль пользователя, который уже известен вашему боту. DarkBoost создаёт или возвращает активную сессию и выдаёт максимум max_sponsors элементов.

cURL
curl -X POST https://darkboosts.com/api/v1/sponsors \
  -H 'Content-Type: application/json' \
  -H 'Auth: YOUR_API_KEY' \
  -d '{
    "user_id": 123456789,
    "chat_id": 123456789,
    "username": "weitov",
    "first_name": "User",
    "last_name": "Example",
    "language_code": "ru",
    "is_premium": true,
    "max_sponsors": 5
  }'
Python / aiohttp
import aiohttp

async def get_sponsors(tg_user):
    payload = {
        "user_id": tg_user.id,
        "chat_id": tg_user.id,
        "username": tg_user.username or "",
        "first_name": tg_user.first_name or "",
        "last_name": tg_user.last_name or "",
        "language_code": tg_user.language_code or "ru",
        "is_premium": bool(tg_user.is_premium),
        "max_sponsors": 5,
    }
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://darkboosts.com/api/v1/sponsors",
            json=payload,
            headers={"Auth": API_KEY},
        ) as response:
            return await response.json()
JavaScript / Node 18+
const data = await fetch('https://darkboosts.com/api/v1/sponsors', {
  method: 'POST',
  headers: {'Content-Type': 'application/json', Auth: process.env.DARKBOOST_KEY},
  body: JSON.stringify({
    user_id: user.id,
    chat_id: user.id,
    username: user.username || '',
    first_name: user.first_name || '',
    language_code: user.language_code || 'ru',
    is_premium: Boolean(user.is_premium),
    max_sponsors: 5
  })
}).then(r => r.json());
{
  "ok": true,
  "status": "ok",
  "session_id": 1042,
  "sponsors": [
    {"id": "s1", "title": "Спонсор #1", "link": "https://darkboosts.com/t/..."}
  ],
  "count": 1,
  "expires_in_seconds": 1200
}
POST/api/v1/check

Проверить обязательную подписку

Передайте того же пользователя и session_id. Выполненные пункты фиксируются идемпотентно; в missing остаются только невыполненные.

curl -X POST https://darkboosts.com/api/v1/check \
  -H 'Content-Type: application/json' -H 'Auth: YOUR_API_KEY' \
  -d '{"user_id":123456789,"chat_id":123456789,"session_id":1042}'
# Python
result = await post_json("/api/v1/check", {
    "user_id": user.id,
    "chat_id": user.id,
    "session_id": session_id,
})
if result["status"] == "ok":
    await grant_access(user.id)
else:
    await show_missing(result.get("missing", []))
Не выдавайте доступ только по факту клика. Для внутренних DarkBoost-офферов tracking является обязательной частью flow, но итоговый статус формируется серверной проверкой конкретного типа ресурса.
POST/api/v1/check-offer

Проверить один оффер из активной сессии

Дополнительный режим поверх существующей сессии. Он не заменяет /api/v1/check: старый способ проверки всей сессии продолжает работать без изменений. Передайте session_id и точную ссылку link, которую DarkBoost вернул для нужного спонсора в /api/v1/sponsors. Можно также передать offer_id.

curl -X POST https://darkboosts.com/api/v1/check-offer \
  -H 'Content-Type: application/json' -H 'Auth: YOUR_API_KEY' \
  -d '{
    "user_id": 123456789,
    "session_id": 1042,
    "offer_link": "https://darkboosts.com/t/EXACT_TRACKING_LINK"
  }'
# Python — проверить только тот оффер, кнопку которого нажал пользователь
result = await post_json("/api/v1/check-offer", {
    "user_id": user.id,
    "session_id": session_id,
    "offer_link": sponsor["link"],
})

if result["subscribed"]:
    # Этот конкретный оффер подтверждён.
    # Остальные элементы сессии находятся в remaining_sponsors.
    await show_sponsors(result["remaining_sponsors"])
else:
    await show_subscription_required()
{
  "ok": true,
  "status": "ok",
  "session_id": 1042,
  "subscribed": true,
  "remaining_count": 3,
  "remaining_sponsors": [
    {"id":"s1","title":"Спонсор #1","link":"https://darkboosts.com/t/..."}
  ],
  "session_complete": false
}
Идемпотентность сохраняется: уже подтверждённый оффер повторно не оплачивается. Сервер сопоставляет как внутренний ID, так и выданную DarkBoost tracking-ссылку. Когда remaining_count=0, сессия завершена.
POST/api/v1/tasksили /api/v1/tasks/next

Получить одно задание

Payload пользователя такой же, как в обязательной подписке. Сервер возвращает task и одновременно совместимый массив sponsors из одного элемента.

curl -X POST https://darkboosts.com/api/v1/tasks/next \
  -H 'Content-Type: application/json' -H 'Auth: YOUR_API_KEY' \
  -d '{"user_id":123456789,"chat_id":123456789,"username":"weitov"}'
// JavaScript / Node 18+
const API_KEY = process.env.DARKBOOST_KEY;

async function nextTask(user) {
  const r = await fetch('https://darkboosts.com/api/v1/tasks/next', {
    method: 'POST',
    headers: {'Content-Type':'application/json', Auth: API_KEY},
    body: JSON.stringify({user_id:user.id, chat_id:user.id, username:user.username})
  });
  const data = await r.json();
  if (data.task) await sendTaskButton(user.id, data.task.title, data.task.link);
  return data;
}
Python / aiohttp
async def next_task(tg_user):
    return await post_json("/api/v1/tasks/next", {
        "user_id": tg_user.id,
        "chat_id": tg_user.id,
        "username": tg_user.username or "",
        "first_name": tg_user.first_name or "",
        "language_code": tg_user.language_code or "ru",
        "is_premium": bool(tg_user.is_premium),
    })
{
  "ok": true,
  "status": "ok",
  "mode": "tasks",
  "session_id": 2088,
  "task": {"id":"s1","title":"Спонсор #1","link":"https://darkboosts.com/t/..."},
  "count": 1,
  "no_timeout": true,
  "cooldown": false
}
POST/api/v1/tasks/check/api/v1/tasks/skip

Проверить или пропустить текущее задание

Check
{"user_id":123456789,"session_id":2088}
Skip
{"user_id":123456789,"session_id":2088}
# Python helper
async def check_task(user_id, session_id):
    return await post_json('/api/v1/tasks/check', {
        'user_id': user_id,
        'session_id': session_id,
    })

async def skip_task(user_id, session_id):
    return await post_json('/api/v1/tasks/skip', {
        'user_id': user_id,
        'session_id': session_id,
    })
JavaScript / Node 18+
async function taskAction(path, userId, sessionId) {
  const response = await fetch(`https://darkboosts.com${path}`, {
    method: 'POST',
    headers: {'Content-Type':'application/json', Auth: process.env.DARKBOOST_KEY},
    body: JSON.stringify({user_id:userId, session_id:sessionId})
  });
  if (!response.ok) throw new Error(`DarkBoost HTTP ${response.status}`);
  return response.json();
}

const checked = await taskAction('/api/v1/tasks/check', user.id, sessionId);
// либо:
const skipped = await taskAction('/api/v1/tasks/skip', user.id, sessionId);

После успешного check или skip запросите /api/v1/tasks/next. Пропуск не создаёт оплачиваемое выполнение.

TRACKING

Как работает DarkBoost tracking

01ВыдачаAPI возвращает URL вида /t/{token}.
02Первый переходФиксируются серверные HTTP-сигналы и click timestamp.
03Client signalsДля внешних web-ресурсов relay отправляет экран, platform, timezone и browser hints.
04Telegram enrichmentДоступные Telegram-поля дополняются через Bot API/подключённые источники.
Важно: обычный HTTP-переход не может раскрыть закрытые поля Telegram-профиля. DarkBoost сохраняет только технические сигналы браузера и те Telegram-данные, которые реально доступны соответствующему Bot API/аккаунту.
OWNER WEBHOOKS

События подключённого бота

Если webhook включён в настройках бота, DarkBoost доставляет события subscription и unsubscription. Ранняя отписка от first-party ресурса DarkBoost приходит как unsubscription с service=darkboost. Тело подписывается HMAC-SHA256 вашим webhook secret.

X-DarkBoost-Event: unsubscription
X-DarkBoost-Event-Id: ...
X-DarkBoost-Signature: sha256=HEX_HMAC
Python / FastAPI
import hashlib, hmac
from fastapi import FastAPI, Request, HTTPException

app = FastAPI()
WEBHOOK_SECRET = "your-secret"

@app.post("/darkboost/webhook")
async def darkboost_webhook(request: Request):
    body = await request.body()
    received = request.headers.get("X-DarkBoost-Signature", "")
    expected = "sha256=" + hmac.new(
        WEBHOOK_SECRET.encode(), body, hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(received, expected):
        raise HTTPException(403, "bad signature")
    event = await request.json()
    return {"ok": True}
Node / Express
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.use(express.raw({type: 'application/json'}));

app.post('/darkboost/webhook', (req, res) => {
  const got = req.get('X-DarkBoost-Signature') || '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.DARKBOOST_WEBHOOK_SECRET)
    .update(req.body).digest('hex');
  const a = Buffer.from(got), b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(403);
  const event = JSON.parse(req.body.toString('utf8'));
  res.json({ok: true});
});

Статусы и ошибки

ЗначениеЧто делать
okДействие подтверждено или выдача готова.
cooldownНе создавайте новую mandatory-сессию до reset_seconds.
no_offersСейчас нет доступных офферов; повторите позднее.
not_foundАктивная сессия не найдена.
invalid_api_keyПроверьте заголовок Auth и активность подключённого бота.
security_lockedБот остановлен системой безопасности/администратором.

Интеграционный checklist

  1. Храните API-key и webhook secret только на сервере.
  2. Не переписывайте tracking URL — показывайте пользователю ссылку из ответа DarkBoost.
  3. Всегда связывайте check с исходным session_id.
  4. Обрабатывайте HTTP-коды и status отдельно.
  5. Webhook сначала проверяйте по HMAC, только потом меняйте внутреннее состояние.
  6. Не начисляйте пользователю награду повторно при retry вашего собственного обработчика.