مقدمه #
وبسرویس پنل Domain123 یک API مبتنی بر HTTP و JSON است که همان هستهٔ کسبوکار پنل را در اختیار سیستم شما میگذارد؛ هیچ قاعدهٔ موازی و هیچ مسیر مالی دومی وجود ندارد. هر عملیاتی که در پنل انجام میشود، از طریق همین سرویس نیز قابل انجام است و برعکس.
این مستندات با استاندارد OpenAPI Specification 3.1 توصیف شده و ساختار صفحه بر پایهٔ الگوی سهستونه (Slate / Three-pane) است: ستون راست، فهرست موضوعات؛ ستون میانی، متن مرجع؛ ستون چپ، نمونهکدها و پاسخها.
آدرس پایه Base URL https://panel.domain123.ir/api/v1
همهٔ مسیرهای این مستندات نسبت به همین آدرس پایه نوشته شدهاند. ارتباط باید روی HTTPS برقرار شود؛ درخواستهای HTTP پذیرفته نمیشوند.
نسخهبندی نسخهٔ فعلی v1 است و در مسیر URL قرار میگیرد. تغییرات ناسازگار تنها در نسخهٔ جدید منتشر میشود؛ افزودن فیلد به پاسخها یا افزودن پارامتر اختیاری، تغییر ناسازگار محسوب نمیشود.
مشخصات کلی سرویس
ویژگی مقدار قالب داده application/json با کدگذاری UTF-8پروتکل HTTPS (TLS 1.2 یا بالاتر) نسخهٔ API v1واحد پول ریال ایران — همهٔ مبالغ عدد صحیح و بدون اعشار هستند سقف درخواست ۶۰ درخواست در دقیقه برای هر حساب؛ ۱۰ عملیات تغییردهنده در دقیقه مستندات ماشینخوان OpenAPI 3.1 — دریافت فایل JSON
پاسخهای این سرویس با Cache-Control: no-store ارسال میشوند. هرگز نتیجهٔ یک درخواست را در سیستم خود کش نکنید؛ وضعیت دامنه، قفل و کیف پول ممکن است در هر لحظه تغییر کند.
شروع سریع #
پیش از نخستین درخواست، سه کار را انجام دهید: ساخت کلید، تعیین IP مجاز و انتخاب سطح دسترسی.
با حساب مشتری وارد پنل شوید و به بخش وبسرویس در آدرس /customer/service/api بروید. یک کلید جدید بسازید و حداقل یک IP یا بازهٔ CIDR را در فهرست مجاز ثبت کنید؛ IP خروجی سروری که درخواستها را میفرستد الزامی است. سطح دسترسی کلید را انتخاب کنید: read، write یا full. مقدار کلید را در متغیر محیطی نگه دارید؛ کلید فقط یک بار نمایش داده میشود. هدرهای استاندارد هر درخواست Authorization: Bearer $DOMAIN123_API_KEY
Accept: application/json
Content-Type: application/json
کلید API با پشتیبانی IP Allowlist کار میکند و این فهرست اجباری است. اگر IP درخواست در فهرست نباشد، پاسخ 401 unauthenticated است، حتی اگر کلید معتبر باشد. پیش از هر عملیات مالی، با POST /domains/availability از آزاد بودن نام مطمئن شوید. این درخواست رایگان است، پولی رزرو نمیکند و پاسخ قطعی ثبتکننده را برمیگرداند. قالب پاسخ هر پاسخ — موفق یا ناموفق — یک پوشش ثابت دارد. دادهٔ عملیات همیشه در data و خطای ساختاریافته همیشه در error قرار میگیرد.
پاسخ موفق {
"ok": true,
"data": {
"...": "..."
}
}
پاسخ ناموفق {
"ok": false,
"error": {
"code": "domain-not-found",
"message": "دامنه در این حساب یافت نشد."
}
}
احراز هویت #
احراز هویت با یک کلید API انجام میشود که به یک حساب مشخص تعلق دارد. سرویس هیچ انتخابگر حسابی نمیپذیرد؛ حساب از خود کلید استخراج میشود.
Authorization Authorization: Bearer <YOUR_API_KEY>
سطوح دسترسی سطح دسترسی به اثر واقعی عملیات بسته است، نه به متد HTTP. یک POST میتواند فقطخواندنی باشد و یک GET هرگز بهصورت خودکار بیخطر فرض نمیشود.
سطح اجازهٔ انجام نمونهٔ عملیات readفقط خواندن؛ بدون هیچ اثر مالی فهرست دامنهها، اطلاعات دامنه، استعلام موجودی، کیف پول writeتغییرات بدون اثر مالی نیمسرورها، Registrar Lock، ایجاد شناسه fullهمهٔ عملیات، از جمله عملیات مالی ثبت، تمدید، انتقال، بازگردانی، تغییر مالکیت
سطح full اجازهٔ خرج کردن از کیف پول را میدهد. اگر کلید فقط برای همگامسازی DNS استفاده میشود، سطح write کافی است. چرخهٔ عمر کلید موضوع رفتار سرویس IP مجاز اجباری؛ درخواست از IP غیرمجاز با 401 رد میشود تاریخ انقضا اختیاری؛ کلید منقضی با 401 رد میشود ابطال و جایگزینی از همان صفحهٔ وبسرویس پنل؛ کلید جایگزین یک کلید مستقل با همان دسترسیهاست لاگ هر درخواست با کلید، IP، متد، مسیر، کد وضعیت و زمان ثبت میشود
کلید را در کد سمت مرورگر، مخزن عمومی یا فایلهای قابل دانلود قرار ندهید. در صورت لو رفتن، کلید را فوراً ابطال و جایگزین کنید.
قواعد عمومی #
این قواعد برای همهٔ اندپوینتها یکسان است و رعایت آنها از خطاهای تکراری جلوگیری میکند.
Idempotency-Key همهٔ عملیات تغییردهنده باید هدر Idempotency-Key داشته باشند؛ رشتهای از ۱۶ تا ۶۴ نویسه شامل حروف لاتین، رقم، - و _. اگر هدر ارسال نشود، همان مقدار از فیلد request_key در بدنه خوانده میشود.
کلید تکرارپذیر است: ارسال دوبارهٔ همان کلید با همان ورودی، عملیات را دوباره اجرا نمیکند و همان نتیجهٔ قبلی را برمیگرداند. ارسال همان کلید با ورودی متفاوت با خطای request-key-reused-with-different-input رد میشود.
کلید را از «عملیات + دامنه + دوره + شناسهٔ داخلی سفارش» بسازید تا تلاش مجدد سیستم شما همیشه به همان عملیات نگاشت شود. کلید تصادفی برای هر تلاش، محافظت در برابر شارژ دوباره را از بین میبرد. پول و مبالغ همهٔ مبالغ عدد صحیح ریال هستند و واحد پول در فیلد currency با مقدار IRR گزارش میشود. عملیات مالی پیش از ارسال به ثبتکننده، مبلغ را در کیف پول رزرو میکند؛ در صورت شکست قطعی، مبلغ بازگردانده و در فیلد returned_amount گزارش میشود.
پارامتر confirmed_amount مبلغی است که کاربر نهایی در سیستم شما تأیید کرده است. اگر با تعرفهٔ منتشرشدهٔ لحظهٔ اجرا یکسان نباشد، عملیات رد میشود تا مبلغی خارج از تأیید کاربر خرج نشود.
نتیجهٔ عملیات مقدار result معنا اقدام لازم successfulعملیات در ثبتکننده و در دفتر مالی قطعی شده است ثبت نتیجه در سیستم شما failedعملیات قطعاً انجام نشده و پول بازگشته است نمایش خطا؛ ارسال مجدد فقط پس از رفع علت unknownنتیجهٔ ثبتکننده اثبات نشده است همگامسازی در پنل؛ ارسال کورکورانهٔ مجدد ممنوع
پاسخ unknown با کد HTTP ۲۰۰ برگردانده میشود، اما موفقیت نیست . تا زمانی که وضعیت واقعی از پنل همگام نشود، نباید برای کاربر «ثبت شد» نمایش دهید. محدودیت نرخ دامنهٔ اعمال سقف سرآیندهای پاسخ درخواستهای احرازشده (کل حساب) ۶۰ در دقیقه X-RateLimit-Limit، X-RateLimit-Remainingعملیات تغییردهنده ۱۰ در دقیقه همان سرآیندها با سقف ۱۰ اندپوینتهای عمومی ۶۰ در دقیقه برای هر IP همان سرآیندها
در پاسخ 429، مقدار Retry-After تعداد ثانیهٔ انتظار را مشخص میکند.
شناسهها و مالکیت هر دامنه در پنل یک id عددی دارد و عملیات روی دامنه با همین شناسه انجام میشود. برای مصرفکنندگانی که دامنه را با نام میشناسند (مثل WHMCS)، اندپوینت GET /domains/lookup?fqdn= همین شناسه را برمیگرداند.
دسترسی به دامنهٔ حسابی دیگر، حتی با شناسهٔ صحیح، پاسخ 404 domain-not-found میدهد. مالکیت در خود پرسوجوی پایگاهداده اعمال میشود.
اندپوینتهای عمومی #
این دو اندپوینت بدون کلید API در دسترساند، فقطخواندنی هستند و بهازای هر IP محدود میشوند. برای استعلام قیمت و WHOIS در سایت یا سیستم خود از همینها استفاده کنید.
این اندپوینتها هیچ حساب، کلید یا اشتراکی نمیپذیرند و هرگز دادهای خارج از تعرفهٔ منتشرشده یا پاسخ عمومی WHOIS برنمیگردانند.
تعرفهٔ جاری یک سطح قیمتی را از آخرین نسخهٔ منتشرشدهٔ پنل برمیگرداند. اگر تعرفه کهنه باشد، بهجای عدد نادرست، خطای ۵۰۳ برگردانده میشود.
پارامترهای درخواست نام نوع داده الزامی توضیحات levelstring اختیاری کلید سطح قیمتی. اگر ارسال نشود، نخستین سطح منتشرشده انتخاب میشود.
فیلدهای پاسخ نام نوع داده توضیحات levelstring سطح قیمتی پاسخ currencystring واحد پول؛ همیشه IRR publicationobject نسخهٔ انتشار تعرفه (id، version، published_at، …) tierobject سطح قیمتی نگاشتشده (slab_id، name) rowsarray<object> یک ردیف برای هر TLD: register، renew، transfer، restore، move، five_year
نمونه درخواست
cURL / PHP
cURL PHP
curl -X GET "https://panel.domain123.ir/api/v1/public/prices?level=reseller" \
-H "Accept: application/json"
<?php
$token = getenv('DOMAIN123_API_KEY');
$query = [
'level' => 'reseller',
];
$url = 'https://panel.domain123.ir/api/v1/public/prices' . '?' . http_build_query($query);
$headers = [
'Accept: application/json',
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — پاسخ موفق
{
"ok": true,
"data": {
"level": "reseller",
"currency": "IRR",
"publication": {
"id": 41,
"version": 7,
"current": true,
"published_at": 1762041600
},
"tier": {
"slab_id": 3,
"name": "نمایندگی"
},
"rows": [
{
"tld_id": 1,
"extension": "ir",
"currency": "IRR",
"register": 450000,
"renew": 450000,
"transfer": 0,
"restore": 0,
"move": 0,
"five_year": 2250000
},
{
"tld_id": 2,
"extension": "com",
"currency": "IRR",
"register": 1250000,
"renew": 1250000,
"transfer": 1250000,
"restore": 0,
"move": 0,
"five_year": 6250000
}
]
}
}
۵۰۳ — تعرفهٔ منتشرشده در دسترس نیست
{
"ok": false,
"error": {
"code": "prices-unavailable",
"message": "قیمت منتشرشده و بهروزی برای این سطح وجود ندارد."
}
}
نتیجهٔ WHOIS یک دامنه را بهصورت پاکسازیشده برمیگرداند: آزاد بودن، وضعیتها، تاریخ انقضا و نیمسرورها. دادهٔ شخصی مالک در این پاسخ نمایش داده نمیشود.
پارامترهای درخواست نام نوع داده الزامی توضیحات domainstring الزامی نام کامل دامنه، مثلاً example.ir
فیلدهای پاسخ نام نوع داده توضیحات domainstring دامنهٔ نرمالشده availableboolean آیا نام آزاد است statusesarray<string> وضعیتهای EPP/WHOIS expirystring|null تاریخ انقضا nameserversarray<string> نیمسرورهای گزارششده sourcestring منبع پاسخ WHOIS checked_atinteger زمان خواندن، به ثانیهٔ یونیکس
نمونه درخواست
cURL / PHP
cURL PHP
curl -X GET "https://panel.domain123.ir/api/v1/public/whois?domain=example.ir" \
-H "Accept: application/json"
<?php
$token = getenv('DOMAIN123_API_KEY');
$query = [
'domain' => 'example.ir',
];
$url = 'https://panel.domain123.ir/api/v1/public/whois' . '?' . http_build_query($query);
$headers = [
'Accept: application/json',
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — پاسخ موفق
{
"ok": true,
"data": {
"domain": "example.ir",
"available": false,
"statuses": [
"ok"
],
"expiry": "2027-04-12",
"nameservers": [
"ns1.example.ir",
"ns2.example.ir"
],
"source": "irnic",
"checked_at": 1762300000
}
}
۴۲۲ — نام دامنه نامعتبر است
{
"ok": false,
"error": {
"code": "domain-invalid",
"message": "پاسخ معتبر WHOIS برای این دامنه در دسترس نیست."
}
}
حساب و کیف پول #
این دو اندپوینت تصویر مالی حسابِ کلید را نشان میدهند و برای کنترل موجودی پیش از عملیات مالی ضروریاند.
شناسه، نام، ایمیل، موجودی کیف پول و مشخصات کلید جاری را برمیگرداند. برای تشخیص اینکه کلید به کدام حساب تعلق دارد و چه سطحی دارد، از همین اندپوینت استفاده کنید.
فیلدهای پاسخ نام نوع داده توضیحات account_idinteger شناسهٔ حساب namestring نام و نام خانوادگی emailstring ایمیل حساب walletobject موجودی و واحد پول keyobject شناسه، نام و سطح دسترسی کلید
نمونه درخواست
cURL / PHP
cURL PHP
curl -X GET "https://panel.domain123.ir/api/v1/account" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY"
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/account';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — پاسخ موفق
{
"ok": true,
"data": {
"account_id": 9701,
"name": "نمونه کاربر",
"email": "user@example.com",
"wallet": {
"balance": 12500000,
"currency": "IRR"
},
"key": {
"id": 12,
"name": "whmcs-prod",
"permissions": "full"
}
}
}
۴۰۱ — کلید نامعتبر یا IP غیرمجاز
{
"ok": false,
"error": {
"code": "unauthenticated",
"message": "کلید API معتبر نیست، لغو شده، منقضی شده یا IP درخواست مجاز نیست."
}
}
موجودی جاری و ۵۰ تراکنش آخر کیف پول را برمیگرداند. هر ردیف، مبلغ، موجودی پس از تراکنش، نوع و عملیات مرتبط را نشان میدهد.
فیلدهای پاسخ نام نوع داده توضیحات balanceinteger موجودی قابل استفادهٔ کیف پول (ریال) currencystring واحد پول historyarray<object> تراکنشها: id، amount، balance_after، type، operation، status، note، at
نمونه درخواست
cURL / PHP
cURL PHP
curl -X GET "https://panel.domain123.ir/api/v1/wallet" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY"
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/wallet';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — پاسخ موفق
{
"ok": true,
"data": {
"balance": 12500000,
"currency": "IRR",
"history": [
{
"id": 8831,
"amount": -450000,
"balance_after": 12500000,
"type": "debit",
"operation": "register",
"status": "success",
"note": "ثبت دامنه example.ir",
"at": "2026-11-02 14:31:08"
}
]
}
}
۴۰۴ — حساب یافت نشد
{
"ok": false,
"error": {
"code": "account-not-found",
"message": "حساب کلید یافت نشد."
}
}
دامنهها #
هستهٔ اصلی سرویس: خواندن، استعلام، ثبت، تمدید، انتقال، بازگردانی، تغییر مالکیت، نیمسرورها و قفل ثبتکننده. همهٔ عملیات تغییردهنده از همان هستهٔ کسبوکار پنل استفاده میکنند.
در همهٔ عملیات تغییردهنده، هدر Idempotency-Key الزامی است و باید بین ۱۶ تا ۶۴ نویسه باشد.
دامنههای همین حساب را با جستوجو، فیلتر و صفحهبندی برمیگرداند. پاسخ همیشه یا کامل است یا صریحاً یک صفحه از یک مجموعهٔ شمارششده؛ فهرست ناقصِ شبیه به کامل وجود ندارد.
پارامترهای درخواست نام نوع داده الزامی توضیحات qstring اختیاری جستوجو در نام دامنه (حداکثر ۱۰۰ نویسه) statusstring اختیاری فیلتر وضعیت: active، pending، expired، redemption، pending_registration، pending_transfer، fraud registrarstring اختیاری فیلتر تخصیص ثبتکننده: assigned یا unknown pageinteger اختیاری شمارهٔ صفحه؛ پیشفرض ۱ per_pageinteger اختیاری اندازهٔ صفحه؛ پیشفرض ۱۰۰ و حداکثر ۵۰۰
فیلدهای پاسخ نام نوع داده توضیحات countsobject شمارش کل حساب (مستقل از فیلتر): total، active، pending، expired، renewal، other، unknown_registrar matchedinteger تعداد ردیفهای منطبق با فیلتر totalinteger کل دامنههای حساب pageobject current، pages، per_page، from، to، numbers filtersobject فیلترهای نرمالشده که واقعاً اعمال شدهاند truncatedboolean همیشه false در حالت صفحهبندیشده domainsarray<object> ردیفهای دامنه (همان شکل اندپوینت جزئیات، بدون خواندن زندهٔ ثبتکننده)
نمونه درخواست
cURL / PHP
cURL PHP
curl -X GET "https://panel.domain123.ir/api/v1/domains?status=active&page=1&per_page=100" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY"
<?php
$token = getenv('DOMAIN123_API_KEY');
$query = [
'status' => 'active',
'page' => 1,
'per_page' => 100,
];
$url = 'https://panel.domain123.ir/api/v1/domains' . '?' . http_build_query($query);
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — پاسخ موفق
{
"ok": true,
"data": {
"status": "ok",
"reason": null,
"counts": {
"total": 1,
"active": 1,
"pending": 0,
"expired": 0,
"renewal": 0,
"other": 0,
"unknown_registrar": 0
},
"total": 1,
"matched": 1,
"page": {
"current": 1,
"pages": 1,
"per_page": 100,
"from": 1,
"to": 1,
"numbers": [
1
]
},
"filters": {
"q": null,
"status": "active",
"registrar": null
},
"truncated": false,
"domains": [
{
"id": 39841,
"fqdn": "example.ir",
"status": "active",
"expiry_date": "2027-04-12",
"locked": true,
"autorenew": true,
"nameservers": [
"ns1.example.ir",
"ns2.example.ir"
],
"nameservers_source": "MIRROR",
"nameservers_established": true,
"nameservers_reason": null,
"nameservers_read_at": 1762200000,
"registrar": "domain123ir",
"registrar_state": "assigned"
}
]
}
}
۴۲۲ — اندازهٔ صفحهٔ نامعتبر
{
"ok": false,
"error": {
"code": "invalid-per-page",
"message": "بیشترین اندازهٔ صفحه 500 است."
}
}
دامنهٔ این حساب را با نام کامل پیدا میکند و همان پاسخ جزئیات را برمیگرداند. این اندپوینت برای مصرفکنندگانی ساخته شده که دامنه را با نام میشناسند، نه با شناسهٔ داخلی پنل.
پارامترهای درخواست نام نوع داده الزامی توضیحات fqdnstring الزامی نام کامل دامنه، مثلاً example.ir
فیلدهای پاسخ نام نوع داده توضیحات (بدنه)object همان فیلدهای اندپوینت «جزئیات دامنه»
نمونه درخواست
cURL / PHP
cURL PHP
curl -X GET "https://panel.domain123.ir/api/v1/domains/lookup?fqdn=example.ir" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY"
<?php
$token = getenv('DOMAIN123_API_KEY');
$query = [
'fqdn' => 'example.ir',
];
$url = 'https://panel.domain123.ir/api/v1/domains/lookup' . '?' . http_build_query($query);
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — پاسخ موفق
{
"ok": true,
"data": {
"id": 39841,
"fqdn": "example.ir",
"status": "active",
"expiry_date": "2027-04-12",
"locked": true,
"autorenew": true,
"nameservers": [
"ns1.example.ir",
"ns2.example.ir"
],
"nameservers_source": "REGISTRAR",
"nameservers_established": true,
"registrar": "domain123ir",
"registrar_state": "assigned",
"live": true,
"read_at": 1762300123,
"read_reason": null,
"statuses": [
"ok"
],
"contacts": [],
"state": "registered",
"state_label": "ثبتشده و فعال",
"registrar_lock": {
"state": "ESTABLISHED",
"locked": true,
"inactive": null,
"statuses": [
"ok"
]
}
}
}
۴۰۴ — دامنه در این حساب نیست
{
"ok": false,
"error": {
"code": "domain-not-found",
"message": "دامنه در این حساب یافت نشد."
}
}
یک خواندن زندهٔ ثبتکننده انجام میدهد و اطلاعات نهایی را برمیگرداند: وضعیتها، تاریخ انقضا، نیمسرورها، قفل و روابط شناسه. اگر خواندن شکست بخورد، آخرین وضعیت معتبر ذخیرهشده با live=false و علت آن برگردانده میشود؛ هیچ چیزی پاک یا حدس زده نمیشود.
پارامترهای مسیر نام نوع داده الزامی توضیحات idinteger الزامی شناسهٔ عددی دامنه در پنل
فیلدهای پاسخ نام نوع داده توضیحات liveboolean آیا پاسخ از خواندن زندهٔ ثبتکننده آمده است read_reasonstring|null علت نبود خواندن زنده statusesarray<string> وضعیتهای EPP گزارششده state / state_labelstring وضعیت نرمالشده و برچسب فارسی آن registrar_lockobject state، locked، inactive، statuses nameservers_sourcestring REGISTRAR یا MIRROR
نمونه درخواست
cURL / PHP
cURL PHP
curl -X GET "https://panel.domain123.ir/api/v1/domains/39841" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY"
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/39841';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — خواندن زندهٔ موفق
{
"ok": true,
"data": {
"id": 39841,
"fqdn": "example.ir",
"status": "active",
"expiry_date": "2027-04-12",
"locked": true,
"autorenew": true,
"nameservers": [
"ns1.example.ir",
"ns2.example.ir"
],
"nameservers_source": "REGISTRAR",
"nameservers_established": true,
"nameservers_reason": null,
"nameservers_read_at": 1762300123,
"registrar": "domain123ir",
"registrar_state": "assigned",
"live": true,
"read_at": 1762300123,
"read_reason": null,
"statuses": [
"ok"
],
"contacts": [],
"state": "registered",
"state_label": "ثبتشده و فعال",
"registrar_lock": {
"state": "ESTABLISHED",
"locked": true,
"inactive": null,
"statuses": [
"ok"
]
}
}
}
۲۰۰ — خواندن ثبتکننده ناموفق (آخرین وضعیت معتبر)
{
"ok": true,
"data": {
"id": 39841,
"fqdn": "example.ir",
"status": "active",
"expiry_date": "2027-04-12",
"locked": true,
"autorenew": true,
"nameservers": [
"ns1.example.ir",
"ns2.example.ir"
],
"nameservers_source": "MIRROR",
"nameservers_established": true,
"nameservers_reason": "registrar-unreachable",
"registrar": "domain123ir",
"registrar_state": "assigned",
"live": false,
"read_at": 1762200000,
"read_reason": "registrar-unreachable",
"statuses": [],
"contacts": [],
"state": "unknown",
"state_label": "نامعلوم",
"registrar_lock": {
"state": "UNAVAILABLE",
"locked": null,
"inactive": null,
"statuses": []
}
}
}
آزاد بودن یک نام را از ثبتکننده میپرسد. این درخواست فقطخواندنی است: چیزی رزرو نمیکند، صورتحساب نمیسازد و پول مصرف نمیکند.
پارامترهای درخواست نام نوع داده الزامی توضیحات fqdnstring الزامی نام کامل دامنه، مثلاً example.ir
فیلدهای پاسخ نام نوع داده توضیحات statusstring available، unavailable یا unknown reasonstring|null علت پاسخ؛ مثلاً provider-reported-available یا availability-not-proven fqdnstring|null نام نرمالشده registrarstring|null ثبتکنندهای که پاسخ داده است operation_idstring شناسهٔ عملیات خواندن (برای پیگیری)
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/availability" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fqdn": "example.ir"
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/availability';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
$payload = [
'fqdn' => 'example.ir',
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — نام آزاد است
{
"ok": true,
"data": {
"status": "available",
"reason": "provider-reported-available",
"fqdn": "example.ir",
"registrar": "domain123ir",
"operation_id": "op_5d1f0a9c3b7e4a21"
}
}
۲۰۰ — نام آزاد نیست
{
"ok": true,
"data": {
"status": "unavailable",
"reason": "provider-reported-unavailable",
"fqdn": "example.ir",
"registrar": "domain123ir",
"operation_id": "op_5d1f0a9c3b7e4a21"
}
}
یک نام جدید را ثبت میکند. پیش از هر اثر مالی، آزاد بودن نام از ثبتکننده پرسیده میشود، تعرفهٔ جاری از انتشار فعال خوانده میشود و مبلغ در کیف پول رزرو میگردد.
شناسهٔ NIC الزامی است. مقدار handle لازم نیست در دفتر شناسههای این حساب وجود داشته باشد؛ ثبتکننده خودش آن را تأیید میکند. اگر نه handle و نه contact_id ارسال نشود، ثبت رد میشود. پذیرش قوانین ثبت (فیلد Conditions در وبسرویس قدیم) در این نسخه بهصورت خودکار و در جریان ثبت اعمال میشود و پارامتر جداگانه ندارد. در دامنههای ملی، فقط حروف لاتین، ارقام و خط تیره مجاز است؛ خط تیره نباید در ابتدا یا انتهای نام باشد. نامهای IDN باید به فرم Punycode ارسال شوند. پارامترهای درخواست نام نوع داده الزامی توضیحات fqdnstring الزامی نام کامل دامنه، مثلاً example.ir periodinteger الزامی مدت ثبت به سال؛ ۱ تا ۱۰ handlestring اختیاری شناسهٔ ایرنیک مالک (NIC handle). یا این یا contact_id الزامی است contact_idinteger اختیاری شناسهٔ محلیِ شناسه در همین حساب؛ جایگزین handle nameserversarray<string> اختیاری حداکثر ۴ نیمسرور؛ تکراریها حذف و نامها نرمال میشوند
فیلدهای پاسخ نام نوع داده توضیحات resultstring successful، failed یا unknown reasonstring|null کد دلیل نهایی operation_idstring شناسهٔ یکتای عملیات؛ برای پیگیری و تکرار امن domain_idinteger|null شناسهٔ دامنه پس از ثبت موفق amountinteger مبلغ رزروشده (ریال) currencystring واحد پول reserve_statestring وضعیت رزرو: NONE، HELD، CONSUMED، RETURNED returned_amountinteger مبلغ بازگشته به کیف پول case_statestring|null CLOSED تنها وقتی پرونده و تسویه هر دو قطعی باشند
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/register" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem-8f2c1d4e5b6a7c8d" \
-d '{
"fqdn": "example.ir",
"period": 1,
"handle": "ex123-irnic",
"nameservers": [
"ns1.example.ir",
"ns2.example.ir"
]
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/register';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Idempotency-Key: idem-8f2c1d4e5b6a7c8d',
];
$payload = [
'fqdn' => 'example.ir',
'period' => 1,
'handle' => 'ex123-irnic',
'nameservers' => [
'ns1.example.ir',
'ns2.example.ir',
],
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — ثبت موفق
{
"ok": true,
"data": {
"result": "successful",
"reason": "registration-completed",
"message": null,
"operation_id": "op_9f3c1a7b2d4e5f60",
"domain_id": 39841,
"amount": 450000,
"currency": "IRR",
"reserve_state": "CONSUMED",
"case_state": null,
"returned_amount": 0
}
}
۴۲۲ — موجودی کیف پول کافی نیست
{
"ok": false,
"error": {
"code": "insufficient-balance",
"message": "موجودی قابل استفادهٔ کیف پول برای این عملیات کافی نیست.",
"case_state": null,
"returned_amount": 0
}
}
مدت اعتبار یک دامنهٔ متعلق به همین حساب را افزایش میدهد. تعرفه از انتشار فعال خوانده میشود و مبلغ پیش از تماس با ثبتکننده رزرو میگردد.
پارامترهای درخواست نام نوع داده الزامی توضیحات domain_idinteger الزامی شناسهٔ دامنه در پنل periodinteger الزامی مدت تمدید به سال
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/renew" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem-8f2c1d4e5b6a7c8d" \
-d '{
"domain_id": 39841,
"period": 1
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/renew';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Idempotency-Key: idem-8f2c1d4e5b6a7c8d',
];
$payload = [
'domain_id' => 39841,
'period' => 1,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — تمدید موفق
{
"ok": true,
"data": {
"result": "successful",
"reason": "renewal-completed",
"message": null,
"operation_id": "op_2b7e5c9a1f0d3e84",
"domain_id": 39841,
"amount": 450000,
"currency": "IRR",
"reserve_state": "CONSUMED",
"case_state": null,
"returned_amount": 0
}
}
۴۲۲ — تمدید پذیرفته نشد
{
"ok": false,
"error": {
"code": "domain-not-renewable",
"message": "دامنه در وضعیتی نیست که قابل تمدید باشد.",
"case_state": null,
"returned_amount": 0
}
}
انتقال یک دامنه از ثبتکنندهٔ دیگر به Domain123 را آغاز میکند. مبلغ تأییدشدهٔ کاربر باید با تعرفهٔ لحظهٔ اجرا یکسان باشد.
اگر confirmed_amount با تعرفهٔ جاری یکسان نباشد، درخواست پیش از هر اثر مالی رد میشود؛ ابتدا تعرفهٔ جدید را نمایش دهید و سپس دوباره تأیید بگیرید. پارامترهای درخواست نام نوع داده الزامی توضیحات fqdnstring الزامی نام کامل دامنه periodinteger الزامی مدت تمدید همراه انتقال confirmed_amountinteger الزامی مبلغی که کاربر تأیید کرده است (ریال)
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/transfer" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem-8f2c1d4e5b6a7c8d" \
-d '{
"fqdn": "example.ir",
"period": 1,
"confirmed_amount": 450000
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/transfer';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Idempotency-Key: idem-8f2c1d4e5b6a7c8d',
];
$payload = [
'fqdn' => 'example.ir',
'period' => 1,
'confirmed_amount' => 450000,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — انتقال پذیرفته شد
{
"ok": true,
"data": {
"result": "successful",
"reason": "transfer-accepted",
"message": null,
"operation_id": "op_7c4a2d8e6b1f0935",
"domain_id": 40112,
"amount": 450000,
"currency": "IRR",
"reserve_state": "CONSUMED",
"case_state": null,
"returned_amount": 0
}
}
۴۲۲ — مبلغ تأییدشده کهنه است
{
"ok": false,
"error": {
"code": "confirmed-amount-mismatch",
"message": "مبلغ تأییدشده با تعرفهٔ جاری یکسان نیست.",
"case_state": null,
"returned_amount": 0
}
}
دامنهٔ منقضی را از دورهٔ بازگردانی (Redemption) خارج و دوباره فعال میکند. این عملیات معمولاً هزینهٔ بازگردانی دارد.
برای دامنههای قفلشده، ابتدا مجوز بازگردانی را با POST /domains/restore-flag ثبت کنید و سپس بازگردانی را اجرا کنید. پارامترهای درخواست نام نوع داده الزامی توضیحات domain_idinteger الزامی شناسهٔ دامنه confirmed_amountinteger الزامی مبلغ تأییدشدهٔ کاربر (ریال)
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/restore" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem-8f2c1d4e5b6a7c8d" \
-d '{
"domain_id": 39841,
"confirmed_amount": 1200000
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/restore';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Idempotency-Key: idem-8f2c1d4e5b6a7c8d',
];
$payload = [
'domain_id' => 39841,
'confirmed_amount' => 1200000,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — بازگردانی موفق
{
"ok": true,
"data": {
"result": "successful",
"reason": "restore-completed",
"message": null,
"operation_id": "op_4e8b1f6a9c2d7053",
"domain_id": 39841,
"amount": 1200000,
"currency": "IRR",
"reserve_state": "CONSUMED",
"case_state": null,
"returned_amount": 0
}
}
۴۲۲ — دامنه قابل بازگردانی نیست
{
"ok": false,
"error": {
"code": "restore-not-eligible",
"message": "این دامنه در وضعیت قابل بازگردانی نیست.",
"case_state": null,
"returned_amount": 0
}
}
مجوز تاریخدار بازیابی یک نام قفلشده را ثبت میکند. این یک «اجازه» است، نه عملیات: چیزی رزرو نمیکند، با ثبتکننده تماس نمیگیرد و هزینهای ندارد.
پارامترهای درخواست نام نوع داده الزامی توضیحات domain_idinteger الزامی شناسهٔ دامنه
فیلدهای پاسخ نام نوع داده توضیحات resultstring flagged یا نتیجهٔ رد flag_idinteger شناسهٔ مجوز ثبتشده flag_datestring تاریخ ثبت مجوز flag_statestring وضعیت مجوز createdboolean آیا مجوز تازه ساخته شد یا مجوز قبلی برگشت amount_chargedinteger همیشه صفر
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/restore-flag" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain_id": 39841
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/restore-flag';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
$payload = [
'domain_id' => 39841,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — مجوز ثبت شد
{
"ok": true,
"data": {
"result": "flagged",
"domain_id": 39841,
"flag_id": 771,
"flag_date": "2026-11-05",
"flag_state": "ACTIVE",
"created": true,
"amount_charged": 0,
"reason": null
}
}
۴۲۲ — مجوز ثبت نشد
{
"ok": false,
"error": {
"code": "restore-flag-refused",
"message": "ثبت مجوز بازگردانی برای این دامنه ممکن نیست."
}
}
شناسهٔ مالک دامنه را به یک NIC handle جدید تغییر میدهد. مبلغ در صورت وجود، پیش از تماس با ثبتکننده رزرو میشود.
تغییر مالکیت برای دامنهٔ قفلشده یا منقضی رد میشود. پیش از فراخوانی، قفل ثبتکننده را با POST /domains/lock باز کنید و وضعیت انقضا را بررسی نمایید. روابط شناسهٔ مالک جدید باید از قبل در ایرنیک تأیید شده باشد؛ در غیر این صورت ثبتکننده درخواست را رد میکند و نتیجه بهصورت failed و با کد دلیل بازگردانده میشود. پارامترهای درخواست نام نوع داده الزامی توضیحات fqdnstring الزامی نام کامل دامنه handlestring الزامی شناسهٔ ایرنیک مالک جدید confirmed_amountinteger اختیاری مبلغ تأییدشده؛ اگر عملیات هزینه داشته باشد الزامی است
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/move" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem-8f2c1d4e5b6a7c8d" \
-d '{
"fqdn": "example.ir",
"handle": "new456-irnic",
"confirmed_amount": 0
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/move';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Idempotency-Key: idem-8f2c1d4e5b6a7c8d',
];
$payload = [
'fqdn' => 'example.ir',
'handle' => 'new456-irnic',
'confirmed_amount' => 0,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — تغییر مالکیت موفق
{
"ok": true,
"data": {
"result": "successful",
"reason": "move-completed",
"message": null,
"operation_id": "op_1a6d9e3c8b5f2047",
"domain_id": 39841,
"amount": 0,
"currency": "IRR",
"reserve_state": "NONE",
"case_state": null,
"returned_amount": 0
}
}
۴۲۲ — دامنه قفل است
{
"ok": false,
"error": {
"code": "domain-locked",
"message": "دامنه در وضعیت قفل است و تغییر مالکیت ممکن نیست.",
"case_state": null,
"returned_amount": 0
}
}
مجموعهٔ نیمسرورهای دامنه را جایگزین میکند. این عملیات رایگان است و هیچ مبلغی رزرو نمیکند، اما تغییردهنده است و کلید Idempotency میخواهد.
برای جلوگیری از تغییر ناخواسته، پیش از ذخیره، مجموعهٔ فعلی را با GET /domains/{id} بخوانید. اگر خواندن وضعیت ثبتکننده ممکن نباشد، ذخیره انجام نمیشود. پارامترهای درخواست نام نوع داده الزامی توضیحات domain_idinteger الزامی شناسهٔ دامنه nameserversarray<string> الزامی بین ۱ تا ۴ نیمسرور؛ نامها lowercase، بدون نقطهٔ پایانی و بدون تکرار میشوند
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/nameservers" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem-8f2c1d4e5b6a7c8d" \
-d '{
"domain_id": 39841,
"nameservers": [
"ns1.example.ir",
"ns2.example.ir"
]
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/nameservers';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Idempotency-Key: idem-8f2c1d4e5b6a7c8d',
];
$payload = [
'domain_id' => 39841,
'nameservers' => [
'ns1.example.ir',
'ns2.example.ir',
],
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — ذخیره شد
{
"ok": true,
"data": {
"result": "successful",
"reason": "nameservers-saved",
"message": null,
"operation_id": "op_6f2c8d1a4e9b3075",
"domain_id": 39841,
"amount": 0,
"currency": "IRR",
"reserve_state": "NONE",
"case_state": null,
"returned_amount": 0
}
}
۴۲۲ — فهرست نیمسرور نامعتبر
{
"ok": false,
"error": {
"code": "nameserver-invalid",
"message": "نام نیمسرور معتبر نیست.",
"case_state": null,
"returned_amount": 0
}
}
قفل ثبتکننده را روی دامنه فعال یا غیرفعال میکند. این عملیات رایگان است، اما یک تغییر واقعی در ثبتکننده است و کلید Idempotency میخواهد.
وضعیت قفل را با GET /domains/{id} و فیلد registrar_lock بخوانید. اگر state برابر UNAVAILABLE باشد، معنایش «قفل نیست» نیست؛ یعنی وضعیت خوانده نشده است. پارامترهای درخواست نام نوع داده الزامی توضیحات domain_idinteger الزامی شناسهٔ دامنه targetstring الزامی مقدار LOCKED یا UNLOCKED
نمونه درخواست
cURL / PHP
cURL PHP
curl -X POST "https://panel.domain123.ir/api/v1/domains/lock" \
-H "Accept: application/json" \
-H "Authorization: Bearer $DOMAIN123_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem-8f2c1d4e5b6a7c8d" \
-d '{
"domain_id": 39841,
"target": "LOCKED"
}'
<?php
$token = getenv('DOMAIN123_API_KEY');
$url = 'https://panel.domain123.ir/api/v1/domains/lock';
$headers = [
'Accept: application/json',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Idempotency-Key: idem-8f2c1d4e5b6a7c8d',
];
$payload = [
'domain_id' => 39841,
'target' => 'LOCKED',
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($response === false) {
throw new RuntimeException('Domain123 API is unreachable.');
}
$result = json_decode($response, true);
echo $status, PHP_EOL, $result['error']['code'] ?? $result['data']['result'] ?? 'ok', PHP_EOL;
پاسخها
JSON
۲۰۰ — قفل اعمال شد
{
"ok": true,
"data": {
"result": "successful",
"reason": "lock-applied",
"message": null,
"operation_id": "op_3e7b0c5d9a2f8146",
"domain_id": 39841,
"amount": 0,
"currency": "IRR",
"reserve_state": "NONE",
"case_state": null,
"returned_amount": 0
}
}
۴۲۲ — هدف قفل نامعتبر
{
"ok": false,
"error": {
"code": "lock-target-invalid",
"message": "هدف قفل باید LOCKED یا UNLOCKED باشد."
}
}
کدهای خطا #
کد خطا پایدار است و هرگز متن استثنا، پاسخ خام ثبتکننده یا مقدار محرمانه را افشا نمیکند. برای منطق برنامه از error.code استفاده کنید، نه از متن پیام.
کدهای وضعیت HTTP
کد معنا اقدام پیشنهادی 200درخواست اجرا شد؛ نتیجه را از data.result بخوانید حتی در ۲۰۰ ممکن است result=unknown باشد 201منبع ساخته شد شناسهٔ ایجادشده را ذخیره کنید 401کلید نامعتبر، منقضی، باطل یا IP غیرمجاز کلید و فهرست IP را بررسی کنید 403سطح دسترسی کلید برای این عملیات کافی نیست کلید با سطح بالاتر بسازید 404دامنه، حساب یا سطح قیمتی در دسترس نیست شناسه و مالکیت را بررسی کنید 422ورودی نامعتبر یا عملیات رد شد فیلدهای خطا را اصلاح کنید؛ ارسال مجدد کورکورانه نکنید 429سقف نرخ پر شده است تا مقدار Retry-After صبر کنید 503سرویس وابسته یا تعرفهٔ منتشرشده در دسترس نیست کمی بعد دوباره تلاش کنید
کدهای خطای پرکاربرد
کد توضیح unauthenticatedکلید معتبر نیست یا IP درخواست مجاز نیست forbiddenسطح دسترسی کلید اجازهٔ این عملیات را نمیدهد rate-limitedسقف درخواست حساب یا IP پر شده است domain-required / domain-invalidنام دامنه ارسال نشده یا قابل نرمالسازی نیست domain-not-foundدامنه در این حساب وجود ندارد idempotency-key-requiredکلید Idempotency ارسال نشده یا شکل آن نامعتبر است insufficient-balanceموجودی کیف پول برای رزرو مبلغ کافی نیست domain-not-availableثبتکننده اعلام کرده نام در دسترس نیست availability-not-provenآزاد بودن نام اثبات نشده است؛ ثبت انجام نمیشود nameservers-empty / nameserver-invalidمجموعهٔ نیمسرور خالی یا نامعتبر است lock-target-invalidمقدار target غیر از LOCKED/UNLOCKED است contact-type-requiredنوع شناسه ارسال نشده است prices-unavailableتعرفهٔ منتشرشده و بهروز وجود ندارد
هرگز بر اساس متن پیام تصمیم نگیرید؛ متن ممکن است برای خوانایی تغییر کند، اما error.code پایدار است.
مهاجرت از وبسرویس قدیم #
اگر مصرفکنندهٔ وبسرویس قدیم CP هستید، جدول زیر معادل هر فراخوانی را نشان میدهد. منطق کسبوکار یکی است، اما پوشش پاسخ و روش احراز هویت تغییر کرده است.
وبسرویس قدیم (CP) معادل در API v1 POST /api/domains/registerPOST /domains/registerPOST /api/domains/renewPOST /domains/renewPOST /api/domains/transferPOST /domains/transferPOST /api/domains/restorePOST /domains/restorePOST /api/domains/movePOST /domains/movePOST /api/domains/dnsPOST /domains/nameserversPOST /api/domains/lock + lockStatusPOST /domains/lock + GET /domains/{id}POST /api/domains/infoGET /domains/lookup?fqdn= یا GET /domains/{id}POST /api/domains/pricesGET /public/pricesPOST /api/resellerGET /account + GET /wallet
پوشش پاسخ تغییر کرده است: نسخهٔ قدیم success و code برمیگرداند، نسخهٔ جدید ok و data یا error. لایهٔ تطبیق خود را پیش از مهاجرت بهروزرسانی کنید. ماژول رسمی WHMCS نسخهٔ ۲.۰ از همین API v1 استفاده میکند و میتواند مرجع پیادهسازی شما باشد.