DNS Hub Reseller API v1.0
Go to Dashboard

Reseller API Documentation

Build your own Telegram bot, website, or automation tool using your personal API key. Create clients, manage subscriptions, and monitor your wallet โ€” all programmatically.

Authentication

All API requests must include your API key in the X-API-Key HTTP header.

# Include this header in every request
X-API-Key: rsk_a7f3b2c9d1e4f8a0b3c6d9e2f5a8b1c4
โš ๏ธ Keep your API key secret. Never expose it in frontend JavaScript or public repositories. Use it only in server-side code (bot backend, PHP server, Python script).

Base URL

Base URL:  https://panel.dnsbd.pp.ua/api/v1

Rate Limit: 60 requests / minute
Format:    application/json

Error Codes

HTTP CodeMeaningCommon Cause
401UnauthorizedMissing or invalid X-API-Key header
402Payment RequiredInsufficient credits in wallet
403ForbiddenReseller account is inactive
404Not FoundClient username not found in your account
409ConflictUsername already taken or client already banned
429Rate LimitedExceeded 60 requests per minute
500Server ErrorContact admin if this persists
GET /api/v1/me Check balance & stats

Returns your reseller account info, current credit balance, and client statistics.

curl https://panel.dnsbd.pp.ua/api/v1/me \
  -H "X-API-Key: rsk_YOUR_KEY_HERE"
// Response
{
  "success": true,
  "data": {
    "username": "dipu_reseller",
    "status": "active",
    "credits": 150,
    "stats": {
      "total_clients": 45,
      "active_clients": 38,
      "expired_clients": 5,
      "banned_clients": 2
    }
  }
}
GET /api/v1/clients List all clients

Returns paginated list of all your DNS clients.

Query ParamTypeDescription
status optionalstringFilter: all, active, expired, banned
search optionalstringSearch by username, phone, or DNS URL
page optionalnumberPage number (default: 1)
limit optionalnumberItems per page (max: 100, default: 50)
curl "https://panel.dnsbd.pp.ua/api/v1/clients?status=active&page=1" \
  -H "X-API-Key: rsk_YOUR_KEY_HERE"
POST /api/v1/client/create Create new client (deducts credits)
Body FieldTypeDescription
username requiredstringClient identifier (min 3 chars, alphanumeric/dash/underscore)
duration_days optionalnumberSubscription length in days (default: 30). 1 credit = 30 days
phone optionalstringClient phone/WhatsApp number for your records
note optionalstringInternal note (logged in transaction history)
curl -X POST https://panel.dnsbd.pp.ua/api/v1/client/create \
  -H "X-API-Key: rsk_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "rahim123",
    "phone": "01712345678",
    "duration_days": 30,
    "note": "Paid via bKash"
  }'
// Success Response (HTTP 201)
{
  "success": true,
  "data": {
    "username": "rahim123",
    "dns_url": "r7392841.dnsbd.pp.ua",
    "android_dns": "r7392841.dnsbd.pp.ua",
    "ios_profile_url": "https://panel.dnsbd.pp.ua/api/public/ios-profile?username=rahim123",
    "expires_at": "2026-09-26 00:00:00",
    "duration_days": 30,
    "credits_deducted": 1,
    "remaining_credits": 149,
    "whatsapp_message": "โšก Private DNS เฆšเฆพเฆฒเง เฆนเฆฏเฆผเง‡เฆ›เง‡!..."
  }
}
POST /api/v1/client/test-pin Fixed 30-Min Trial (1 Test Credit)

Instantly generate and authorize an on-demand 30-Minute Trial PIN for prospective customers. Deducts 1 Test PIN Credit. Automatically deleted from AdGuard Home upon expiration by our background daemon.

FieldTypeRequiredDescription
usernamestringOptionalCustom subdomain prefix (e.g. test8821). Auto-generated if omitted.
phonestringOptionalCustomer WhatsApp/mobile number for 1-click delivery.
notestringOptionalInternal tracking note (e.g. Telegram trial lead).
curl -X POST https://panel.dnsbd.pp.ua/api/v1/client/test-pin \
  -H "X-API-Key: rsk_YOUR_RESELLER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "test8821",
    "phone": "01712345678",
    "note": "Demo client"
  }'
// Success Response (HTTP 201)
{
  "success": true,
  "message": "30-Minute Test PIN 'test8821' created and activated!",
  "data": {
    "username": "test8821",
    "dns_url": "test8821.dnsbd.pp.ua",
    "dot_host": "test8821.dnsbd.pp.ua",
    "duration_minutes": 30,
    "expires_at": "2026-08-27 15:30:00",
    "remaining_test_credits": 9,
    "vps_synced": true,
    "ios_profile_url": "https://panel.dnsbd.pp.ua/api/public/ios-profile?username=test8821",
    "whatsapp_share_text": "โšก DNSBD 30-MIN PRIVATE DNS TEST PIN โšก..."
  }
}
POST /api/v1/client/renew Extend subscription
FieldTypeDescription
username requiredstringClient's username to renew
duration_days optionalnumberDays to add (default: 30)
curl -X POST https://panel.dnsbd.pp.ua/api/v1/client/renew \
  -H "X-API-Key: rsk_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"username": "rahim123", "duration_days": 30}'
POST /api/v1/client/ban Block client DNS
curl -X POST https://panel.dnsbd.pp.ua/api/v1/client/ban \
  -H "X-API-Key: rsk_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"username": "rahim123", "reason": "Non-payment"}'
POST /api/v1/client/unban Restore client DNS
curl -X POST https://panel.dnsbd.pp.ua/api/v1/client/unban \
  -H "X-API-Key: rsk_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"username": "rahim123"}'
DELETE /api/v1/client/{username} Permanently delete client
curl -X DELETE https://panel.dnsbd.pp.ua/api/v1/client/rahim123 \
  -H "X-API-Key: rsk_YOUR_KEY_HERE"

๐Ÿค– Complete Telegram Bot Example

A full-featured Telegram bot for managing DNS clients. Setup: npm install node-telegram-bot-api axios

const TelegramBot = require("node-telegram-bot-api");
const axios = require("axios");

const BOT_TOKEN = "YOUR_BOT_TOKEN";
const ADMIN_ID = 123456789; // Your Telegram user ID
const API_KEY = "rsk_YOUR_KEY_HERE";
const BASE = "https://panel.dnsbd.pp.ua/api/v1";

const bot = new TelegramBot(BOT_TOKEN, { polling: true });
const api = axios.create({ headers: { "X-API-Key": API_KEY } });

// /start
bot.onText(/\/start/, msg => {
    bot.sendMessage(msg.chat.id,
        `๐Ÿ”‘ *DNS Hub Bot*\n\nCommands:\n` +
        `/balance โ€” Check credits\n` +
        `/create username phone โ€” Create DNS client\n` +
        `/renew username โ€” Renew 30 days\n` +
        `/ban username โ€” Ban client\n` +
        `/unban username โ€” Unban client\n` +
        `/clients โ€” List active clients`,
        { parse_mode: "Markdown" }
    );
});

// /balance
bot.onText(/\/balance/, async msg => {
    const res = await api.get(`${BASE}/me`);
    const d = res.data.data;
    bot.sendMessage(msg.chat.id,
        `๐Ÿ’ฐ *Wallet Balance*\n\n` +
        `Credits: *${d.credits}*\n` +
        `Active Clients: *${d.stats.active_clients}*\n` +
        `Expired: *${d.stats.expired_clients}*`,
        { parse_mode: "Markdown" }
    );
});

// /create username 01712345678
bot.onText(/\/create (.+?) (.+)/, async (msg, match) => {
    if (msg.from.id !== ADMIN_ID) return;
    const [, username, phone] = match;
    try {
        const res = await api.post(`${BASE}/client/create`, { username, phone, duration_days: 30 });
        const d = res.data;
        if (d.success) {
            bot.sendMessage(msg.chat.id,
                `โœ… *DNS Created!*\n\n` +
                `๐Ÿ‘ค User: \`${d.data.username}\`\n` +
                `๐ŸŒ DNS: \`${d.data.dns_url}\`\n` +
                `๐Ÿ“… Expires: ${d.data.expires_at}\n` +
                `๐Ÿ“ฑ iOS: ${d.data.ios_profile_url}\n` +
                `๐Ÿ’ฐ Credits Left: ${d.data.remaining_credits}`,
                { parse_mode: "Markdown" }
            );
        } else {
            bot.sendMessage(msg.chat.id, `โŒ ${d.error}`);
        }
    } catch (e) {
        bot.sendMessage(msg.chat.id, `โŒ Error: ${e.response?.data?.error || e.message}`);
    }
});

// /renew username
bot.onText(/\/renew (.+)/, async (msg, match) => {
    if (msg.from.id !== ADMIN_ID) return;
    const res = await api.post(`${BASE}/client/renew`, { username: match[1], duration_days: 30 });
    const d = res.data;
    bot.sendMessage(msg.chat.id, d.success ? `โœ… Renewed! New expiry: ${d.data.new_expires_at}` : `โŒ ${d.error}`);
});

// /ban username
bot.onText(/\/ban (.+)/, async (msg, match) => {
    if (msg.from.id !== ADMIN_ID) return;
    const res = await api.post(`${BASE}/client/ban`, { username: match[1] });
    const d = res.data;
    bot.sendMessage(msg.chat.id, d.success ? `๐Ÿšซ Client '${match[1]}' banned.` : `โŒ ${d.error}`);
});

// /unban username
bot.onText(/\/unban (.+)/, async (msg, match) => {
    if (msg.from.id !== ADMIN_ID) return;
    const res = await api.post(`${BASE}/client/unban`, { username: match[1] });
    const d = res.data;
    bot.sendMessage(msg.chat.id, d.success ? `โœ… Client '${match[1]}' unbanned & DNS restored.` : `โŒ ${d.error}`);
});

console.log("๐Ÿค– DNS Hub Bot started!");

๐Ÿ Python Script Example

import requests

class DNSHubAPI:
    def __init__(self, api_key):
        self.base = "https://panel.dnsbd.pp.ua/api/v1"
        self.headers = {"X-API-Key": api_key}

    def balance(self):
        return requests.get(f"{self.base}/me", headers=self.headers).json()

    def create(self, username, phone="", days=30):
        return requests.post(f"{self.base}/client/create", headers=self.headers,
            json={"username": username, "phone": phone, "duration_days": days}).json()

    def renew(self, username, days=30):
        return requests.post(f"{self.base}/client/renew", headers=self.headers,
            json={"username": username, "duration_days": days}).json()

    def ban(self, username, reason=""):
        return requests.post(f"{self.base}/client/ban", headers=self.headers,
            json={"username": username, "reason": reason}).json()

    def unban(self, username):
        return requests.post(f"{self.base}/client/unban", headers=self.headers,
            json={"username": username}).json()

    def clients(self, status="all"):
        return requests.get(f"{self.base}/clients?status={status}", headers=self.headers).json()

# Usage
api = DNSHubAPI("rsk_YOUR_KEY_HERE")

# Create a client
result = api.create("rahim123", "01712345678", 30)
print(result["data"]["dns_url"])

# Check balance
info = api.balance()
print(f"Credits: {info['data']['credits']}")

๐Ÿ˜ PHP / Laravel Example

<?php
class DNSHubAPI {
    private $key;
    private $base = "https://panel.dnsbd.pp.ua/api/v1";

    public function __construct($apiKey) {
        $this->key = $apiKey;
    }

    private function request($method, $path, $data = null) {
        $ch = curl_init($this->base . $path);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                "X-API-Key: {$this->key}",
                "Content-Type: application/json"
            ],
            CURLOPT_CUSTOMREQUEST => $method,
        ]);
        if ($data) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        $result = json_decode(curl_exec($ch), true);
        curl_close($ch);
        return $result;
    }

    public function balance() { return $this->request("GET", "/me"); }
    public function create($username, $phone="", $days=30) {
        return $this->request("POST", "/client/create", compact("username","phone") + ["duration_days" => $days]);
    }
    public function renew($username, $days=30) {
        return $this->request("POST", "/client/renew", ["username" => $username, "duration_days" => $days]);
    }
    public function ban($username) { return $this->request("POST", "/client/ban", ["username" => $username]); }
    public function unban($username) { return $this->request("POST", "/client/unban", ["username" => $username]); }
}

// Usage
$api = new DNSHubAPI("rsk_YOUR_KEY_HERE");
$result = $api->create("rahim123", "01712345678", 30);
echo $result["data"]["dns_url"]; // r7392841.dnsbd.pp.ua
?>