پیش از شروع
نشانی پایهٔ همهٔ درخواستها https://iranclaud.ir/api/v1 است. همین نشانی بدون توکن هم پاسخ میدهد و نام سرویس، نسخه، نشانی مستندات و نام گروههای API را برمیگرداند؛ راه خوبی برای اطمینان از دسترسی شبکه پیش از ساخت توکن. مسیر دقیق هر endpoint را در مرجع ببینید.
curl https://iranclaud.ir/api/v1۱. ساخت توکن
- ۱ وارد حساب شوید و به صفحهٔ ساخت توکن بروید.
- ۲ یک نام توضیحی بنویسید (مثلاً «CI استقرار») و فقط دسترسیهایی را تیک بزنید که اسکریپت لازم دارد؛ فهرست کامل در بخش ۷ است.
- ۳ انقضا را انتخاب کنید: ۳۰، ۹۰ یا ۳۶۵ روز، یا بدون انقضا.
- ۴ توکن فقط همین یک بار نمایش داده میشود. همان لحظه آن را در جای امنی ذخیره کنید؛ اگر گم شد، باطلش کنید و توکن تازه بسازید.
توکنها شکل ic_pat_xxxxxxxx_xxxx… دارند: پیشوند ثابت ic_pat_، هشت نویسهٔ شناسه و ۳۲ نویسهٔ مخفی. پیشوند ثابت کمک میکند ابزارهای اسکن کد، توکنی را که اشتباهی در مخزن کد قرار گرفته پیدا کنند.
۲. اولین درخواست
توکن را در هدر Authorization: Bearer <token> بفرستید. بهتر است آن را در یک متغیر محیطی نگه دارید تا در تاریخچهٔ shell و کد شما نماند. این درخواست فهرست سرورهای حساب را برمیگرداند و به دسترسی vm:read نیاز دارد.
export IRANCLAUD_TOKEN="ic_pat_…"
curl -H "Authorization: Bearer $IRANCLAUD_TOKEN" \
"https://iranclaud.ir/api/v1/vms?limit=10"import os, requests
r = requests.get(
"https://iranclaud.ir/api/v1/vms",
headers={"Authorization": f"Bearer {os.environ['IRANCLAUD_TOKEN']}"},
params={"limit": 10},
timeout=30,
)
r.raise_for_status()
for vm in r.json()["data"]:
print(vm["uuid"], vm["status"], vm["public_ip"])const res = await fetch("https://iranclaud.ir/api/v1/vms?limit=10", {
headers: { Authorization: `Bearer ${process.env.IRANCLAUD_TOKEN}` },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
for (const vm of body.data) console.log(vm.uuid, vm.status, vm.public_ip);۳. ساخت سرور ابری با API
ابتدا شناسهٔ پلن و سیستمعامل را از فهرستهای عمومی بخوانید؛ این دو درخواست توکن لازم ندارند. فیلد slug هر مورد همان مقداری است که در درخواست ساخت میفرستید.
curl https://iranclaud.ir/api/v1/plans
curl https://iranclaud.ir/api/v1/os-templates
سپس با توکنی که دسترسی vm:create دارد درخواست ساخت را بفرستید. فیلدهای plan_slug و os_template_slug الزامیاند؛ hostname اختیاری است (پایینتر را ببینید) و برای ورود میتوانید رمز عبور (password)، کلید SSH (pubkey) یا هر دو (both) را انتخاب کنید. در نمونهٔ زیر، YOUR_SSH_KEY_UUID را با شناسهٔ کلید SSH خود عوض کنید؛ فهرست کلیدها و شناسههایشان را GET /api/v1/account/ssh-keys برمیگرداند.
curl -X POST "https://iranclaud.ir/api/v1/vms" \
-H "Authorization: Bearer $IRANCLAUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"plan_slug": "mini",
"os_template_slug": "debian-12",
"auth_mode": "pubkey",
"ssh_key_uuids": ["YOUR_SSH_KEY_UUID"]
}'-
پاسخ موفق کد 202 دارد؛ سرور ساخته شده و شناسهٔ آن در
data.uuidو هدرLocationاست. -
هزینهٔ ساعت اول همان لحظه از کیف پول کسر میشود. اگر موجودی کافی نباشد، پاسخ
422باdetails.reason = insufficient_balanceمیگیرید. -
وضعیت را با
GET /api/v1/vms/{uuid}چند ثانیه یک بار بخوانید تاstatusبهrunningبرسد. -
اگر پاسخ
503با کدcompute_unavailableبود، هزینهٔ ساعت اول کسر شده و سفارش پرداختشده بهطور خودکار ساخته میشود؛ درخواست را تکرار نکنید. - هر درخواست POST یک سرور تازه میسازد. اگر پاسخ بهخاطر قطعی شبکه نرسید، پیش از تکرار فهرست سرورها را بخوانید تا سرور تکراری و هزینهٔ دوباره نسازید.
-
فیلد
hostnameفعلاً فقط بررسی میشود و هنگام ساخت اعمال نمیشود؛ پس از ساخت آن را باPOST /api/v1/vms/{uuid}/security/hostnameتنظیم کنید.
۴. قالب پاسخ و صفحهبندی
همهٔ پاسخها JSON هستند و یکی از سه شکل زیر را دارند. request_id را در گزارشهای خود نگه دارید؛ همین شناسه در هدر X-Request-Id هم میآید و هنگام تماس با پشتیبانی پیگیری را سریع میکند.
// موفق، یک مورد
{ "data": { … }, "meta": { "request_id": "…" } }
// موفق، فهرست
{ "data": [ … ],
"meta": { "request_id": "…", "next_cursor": null, "has_more": false, "total": 7 } }
// خطا
{ "error": { "code": "scope_missing", "message": "Token requires vm:write scope.",
"details": { "required_scope": "vm:write" } },
"meta": { "request_id": "…" } }
صفحهبندی در همهٔ فهرستها یکسان نیست؛ next_cursor در نسخهٔ v1 همیشه null و has_more همیشه false است:
-
فهرست سرورها (
/vms) و تراکنشهای کیف پول (/wallet/transactions) باlimit(۱ تا ۲۰۰، پیشفرض ۵۰) وoffsetصفحهبندی میشوند وmeta.totalتعداد کل را میگوید. فهرست سرورها فیلترstatusو جستوجویqدر شناسه، IP و نام سرور هم دارد. -
تیکتها (
/tickets) و گزارش فعالیت (/activity) باpageوper_page(۱ تا ۲۰۰، پیشفرض ۵۰) کار میکنند و فهرست را داخلdata.itemsهمراه باtotalوpagesبرمیگردانند. -
بقیهٔ فهرستها (DNS، CDN، کلیدهای SSH، فضای ذخیرهسازی، دیتابیس، اپلیکیشنها و…) صفحهبندی ندارند و همهٔ موارد را یکجا با
meta.totalبرمیگردانند.
پارامترهای هر endpoint در مرجع آمده است.
۵. کدهای خطا
برنامهٔ خود را بر اساس error.code بنویسید، نه متن پیام؛ کدها ثابتاند و پیام ممکن است تغییر کند.
| کد | HTTP | معنی و راهحل |
|---|---|---|
unauthenticated |
HTTP 401 | هدر Authorization نیست یا با Bearer شروع نمیشود. |
token_invalid |
HTTP 401 | توکن نامعتبر، منقضی یا باطلشده است، یا حساب فعال نیست. توکن تازه بسازید. |
scope_missing |
HTTP 403 | توکن دسترسی لازم را ندارد؛ نام آن در details.required_scope آمده است. |
not_found |
HTTP 404 | منبع وجود ندارد یا متعلق به حساب شما نیست. |
conflict |
HTTP 409 | وضعیت فعلی اجازهٔ این کار را نمیدهد؛ مثلاً دامنه قبلاً ثبت شده یا زون هنوز تأیید نشده است. |
not_supported |
HTTP 409 | این کار برای این نوع سرور در دسترس نیست؛ مثلاً کنسول وب، تغییر رمز روت یا نام میزبان و بازیابی بکاپ در سرور اختصاصی. راه جایگزین در متن پیام خطا آمده است. |
suspended_unpaid |
HTTP 409 | سرور بهدلیل کسری موجودی معلق است؛ روشن کردن، راهاندازی دوباره، بازیابی بکاپ و تغییر رمز یا نام میزبان رد میشود (خاموش کردن مجاز است). پس از شارژ کیف پول سرور خودکار روشن میشود. |
topup_failed |
HTTP 402/422 | خرید بستهٔ ترافیک انجام نشد: 402 یعنی موجودی کیف پول کافی نیست؛ 422 یعنی بسته اعمال نشد و مبلغ برگشت داده شد. |
validation_failed |
HTTP 422 | بدنه یا پارامترها نامعتبرند؛ فیلدهای مشکلدار در details.fields آمدهاند. |
rate_limited |
HTTP 429 | از سقف درخواست گذشتهاید؛ به اندازهٔ هدر Retry-After (ثانیه) صبر کنید. |
internal_error |
HTTP 500 | خطای پیشبینینشده؛ request_id را برای پشتیبانی بفرستید. |
compute_unavailable |
HTTP 503 | سرویس ساخت و مدیریت سرور موقتاً در دسترس نیست؛ کمی بعد دوباره تلاش کنید. |
backend_error |
HTTP 503 | سرویس پشتیبان (مثلاً فضای ذخیرهسازی) موقتاً پاسخ نمیدهد؛ دوباره تلاش کنید. |
sync_failed |
HTTP 503 | گروه قانون فایروال ذخیره شد اما روی سرور اعمال نشد؛ بعداً با POST /firewall/rulesets/{uuid}/sync دوباره اعمال کنید. |
نشانی یا متدی که وجود ندارد قالب JSON بالا را ندارد: مسیر ناشناخته پاسخ متنی 404 Not Found و متد نادرست روی مسیر درست پاسخ 405 با هدر Allow میگیرد. اگر بهجای JSON متن گرفتید، مسیر و متد را با مرجع مقایسه کنید.
۶. محدودیت نرخ
سقفها برای هر توکن و هر نوع درخواست جداگانه حساب میشوند. پنجرهٔ دقیقهای سر هر دقیقه و پنجرهٔ روزانه سر هر روز (UTC) از نو شروع میشود. درخواستهای ردشده هم در شمارش حساب میشوند، پس پس از 429 تا پایان زمان Retry-After صبر کنید.
| نوع درخواست | در دقیقه | در روز |
|---|---|---|
| خواندن (GET) | ۱۲۰ | ۵۰٬۰۰۰ |
| تغییر (POST، PATCH، DELETE) | ۳۰ | ۵٬۰۰۰ |
| باز کردن کنسول سرور | ۱۰ | ۲۰۰ |
| مجموع همهٔ توکنهای حساب | — | ۱۰۰٬۰۰۰ |
هر پاسخی که از سد محدودیت بگذرد این هدرها را دارد (همه برای پنجرهٔ دقیقهای):
X-RateLimit-Limitسقف دقیقهای این نوع درخواستX-RateLimit-Remainingتعداد باقیمانده در این دقیقهX-RateLimit-Resetزمان شروع دقیقهٔ بعد به صورت Unix timestamp
نوع هر endpoint (خواندن، تغییر یا کنسول) کنار آن در مرجع آمده است. فهرستهای عمومی پلن و سیستمعامل توکن نمیخواهند و در این سقفها شمرده نمیشوند.
پاسخ 429 بهجای آنها هدر Retry-After (ثانیه) و در بدنه details.retry_after_sec دارد.
۷. دسترسیها (scope)
هر endpoint، بهجز فهرستهای عمومی پلن و سیستمعامل، یک scope مشخص لازم دارد که کنار آن در مرجع آمده است. توکن را با کمترین دسترسی لازم بسازید: اسکریپت گزارشگیری فقط به scopeهای :read نیاز دارد. vm:destroy در فرم ساخت توکن هست اما هنوز endpointی برای حذف سرور با API وجود ندارد؛ حذف سرور فعلاً از پنل انجام میشود.
| حوزه | scopeها |
|---|---|
| سرور ابری |
|
| حذف سرور (بهزودی) |
|
| فایروال سرور |
|
| گروههای قانون فایروال |
|
| حساب و کلید SSH |
|
| DNS |
|
| CDN |
|
| پشتیبانگیری |
|
| ترافیک |
|
| کیف پول |
|
| فضای ذخیرهسازی |
|
| دیتابیس |
|
| وردپرس |
|
| نکستکلاد |
|
| مترموست |
|
| تیکت و فعالیت |
|
۸. نگهداری امن توکن
- توکن را در متغیر محیطی یا بخش secrets سامانهٔ CI نگه دارید، نه در کد یا فایلهای مخزن.
- برای هر اسکریپت یا سرویس توکن جداگانه بسازید تا در صورت نشت، فقط همان یکی را باطل کنید.
- برای توکنهای موقت انقضا بگذارید و توکنهای بیاستفاده را در صفحهٔ توکنها باطل کنید؛ آنجا زمان آخرین استفادهٔ هر توکن هم دیده میشود.
- همیشه از نشانی https استفاده کنید. API توکن را فقط از هدر Authorization میخواند؛ آن را در نشانی (query string) یا لاگها نگذارید.