API نمایندگیv1 https://panel.nyxcraft.ir/api/v1/

مرجع API نمایندگی

ربات تلگرام، سایت یا هر سامانهٔ فروش خودتان را به پنل نمایندگی وصل کنید: کاربر بسازید، تمدید کنید و لینک اشتراک و مصرف را بخوانید. همهٔ هزینه‌ها از همان اعتبار و موجودی حجمی حساب شما کم می‌شود و هر تغییری همان لحظه در ربات و پنل وب هم دیده می‌شود.

آدرس پایه
https://panel.nyxcraft.ir/api/v1/
قالب
JSON در بدنهٔ درخواست و پاسخ، با Content-Type: application/json
زمان
ثانیهٔ یونیکس (UTC)
حجم
مصرف به بایت، سقف حجم به گیگابایت
نسخه
v1. فیلد تازه ممکن است به پاسخ‌ها اضافه شود، فیلدی حذف یا تغییرنام داده نمی‌شود

احراز هویت

هر درخواست باید کلید API را در هدر Authorization داشته باشد. کلید را از ربات (پنل نمایندگی، بخش API) یا پنل وب (تنظیمات، API) بسازید. هر حساب حداکثر پنج کلید فعال دارد و هر کلید فقط یک بار، هنگام ساخت، نشان داده می‌شود.

هدر
Authorization: Bearer rk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • کلید را فقط سمت سرور نگه دارید؛ در اپلیکیشن موبایل یا کد مرورگر قرار ندهید.
  • اگر کلیدی لو رفت، همان لحظه حذفش کنید؛ درخواست‌های بعدی با آن کلید پاسخ 401 می‌گیرند.
  • برای هر سامانه کلید جدا بسازید تا در صورت نیاز فقط همان را حذف کنید.

تکرار امن (Idempotency-Key)

درخواست‌هایی که هزینه دارند (ساخت کاربر، تمدید، دستگاه بیشتر) را با یک شناسهٔ یکتا در هدر Idempotency-Key بفرستید؛ مثلاً شمارهٔ سفارش در سامانهٔ خودتان. اگر پاسخ به دستتان نرسید و همان درخواست را با همان شناسه دوباره فرستادید، نتیجهٔ درخواست اول برمی‌گردد و هزینه دوباره کم نمی‌شود.

هدر
Idempotency-Key: order-10452
  • شناسه ۱ تا ۱۰۰ نویسه از حروف انگلیسی، عدد و _ . : - است و تا هفت روز به خاطر سپرده می‌شود.
  • در ساخت کاربر، پاسخ تکراری فیلد "replayed": true دارد.
  • اگر درخواست اول رد شود (مثلاً اعتبار کافی نبود)، همان شناسه برای تلاش بعدی آزاد می‌ماند.

محدودیت درخواست

هر حساب در دقیقه حداکثر 300 درخواست و از این میان 60 درخواست تغییر می‌فرستد. درخواست‌های تغییر هر حساب یکی‌یکی انجام می‌شوند؛ تا پاسخ یکی نرسیده، بعدی را نفرستید. پاسخ 429 فیلد retry_after (ثانیه) دارد.

خطاها

پاسخ ناموفق همیشه یک کد وضعیت HTTP و یک شیء JSON با error (برای منطق برنامهٔ شما) و message (متن فارسی قابل نمایش به کاربر) است؛ گاهی فیلدهای بیشتری مثل cost و credits هم دارد.

نمونه
{
  "error": "short",
  "message": "این کاربر ۲ اعتبار لازم دارد و اعتبار شما ۱ است.",
  "cost": 2,
  "credits": 1
}
وضعیتerrorمعنا
400bad_json · idempotency_key · badبدنهٔ درخواست JSON معتبر نیست، یا Idempotency-Key نامعتبر است.
401authکلید نیست، نامعتبر است یا حذف شده.
403closed · blocked · not_resellerAPI فعلاً بسته است، یا حساب مسدود است یا دیگر نمایندگی ندارد.
404not_foundکاربر یا آدرس پیدا نشد؛ کاربر نمایندهٔ دیگر هم پیدا نمی‌شود.
409short · pool_empty · changed · cost · in_progress · trial_quotaاعتبار یا موجودی حجمی کافی نیست، کاربر یا فهرست میان راه تغییر کرده، هزینه بیشتر از max_cost است، درخواست قبلی با همین کلید تکرار هنوز در حال انجام است، یا سهمیهٔ اکانت تست امروز تمام شده.
413too_largeبدنهٔ درخواست بیش از ۶۴ کیلوبایت است.
422name · gb · ips · days · periods · devices · kind · expired · trial · tags · url · all_hiddenمقدار یکی از فیلدها خارج از محدوده است یا این کار برای این نوع کاربر ممکن نیست (مثلاً اکانت تست تا تبدیل نشده سقف و دستگاه نمی‌گیرد).
429slow_down · busyدرخواست‌ها بیش از سقف است، یا تغییر قبلی هنوز تمام نشده؛ پس از retry_after ثانیه دوباره بفرستید.
502 · 503panel_downسرور موقتاً پاسخ نمی‌دهد؛ چند دقیقه بعد دوباره امتحان کنید.

شیء کاربر

پاسخ همهٔ درخواست‌های مربوط به یک کاربر همین شیء است.

فیلدها

idintegerشناسهٔ کاربر
kindstringunl (نامحدود، با اعتبار) یا vol (حجمی، از موجودی)
name / notestringنام و یادداشت داخلی
statestringوضعیت؛ جدول زیر
enabledbooleanfalse یعنی متوقف‌شده توسط شما
expires_atinteger | nullانقضا (ثانیهٔ یونیکس)؛ null برای کاربر حجمی بدون انقضا
volume_gbintegerسقف حجم دوره به گیگابایت؛ ۰ یعنی بدون سقف
used_bytesinteger | nullمصرف دورهٔ فعلی به بایت
consumed_bytesintegerکل مصرف از ابتدا؛ برای کاربر حجمی همان مقداری که از موجودی کم شده
devices / paid_devicesintegerدستگاه همزمان، و دستگاه‌های پرداخت‌شده تا انقضا
link / sub_idstringلینک اشتراک (روی دامنهٔ اختصاصی‌تان، اگر فعال باشد) و شناسهٔ آن
tagsstring[]برچسب‌های کاربر
trial / trial_mbboolean / integerاکانت تست رایگان است و حجمش چند مگابایت است
hidden_serversstring[] | nullسرورهای پنهان جدای همین کاربر؛ null یعنی پیش‌فرض شما
live / pendingbooleanمصرف همین الان خوانده شده / آخرین تغییر هنوز به سرور نرسیده
daily_cap_gb / daily_used_bytes / daily_cutinteger / integer | null / booleanسقف مصرف روزانه (۰ = ندارد)، مصرف امروز و اینکه امروز به سقف رسیده و قطع است
cut_at / resume_atinteger | nullزمان‌بندی قطع و وصل (ثانیهٔ یونیکس)

مقدارهای state

activeفعال
endingفعال، ولی نزدیک انقضا
depletedحجم این دوره تمام شده
daycutسقف مصرف امروز تمام شده؛ فردا خودکار وصل می‌شود
expiredمنقضی شده
pausedمتوقف‌شده توسط شما
blockedموجودی پنل حجمی تمام شده؛ تا خرید حجم قطع است
creatingدر حال ساخت روی سرور؛ چند ثانیه بعد فعال می‌شود
deletingدر حال حذف

وب‌هوک: رویدادها و امضا

وقتی برای کاربران یا موجودی شما اتفاقی می‌افتد، یک درخواست POST با بدنهٔ JSON به آدرس وب‌هوک شما فرستاده می‌شود. اگر جواب 2xx نگیریم، بعد از ۱، ۵ و ۱۵ دقیقه، ۱، ۳، ۶ و ۱۲ ساعت دوباره می‌فرستیم و بعد رها می‌کنیم (و در تلگرام خبرتان می‌کنیم). یک رویداد در همهٔ تلاش‌ها همان id را دارد؛ رویداد تکراری را از روی آن نادیده بگیرید.

بدنه
{
  "id": "evt_1041",
  "type": "client.created",
  "created_at": 1764633605,
  "data": { "client": { "id": 812, "name": "Ali", "link": "https://…", "...": "..." } }
}

هدرها

X-Webhook-Idشناسهٔ رویداد (همان id بدنه)
X-Webhook-Eventنوع رویداد
X-Webhook-Timestampزمان ارسال (ثانیهٔ یونیکس)
X-Webhook-Signaturev1= و HMAC-SHA256 هگز از «Timestamp + نقطه + بدنهٔ خام» با کلید امضای شما

امضا را همیشه بررسی کنید و رویدادی را که Timestamp آن بیش از پنج دقیقه با ساعت شما فاصله دارد رد کنید:

Node.js
const crypto = require("crypto");
function verify(rawBody, headers, secret) {
  const ts = headers["x-webhook-timestamp"];
  const sig = (headers["x-webhook-signature"] || "").replace(/^v1=/, "");
  const mac = crypto.createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && sig.length === mac.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(mac));
}
Python
import hmac, hashlib, time
def verify(raw_body: bytes, headers, secret: str) -> bool:
    ts = headers["X-Webhook-Timestamp"]
    sig = headers.get("X-Webhook-Signature", "").removeprefix("v1=")
    mac = hmac.new(secret.encode(), ts.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
    return abs(time.time() - int(ts)) < 300 and hmac.compare_digest(sig, mac)

رویدادها

client.createdکاربر روی سرور ساخته شد و لینکش آماده است
client.renewedکاربر تمدید شد (نامحدود با اعتبار، حجمی با انقضای تازه)
client.convertedاکانت تست به کاربر دائمی تبدیل شد
client.expiringکاربر به‌زودی منقضی می‌شود (days_left)
client.expiredکاربر یا اکانت تست منقضی شد
client.usage_warningکاربر به درصد هشدار سقف حجمش رسید (percent)
client.depletedحجم کاربر تمام شد
client.daily_limitکاربر به سقف مصرف روزانه‌اش رسید و تا فردا قطع شد (daily_gb)
client.deletedکاربر حذف شد
credits.addedاعتبار خریده شد (auto: با شارژ خودکار)
credits.lowاعتبار زیر حد هشدار رفت
pool.addedحجم به موجودی پنل حجمی اضافه شد
pool.lowموجودی حجمی رو به اتمام است
pool.emptyموجودی حجمی تمام شد و کاربران حجمی قطع‌اند
topup.failedشارژ خودکار نتوانست بخرد (reason)
testارسال آزمایشی از ربات یا پنل

رویدادهای کاربر در data.client همان شیء کاربر را دارند (بدون فیلدهای لحظه‌ای مثل live)؛ رویدادهای اعتبار و حجم مقدارهای خودشان را دارند.

حساب
GET/me

وضعیت حساب

موجودی پنل حجمی (پرداخت به‌ازای مصرف)، سطح نمایندگی، شمار کاربران و محدودیت‌ها. پیش از ساخت کاربر، از اینجا باقی‌ماندن موجودی را بسنجید. credits و unlimited_panel فقط برای کسانی معنا دارند که هنوز پنل نامحدود (اعتبار) دارند.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/me" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{
  "id": 7210936715,
  "brand": "Aria VPN",
  "credits": 0,
  "unlimited_panel": false,
  "pool": { "gb": 512, "used_bytes": 196280473600, "left_bytes": 353482752000, "off": false },
  "counts": { "clients": 58, "active": 51, "ending": 4, "expired": 3, "paused": 1, "creating": 0, "vol": 12 },
  "tier": {
    "key": "silver", "percent_off": 5, "sales_30d": 23550000,
    "next": { "key": "gold", "need_toman": 36450000, "percent_off": 10 }
  },
  "rules": {
    "days_per_credit": 30, "max_devices": 10, "periods_max": 12,
    "volume_gb_max": 10000, "vol_days_max": 3650, "name_max": 32, "note_max": 200
  },
  "shop": { "credits_open": false, "volume_open": true }
}
کاربران
GET/clients

فهرست کاربران

کاربران شما، صفحه‌به‌صفحه. مصرف در این فهرست آخرین مقدار ثبت‌شده است؛ مصرف لحظه‌ای را از جزئیات کاربر بخوانید.

پارامترهای آدرس

statusstringall (پیش‌فرض)، active، soon (رو به اتمام)، expired، paused، depleted (حجم دوره تمام)، trial (اکانت تست)
kindstringunl (نامحدود) یا vol (حجمی)؛ خالی یعنی هر دو
qstringجستجو در نام، یادداشت و برچسب (حداکثر 32 حرف)
tagstringفقط کاربرانی که این برچسب را دارند
sortstringnew (پیش‌فرض)، old، expiry
pageintegerاز ۱
sizeinteger۱ تا 200؛ پیش‌فرض ۵۰
درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/clients" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{
  "items": [ { "id": 812, "kind": "unl", "name": "Ali", "state": "active", "...": "..." } ],
  "total": 58,
  "page": 1,
  "size": 50
}
POST/clients

ساخت کاربر

کاربر نامحدود به تعداد «دوره × دستگاه» اعتبار برمی‌دارد. کاربر حجمی هزینه‌ای در لحظهٔ ساخت ندارد و مصرف واقعی‌اش از موجودی پنل حجمی کم می‌شود. پاسخ، کاربر ساخته‌شده با لینک اشتراک آن است.

این درخواست هزینه دارد؛ با Idempotency-Key بفرستید تا تکرار آن دوبار هزینه نشود.

بدنهٔ درخواست

kindstringvol (حجمی، از موجودی) یا unl (نامحدود، با اعتبار؛ فقط برای کسی که هنوز اعتبار یا کاربر نامحدود دارد)؛ خالی یعنی vol، مگر نماینده هنوز پنل نامحدود داشته باشد
namestringحداکثر 32 حرف؛ خالی یعنی نام خودکار
periodsintegerفقط unl؛ تعداد دوره‌های ۳۰ روزه، ۱ تا 12
devicesintegerتعداد دستگاه همزمان؛ پیش‌فرض ۱
volume_gbintegerسقف حجم به گیگابایت، ۰ تا 10000؛ ۰ یعنی بدون سقف
daysintegerفقط vol؛ مدت به روز، ۰ تا 3650؛ ۰ یعنی بدون انقضا
tagsstring[]برچسب‌ها (حداکثر ۵، هرکدام تا ۲۰ حرف)
trialbooleantrue یعنی اکانت تست رایگان (حجم و مدتش را پشتیبانی تعیین کرده، یک دستگاه)؛ periods، devices، volume_gb و days نادیده گرفته می‌شوند. سهمیهٔ روزانه را از GET /trial ببینید
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-10452" \
  -H "Content-Type: application/json" \
  -d '{"kind":"unl","name":"Ali","periods":1,"devices":1,"volume_gb":0,"tags":["vip"]}'
پاسخ 200
{
  "id": 812,
  "kind": "unl",
  "name": "Ali",
  "note": null,
  "state": "active",
  "enabled": true,
  "expires_at": 1767225600,
  "volume_gb": 0,
  "used_bytes": 1073741824,
  "devices": 1,
  "link": "https://panel.nyxcraft.ir/s/9f2c4e1a7b3d5f60",
  "sub_id": "9f2c4e1a7b3d5f60",
  "tags": ["vip"],
  "trial": false,
  "trial_mb": 0,
  "hidden_servers": null,
  "created_at": 1764633600,
  "consumed_bytes": 1073741824,
  "live": true,
  "pending": false,
  "credits_spent": 1,
  "paid_devices": 1,
  "periods_left": 1,
  "activated_at": 1764633605,
  "renewed_at": null
}
GET/clients/{id}

جزئیات کاربر

کاربر با مصرف لحظه‌ای که همان موقع از سرور خوانده می‌شود (live برابر true). اگر سرور در دسترس نباشد، آخرین مقدار ثبت‌شده برمی‌گردد و live برابر false است.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/clients/812" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{
  "id": 812,
  "kind": "unl",
  "name": "Ali",
  "note": null,
  "state": "active",
  "enabled": true,
  "expires_at": 1767225600,
  "volume_gb": 0,
  "used_bytes": 1073741824,
  "devices": 1,
  "link": "https://panel.nyxcraft.ir/s/9f2c4e1a7b3d5f60",
  "sub_id": "9f2c4e1a7b3d5f60",
  "tags": ["vip"],
  "trial": false,
  "trial_mb": 0,
  "hidden_servers": null,
  "created_at": 1764633600,
  "consumed_bytes": 1073741824,
  "live": true,
  "pending": false,
  "credits_spent": 1,
  "paid_devices": 1,
  "periods_left": 1,
  "activated_at": 1764633605,
  "renewed_at": null
}
GET/clients/{id}/configs

کانفیگ‌های تکی

لینک کانفیگ هر سرور به‌صورت جدا، برای برنامه‌هایی که لینک اشتراک را نمی‌پذیرند.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/clients/812/configs" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{
  "items": [
    { "name": "Germany - Ali", "link": "vless://…" },
    { "name": "Netherlands - Ali", "link": "vless://…" }
  ]
}
مدیریت کاربر
POST/clients/{id}/renew

تمدید کاربر نامحدود

روزها از انقضای فعلی (یا اگر گذشته، از همین لحظه) اضافه می‌شود و سقف حجم دوره از نو شروع می‌شود. هزینه: دوره × دستگاه‌های فعلی. لینک تغییر نمی‌کند.

این درخواست هزینه دارد؛ با Idempotency-Key بفرستید تا تکرار آن دوبار هزینه نشود.

بدنهٔ درخواست

periodsinteger۱ تا 12؛ پیش‌فرض ۱
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/renew" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-10452" \
  -H "Content-Type: application/json" \
  -d '{"periods":1}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/expiry

انقضای کاربر حجمی

روز اضافه از انقضای فعلی (یا امروز). کاربر حجمی هزینهٔ زمانی ندارد.

بدنهٔ درخواست

daysالزامیinteger۰ تا 3650؛ ۰ یعنی بدون انقضا
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/expiry" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"days":30}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/reset

شروع دوبارهٔ حجم

فقط کاربر حجمی: مصرف از همین لحظه از صفر شمرده می‌شود. مصرف قبلی از موجودی پنل کم شده می‌ماند.

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/reset" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/volume

سقف حجم

سقف حجم دورهٔ کاربر. اگر مصرف فعلی از سقف تازه بیشتر باشد، کاربر تا تمدید یا افزایش سقف قطع می‌شود.

بدنهٔ درخواست

volume_gbالزامیinteger۰ تا 10000؛ ۰ یعنی بدون سقف
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/volume" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"volume_gb":50}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/devices

تعداد دستگاه

برای کاربر حجمی رایگان است. برای کاربر نامحدود، کم کردن رایگان است و افزایش تا دستگاه‌های پرداخت‌شده هم هزینه ندارد؛ بیش از آن، به ازای هر دستگاه اضافه برای هر دورهٔ باقی‌مانده یک اعتبار کم می‌شود.

این درخواست هزینه دارد؛ با Idempotency-Key بفرستید تا تکرار آن دوبار هزینه نشود.

بدنهٔ درخواست

devicesالزامیintegerتعداد تازهٔ دستگاه همزمان
max_costintegerبیشترین اعتباری که می‌پذیرید؛ اگر هزینه بیشتر باشد، چیزی کم نمی‌شود و پاسخ 409 با مقدار cost برمی‌گردد
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/devices" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-10452" \
  -H "Content-Type: application/json" \
  -d '{"devices":2,"max_cost":1}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/pause

توقف

کاربر تا فعال شدن دوباره وصل نمی‌شود. زمان انقضا در این مدت ادامه دارد. با until می‌توانید بگویید خودکار کی دوباره وصل شود.

بدنهٔ درخواست

untilintegerثانیهٔ یونیکسِ وصل شدن دوباره؛ از حالا تا یک سال دیگر. نباشد یعنی تا وقتی خودتان فعالش کنید
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/pause" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"until":1767225600}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/resume

فعال کردن دوباره

کاربر متوقف‌شده دوباره وصل می‌شود. کاربر منقضی‌شده با تمدید فعال می‌شود، نه با این درخواست.

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/resume" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/rotate

لینک تازه

شناسه و لینک اشتراک تازه ساخته می‌شود و لینک قبلی بی‌درنگ از کار می‌افتد. لینک تازه را دوباره برای مشتری بفرستید.

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/rotate" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/name

تغییر نام

نامی که در پنل و در نام کانفیگ‌ها دیده می‌شود.

بدنهٔ درخواست

nameالزامیstringحداکثر 32 حرف
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/name" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Ali Rezaei"}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/note

یادداشت

یادداشت داخلی شما؛ مشتری آن را نمی‌بیند.

بدنهٔ درخواست

notestringحداکثر 200 حرف؛ خالی یعنی حذف
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/note" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"note":"telegram: @ali"}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

DELETE/clients/{id}

حذف کاربر

کاربر قطع می‌شود و به سطل بازیافت می‌رود (trashed: true)؛ ۲۴ ساعت می‌توانید با POST /trash/{id}/restore برش گردانید و بعد از آن خودکار حذف نهایی می‌شود. با ?purge=true همان لحظه برای همیشه حذف می‌شود. کاربر نامحدودی که هیچ مصرفی نداشته، اعتبارش را در حذف نهایی برمی‌گرداند (refund). مصرف کاربر حجمی از موجودی کم شده می‌ماند.

پارامترهای آدرس

purgebooleantrue: بدون سطل بازیافت و برای همیشه
درخواست
curl -X DELETE "https://panel.nyxcraft.ir/api/v1/clients/812" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "done": true, "refund": 1, "trashed": true }
POST/clients/{id}/tags

برچسب‌ها

برچسب‌های کاربر جایگزین می‌شوند؛ آرایهٔ خالی یعنی بدون برچسب. با GET /clients?tag=vip همه را پیدا کنید.

بدنهٔ درخواست

tagsالزامیstring[]حداکثر ۵ برچسب، هرکدام تا ۲۰ حرف (حرف، عدد، _ و -)
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/tags" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tags":["vip","telegram"]}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

GET/tags

همهٔ برچسب‌ها

برچسب‌هایی که کاربرانتان دارند، با تعداد هرکدام.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/tags" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "tags": [ { "tag": "vip", "n": 12 }, { "tag": "telegram", "n": 40 } ] }
سقف روزانه، زمان‌بندی و سطل بازیافت
POST/clients/{id}/daily-cap

سقف مصرف روزانه

کاربر در هر روز (به وقت تهران) تا این مقدار مصرف می‌کند؛ به سقف که برسد تا نیمه‌شب قطع است و فردا خودکار وصل می‌شود (state برابر daycut). مصرف هر چند دقیقه یک بار خوانده می‌شود. ۰ سقف را برمی‌دارد. روی اکانت تست کار نمی‌کند.

بدنهٔ درخواست

gbالزامیinteger۰ تا 10000 گیگ
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/daily-cap" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"gb":5}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/clients/{id}/schedule

زمان‌بندی قطع و وصل

کاربر در cut_at قطع و در resume_at دوباره وصل می‌شود (هرکدام را می‌توانید خالی بگذارید). هر دو null زمان‌بندی را لغو می‌کند.

بدنهٔ درخواست

cut_atinteger | nullثانیهٔ یونیکس؛ از حالا تا یک سال دیگر
resume_atinteger | nullثانیهٔ یونیکس؛ بعد از cut_at
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/schedule" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"cut_at":1767225600,"resume_at":1767312000}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

GET/clients/{id}/ips

آدرس‌های اخیر کاربر

آدرس‌هایی که کاربر در ۳۰ دقیقهٔ اخیر با آن‌ها دیده شده، با سروری که دیده و تعداد دستگاه مجاز. over یعنی آدرس‌ها از دستگاه مجاز بیشترند.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/clients/812/ips" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "limit": 1, "count": 2, "over": true, "items": [ { "ip": "198.51.100.7", "at": 1767225000, "node": "nl-ams-1" } ] }
POST/clients/{id}/ips/clear

پاک کردن فهرست آدرس‌ها

فهرست از نو شروع می‌شود تا ببینید چه کسی واقعاً وصل می‌شود.

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/ips/clear" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "limit": 1, "count": 0, "over": false, "items": [] }
GET/sharing

اشتراک‌گذاری مشکوک

کاربرانی که در ۳۰ دقیقهٔ اخیر با آدرس‌های بیشتر از دستگاه مجازشان وصل بوده‌اند، بیشترین اول.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/sharing" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "items": [ { "id": 812, "name": "Ali", "limit": 1, "count": 3, "last_at": 1767225000 } ], "at": 1767225100 }
GET/trash

سطل بازیافت

کاربرهای حذف‌شده‌ای که هنوز ۲۴ ساعتشان تمام نشده است.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/trash" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "items": [ { "id": 812, "name": "Ali", "kind": "unl", "trashed_at": 1767225000, "expires_at": 1767311400 } ], "hours": 24 }
POST/trash/{id}/restore

برگرداندن از سطل

کاربر همان‌طور که بود دوباره وصل می‌شود (با همان لینک).

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/trash/812/restore" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

POST/trash/{id}/purge

حذف نهایی از سطل

همین لحظه برای همیشه حذف می‌شود؛ اعتبار کاربر نامحدودِ مصرف‌نشده برمی‌گردد.

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/trash/812/purge" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "done": true, "refund": 1 }
GET/audit

گزارش فعالیت

هر تغییر با اینکه چه کسی (شما از ربات، مینی‌اپ یا پنل وب، همکار، کلید API، سیستم یا پشتیبانی) انجام داده. ۱۸۰ روز نگه داشته می‌شود؛ جدیدترین اول.

پارامترهای آدرس

clientintegerفقط تغییرهای همین کاربر
groupstringusers · access · delete · account · team
whostringowner · system · api · admin، یا شناسهٔ همکار
beforeintegerشناسهٔ آخرین خط برای صفحهٔ بعد
درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/audit" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "items": [ { "id": 41, "at": 1767225000, "who": "API: bot", "action": "renew", "text": "تمدید ۳۰ روز — ۱ اعتبار", "client_id": 812, "client_name": "Ali" } ], "more": false, "days": 180 }
اکانت تست
GET/trial

سهمیهٔ اکانت تست

چند اکانت تست در ۲۴ ساعت می‌سازید، چندتا ساخته‌اید و هر تست چه دارد. اکانت تست با POST /clients و trial: true ساخته می‌شود و دو روز بعد از تمام شدن خودکار حذف می‌شود.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/trial" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "open": true, "per_day": 5, "used": 2, "mb": 300, "minutes": 60, "vol": true }
POST/clients/{id}/convert

تبدیل تست به کاربر دائمی

اکانت تست با همان لینک به کاربر عادی تبدیل می‌شود: تست نامحدود با اعتبار (دوره × دستگاه)، تست حجمی رایگان با انقضا و سقف حجم دلخواه (مصرفش از این لحظه از صفر شمرده می‌شود). روی کاربری که تست نیست کاری نمی‌کند.

این درخواست هزینه دارد؛ با Idempotency-Key بفرستید تا تکرار آن دوبار هزینه نشود.

بدنهٔ درخواست

periodsintegerتست نامحدود: ۱ تا 12؛ پیش‌فرض ۱
daysintegerتست حجمی: ۰ تا 3650 روز از همین لحظه؛ ۰ یعنی بدون انقضا؛ پیش‌فرض ۳۰
volume_gbintegerتست حجمی: سقف حجم؛ ۰ یعنی تا موجودی پنل
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/convert" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-10452" \
  -H "Content-Type: application/json" \
  -d '{"periods":1}'
پاسخ 200

شیء کاربر با وضعیت تازه؛ فیلدها · نمونهٔ کامل

تمدید همه
GET/renew-all

کاربرانی که تمدید همه می‌گیرد

کاربران نامحدود (نه تست) که رو به اتمام‌اند یا در سه روز اخیر منقضی شده‌اند، هزینهٔ یک دوره برای همه، و اعتبار شما.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/renew-all" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "items": [ { "id": 812, "name": "Ali", "devices": 1, "...": "..." } ], "cost": 14, "credits": 40, "days": 30 }
POST/renew-all

تمدید همه

همان فهرستی که خواندید را یک دوره تمدید می‌کند. count و cost همان اعداد پاسخ GET است؛ اگر فهرست میان راه عوض شده باشد، چیزی کم نمی‌شود و 409 با changed برمی‌گردد.

این درخواست هزینه دارد؛ با Idempotency-Key بفرستید تا تکرار آن دوبار هزینه نشود.

بدنهٔ درخواست

countالزامیintegerتعداد کاربران فهرست
costالزامیintegerهزینهٔ فهرست (اعتبار)
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/renew-all" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-10452" \
  -H "Content-Type: application/json" \
  -d '{"count":7,"cost":14}'
پاسخ 200
{ "renewed": [812, 813], "failed": [], "cost": 14 }
سرورهای اشتراک
GET/servers

سرورها و پیش‌فرض شما

سرورهایی که در لینک اشتراک هستند (names به ترتیبی که تعیین کرده‌اید)، آن‌هایی که برای همهٔ کاربرانتان پنهان کرده‌اید و نام‌هایی که به سرورها داده‌اید (labels). وقتی سروری مشکل دارد، پنهانش کنید تا برنامه‌ها با به‌روزرسانی بعدی اشتراک روی سرورهای دیگر بروند؛ لینک‌ها عوض نمی‌شوند.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/servers" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "names": ["🇩🇪 Germany", "🇳🇱 Netherlands"], "hidden": ["🇩🇪 Germany"], "own": false, "own_users": 2, "labels": [{ "name": "🇳🇱 Netherlands", "label": "🇳🇱 هلند" }] }
POST/servers

پنهان کردن، نام و ترتیب سرورها

پیش‌فرض همهٔ کاربرانی که سرورهای جدای خودشان را ندارند. همهٔ سرورها پنهان نمی‌شوند. با all: true، انتخاب جدای کاربران هم پاک می‌شود. order و labels برای همهٔ کاربران شماست و هرکدام که نفرستید همان‌طور می‌ماند؛ برای بازگرداندن، order: [] و labels: [] بفرستید. hidden فقط وقتی لازم است که order و labels نباشند.

بدنهٔ درخواست

hiddenstring[]نام سرورهایی که در لینک نباشند (همان names)
allbooleanهمهٔ کاربران از همین پیروی کنند
orderstring[]نام سرورها به ترتیبی که در برنامهٔ کاربران بیایند (سرورهای نیامده بعد از آن‌ها)
labels{ name, label }[]نامی که کاربران به‌جای نام سرور می‌بینند (تا ۴۰ حرف)؛ سروری که در فهرست نباشد همان نام اصلی را دارد
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/servers" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"order":["🇳🇱 Netherlands","🇩🇪 Germany"],"labels":[{"name":"🇳🇱 Netherlands","label":"🇳🇱 هلند"}]}'
پاسخ 200
{ "names": ["🇳🇱 Netherlands", "🇩🇪 Germany"], "hidden": [], "own": false, "own_users": 0, "labels": [{ "name": "🇳🇱 Netherlands", "label": "🇳🇱 هلند" }] }
POST/clients/{id}/servers

سرورهای یک کاربر

سرورهای جدای یک کاربر؛ hidden برابر null یعنی پیروی از پیش‌فرض شما.

بدنهٔ درخواست

hiddenالزامیstring[] | nullنام سرورهای پنهان، یا null
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/clients/812/servers" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"hidden":[]}'
پاسخ 200
{ "names": ["🇩🇪 Germany", "🇳🇱 Netherlands"], "hidden": [], "own": true, "own_users": 0, "labels": [] }
هشدار و شارژ خودکار
GET/settings

تنظیمات هشدار و شارژ خودکار

هشدارهای تلگرام (انقضا، حجم کاربران، گزارش ماهانه)، حد هشدار اعتبار و حجم، و مقدار شارژ خودکار از کیف پول.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/settings" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{
  "alert_expiry": true, "alert_usage": true, "alert_report": true,
  "low_credits": 5, "low_gb": 0, "auto_credits": 50, "auto_gb": 0, "auto_failed": false,
  "credits": 42, "pool": null, "wallet": { "open": true, "balance": 2100000 },
  "limits": { "credits": { "min": 10, "max": 1000 }, "gb": { "min": 256, "max": 50000 }, "usage_warn": 80, "auto_per_day": 10 }
}
POST/settings

تغییر تنظیمات

هر فیلدی که بفرستید عوض می‌شود. شارژ خودکار وقتی اعتبار (یا موجودی حجمی) زیر حد هشدار برود، از کیف پول با قیمت و تخفیف سطح شما می‌خرد؛ حداکثر ده بار در روز.

بدنهٔ درخواست

alert_expiry / alert_usage / alert_reportbooleanپیام‌های تلگرام
low_creditsintegerحد هشدار اعتبار؛ ۰ یعنی خاموش
low_gbintegerحد هشدار موجودی حجمی به گیگ؛ ۰ یعنی ده درصد خرید
auto_creditsintegerاعتبار هر شارژ خودکار؛ ۰ یعنی خاموش
auto_gbintegerگیگ هر شارژ خودکار؛ ۰ یعنی خاموش
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/settings" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"low_credits":10,"auto_credits":50}'
پاسخ 200
{ "alert_expiry": true, "...": "..." }
GET/report/month

گزارش ماهانه

خلاصهٔ یک ماه شمسی: کاربران ساخته، تمدید و حذف‌شده، اعتبار و حجم خریده و مصرف‌شده، مصرف کاربران و پورسانت.

پارامترهای آدرس

monthstringcurrent (ماه جاری تا امروز، پیش‌فرض) یا previous
درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/report/month" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{
  "key": "1405-07", "label": "مهر ۱۴۰۵", "partial": true, "from": 1758400200, "to": 1760992200,
  "bought": 100, "spent": 87, "refunded": 0, "renewed": 31, "unl": 12, "vol": 5, "trials": 9, "deleted": 2,
  "gb": 1024, "orders": 3, "toman": 23000000, "commission": 450000, "subs": 1, "used": 901943132160, "running": 48
}
GET/export/clients.csv

خروجی CSV

فایل CSV (UTF-8، در اکسل باز می‌شود): clients.csv کاربران، credits.csv دفتر اعتبار، volume.csv دفتر حجم.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/export/clients.csv" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
شماره,نام,نوع,اکانت تست,وضعیت,برچسب‌ها,...
812,Ali,نامحدود,,فعال,vip,...
وب‌هوک
GET/webhook

وب‌هوک شما

آدرس، رویدادهای انتخاب‌شده، شکست‌های پشت سر هم و آخرین ارسال‌ها. راهنمای امضا و رویدادها در بخش «وب‌هوک» بالای همین صفحه است.

درخواست
curl -X GET "https://panel.nyxcraft.ir/api/v1/webhook" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{
  "open": true, "url": "https://mybot.example.com/hook", "events": ["client.created", "client.expired"],
  "all_events": [ { "key": "client.created", "label": "…" } ], "fails": 0, "has_secret": true,
  "log": [ { "id": 1041, "event": "client.created", "state": "done", "status": 200, "error": null, "attempts": 1, "at": 1764633605 } ]
}
POST/webhook

تنظیم وب‌هوک

آدرس https (با دامنه، نه IP؛ پورت ۴۴۳ یا ۸۴۴۳) و رویدادها. بار اول کلید امضا ساخته می‌شود و فقط در همین پاسخ در فیلد secret می‌آید.

بدنهٔ درخواست

urlstringآدرس https
eventsstring[]رویدادهایی که می‌خواهید؛ نفرستید یعنی همه
درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/webhook" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://mybot.example.com/hook"}'
پاسخ 200
{ "url": "https://mybot.example.com/hook", "secret": "whsec_…", "...": "..." }
POST/webhook/secret

کلید امضای تازه

کلید قبلی از همین لحظه کار نمی‌کند؛ کلید تازه در فیلد secret همین پاسخ است.

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/webhook/secret" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "secret": "whsec_…", "...": "..." }
POST/webhook/test

ارسال آزمایشی

یک رویداد test همین الان فرستاده می‌شود و جواب سرور شما برمی‌گردد.

درخواست
curl -X POST "https://panel.nyxcraft.ir/api/v1/webhook/test" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "ok": true, "status": 200, "error": null }
DELETE/webhook

حذف وب‌هوک

دیگر چیزی فرستاده نمی‌شود و رویدادهای در صف دور ریخته می‌شوند.

درخواست
curl -X DELETE "https://panel.nyxcraft.ir/api/v1/webhook" \
  -H "Authorization: Bearer $API_KEY"
پاسخ 200
{ "url": null, "...": "..." }