پرش به مطلب اصلی

وب سرویس ابری آریانت

وب سرویس آریانت، سرویس عمومی خرید و مدیریت سرورهای ابری است. ابزار خط فرمان arianet، ربات تلگرام و یکپارچه‌سازی‌های همکاران همه از همین سرویس استفاده می‌کنند و کد خود شما هم می‌تواند از آن استفاده کند. توصیف ماشین‌خوان آن در فایل openapi.yaml کنار همین مستندات منتشر می‌شود.

  • آدرس پایه: https://api.ariaservice.net/api/v1
  • قالب: درخواست و پاسخ JSON روی HTTPS
  • احراز هویت: توکن شخصی API که به صورت Bearer ارسال می‌شود

شروع سریع​

۱. ساخت توکن​

وارد پنل شوید، به تنظیمات ← توکن‌های API بروید، یک توکن بسازید و آن را کپی کنید. توکن فقط یک بار نمایش داده می‌شود. می‌توانید توکن را به دسترسی‌های (scope) مورد نیازش و به آدرس‌های IP مجاز محدود کنید.

export ARIANET_TOKEN="paste-your-token-here"

۲. اولین درخواست​

curl https://api.ariaservice.net/api/v1/balance \
-H "Authorization: Bearer $ARIANET_TOKEN"

۳. خرید سرور​

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

BASE=https://api.ariaservice.net/api/v1
AUTH="Authorization: Bearer $ARIANET_TOKEN"

curl -s $BASE/regions -H "$AUTH" # datacenter ids
curl -s $BASE/plans/datacenter/9 -H "$AUTH" # plan ids and prices
curl -s $BASE/os/datacenter/9 -H "$AUTH" # os ids

curl -s -X POST $BASE/servers \
-H "$AUTH" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"plan_id":101,"datacenter_id":9,"os_id":55,"hostname":"web-1","auth_type":"password","auth_value":"Str0ng!Passw0rd"}'

تا زمانی که سرور در حال ساخت است پاسخ 202 Accepted است. با GET /servers/{id}/status تا زمانی که status برابر active شود وضعیت را بررسی کنید.

احراز هویت​

توکن را در هدر Authorization هر درخواست بفرستید:

Authorization: Bearer <token>

توکن نبودن، نامعتبر بودن، منقضی یا ابطال‌شده بودن پاسخ 401 UNAUTHORIZED دارد.

دسترسی‌ها (Scope)​

هر توکن می‌تواند فهرستی از scope داشته باشد. توکنی که بدون scope ساخته شود نامحدود است. درخواست خارج از scope توکن پاسخ 403 INSUFFICIENT_SCOPE می‌گیرد.

Scopeاجازه می‌دهد
regions:readGET /regions
os:readGET /os/datacenter/{id}
plans:readGET /plans/...
servers:readGET /servers، /servers/{id}، /servers/{id}/status، /servers/{id}/actions
servers:writeساخت، حذف، راه‌اندازی مجدد، روشن/خاموش، تغییر نام، نصب مجدد، محافظت
balance:readGET /balance، /balance/transactions
invoices:readGET /invoices، /invoices/{number}
ssh-keys:read / ssh-keys:writeفهرست و مشاهده / ساخت، ویرایش و حذف کلید SSH
firewalls:read / firewalls:writeفهرست و مشاهده / مدیریت فایروال، قوانین و اتصال‌ها

نقاط پایانی /auth/* به scope نیازی ندارند.

فهرست IP مجاز​

توکن را می‌توان به فهرستی از آدرس‌های مبدأ محدود کرد. درخواست از هر آدرس دیگر پاسخ 403 IP_NOT_ALLOWED می‌گیرد.

نکات امنیتی توکن​

  • هرگز توکن را در کد سمت کاربر یا مخزن کد قرار ندهید؛ آن را در متغیر محیطی یا ذخیره‌گاه اسرار نگه دارید.
  • برای هر برنامه یک توکن جدا و فقط با scopeهای لازم بسازید تا بتوانید یکی را بدون اختلال در بقیه ابطال کنید.
  • توکن‌ها را مرتب بچرخانید؛ ابطال با DELETE /auth/tokens/{id} انجام می‌شود.

پاسخ‌ها​

همه پاسخ‌ها از یک قالب واحد استفاده می‌کنند.

{ "success": true, "data": { "id": 4821, "status": "active" } }

فهرست‌ها pagination هم دارند:

{
"success": true,
"data": [ { "id": 4821 } ],
"pagination": { "current_page": 1, "per_page": 15, "total": 40, "last_page": 3 }
}

خطاها:

{ "success": false, "error": { "code": "INSUFFICIENT_BALANCE", "message": "Not enough balance. Required balance: 4.50" } }

منطق برنامه را بر اساس error.code بنویسید. error.message برای انسان نوشته شده و ممکن است تغییر کند.

فهرست‌ها page (پیش‌فرض ۱) و limit (۱ تا ۱۰۰، پیش‌فرض ۱۵؛ مقدار خارج از بازه به ۱۵ برمی‌گردد) می‌گیرند. زمان‌ها به UTC و با قالب ISO 8601 هستند (2026-10-02T09:30:00Z).

کدهای خطا​

HTTPerror.codeمعنی
400VALIDATION_ERRORفیلدی ارسال نشده یا نامعتبر است؛ پیام نام آن را می‌گوید
400INVALID_IDشناسه در مسیر عدد نیست
400IDEMPOTENCY_KEY_REQUIREDPOST /servers بدون Idempotency-Key
400INVALID_IDEMPOTENCY_KEYکلید ۸ تا ۱۲۸ نویسه از A-Z a-z 0-9 _ - : . نیست
400NO_DEFAULT_WALLETcurrency_id داده نشده و حساب کیف پول پیش‌فرض ندارد
400BAD_REQUESTپلتفرم درخواست را نامعتبر دانست
401UNAUTHORIZEDتوکن نبودن، نامعتبر، منقضی یا ابطال‌شده
402INSUFFICIENT_BALANCEموجودی کیف پول برای سفارش کافی نیست
403FORBIDDENحساب فعال نیست یا اجازه این کار را ندارد
403INSUFFICIENT_SCOPEتوکن scope لازم برای این نقطه پایانی را ندارد
403IP_NOT_ALLOWEDدرخواست از آدرسی خارج از فهرست مجاز توکن آمده است
404NOT_FOUNDمنبع در حساب شما وجود ندارد
409CONFLICTدرخواستی با همان Idempotency-Key هنوز در حال اجراست؛ کمی بعد دوباره تلاش کنید
422VALIDATION_ERRORدرخواست درست است اما اکنون قابل انجام نیست (سرور محافظت‌شده، پلن تمام‌شده، استفاده از کلید با بدنه متفاوت و ...)
429RATE_LIMIT_EXCEEDEDتعداد درخواست‌ها بیش از حد است
502UPSTREAM_ERRORپلتفرم نتوانست درخواست را کامل کند؛ دوباره تلاش کنید
503UPSTREAM_UNAVAILABLE / WRITES_UNAVAILABLEپلتفرم موقتاً در دسترس نیست؛ با همان کلید دوباره تلاش کنید
500INTERNAL_ERRORخطای پیش‌بینی‌نشده

خطاهای 429، 502 و 503 را با فاصله‌گذاری فزاینده (back-off) دوباره بفرستید. تکرار درخواست ساخت تا زمانی که همان Idempotency-Key را بفرستید بی‌خطر است.

محدودیت نرخ​

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

گروهمحدودیت
خواندن۱۲۰ در دقیقه، burst برابر ۲۰
نوشتن (عملیات، کلید SSH، فایروال، توکن)حدود ۲۰ در دقیقه، burst برابر ۵
POST /serversburst برابر ۵ و سپس ۵ در ساعت برای هر توکن؛ پلتفرم علاوه بر آن ۱۰ در ساعت برای هر حساب را سقف می‌گذارد

با رسیدن به حد مجاز، API پاسخ 429 RATE_LIMIT_EXCEEDED می‌دهد. ساخت سرور هدر Retry-After (به ثانیه) هم می‌فرستد. هدرهای X-RateLimit-* ارسال نمی‌شوند.

عملیات ناهمگام​

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

  • با GET /servers/{id}/status تا زمانی که status برابر active و instance_status برابر RUNNING شود (یا پس از خاموش کردن STOPPED) وضعیت را بررسی کنید، یا
  • تاریخچه عملیات را با GET /servers/{id}/actions بخوانید (status یکی از pending، running، success یا failed است).

یک حلقه انتظار نمونه:

until [ "$(curl -s $BASE/servers/4821/status -H "$AUTH" | jq -r .data.status)" = "active" ]; do
sleep 5
done

تغییر نام و تغییر محافظت بلافاصله اعمال می‌شوند و پاسخ 200 دارند.

ایدمپوتنسی​

ساخت سرور هزینه دارد، بنابراین POST /servers هدر Idempotency-Key را الزامی می‌کند: ۸ تا ۱۲۸ نویسه از A-Z a-z 0-9 _ - : .، مثلاً یک UUID.

  • اگر با همان کلید و همان بدنه دوباره بفرستید، هرگز سرور دوم ساخته نمی‌شود. پاسخ اصلی تا ۲۴ ساعت دوباره برگردانده می‌شود و هدر Idempotent-Replayed: true دارد.
  • همان کلید با بدنه متفاوت پاسخ 422 می‌گیرد.
  • تکرار در حالی که درخواست اول هنوز در حال اجراست پاسخ 409 CONFLICT می‌گیرد؛ چند ثانیه صبر کنید و دوباره بفرستید.
  • برای هر سفارش جدید کلید تازه بسازید و تا گرفتن پاسخ قطعی آن را نگه دارید.

پاسخ تکرارشده شامل رمز root است، پس با کلید مثل یک راز رفتار کنید.


مرجع

حساب​

GET /auth/me​

کاربری که توکن متعلق به اوست.

{ "success": true, "data": { "id": 17, "email": "user@example.com", "mobile": null, "status": "active", "verified": true } }

GET /auth/tokens​

توکن‌های API شما. مقدار محرمانه هرگز برگردانده نمی‌شود، فقط یک prefix برای شناسایی.

{
"success": true,
"data": {
"tokens": [
{ "id": 3, "name": "ci", "prefix": "ak_3f9c", "last_used": "2026-10-02T08:12:44Z", "expires": null, "created_at": "2026-09-01T10:00:00Z" }
]
}
}

DELETE /auth/tokens/{id}​

ابطال یکی از توکن‌های شما. پاسخ: {"message": "Token revoked successfully"}.

DELETE /auth/logout​

ابطال توکنی که با آن این درخواست را فرستاده‌اید.

کاتالوگ​

داده‌های کاتالوگ که پیش از خرید سرور لازم دارید.

GET /regions​

Scope: regions:read. مناطق همراه دیتاسنترهایشان. id دیتاسنتر همان datacenter_id است که در سایر نقاط پایانی استفاده می‌شود.

{
"success": true,
"data": {
"items": [
{
"id": 2, "name": "Germany", "is_region": true, "status": "active", "is_default": false,
"country_code": "DE", "flag": "https://.../de.svg",
"datacenters": [
{ "id": 9, "name": "Falkenstein", "is_default": false, "status": "active", "country_code": "DE", "flag": "https://.../de.svg",
"features": [ { "name": "IPv6", "details": null, "quantity": 1 } ] }
]
}
]
}
}

GET /os/datacenter/{datacenter_id}​

Scope: os:read. سیستم‌عامل‌ها به تفکیک خانواده. id یک قالب، یا یکی از children آن (نسخه‌ها)، همان os_id برای ساخت و نصب مجدد است.

{
"success": true,
"data": {
"groups": [
{ "id": 1, "name": "Ubuntu", "type": "linux", "order": 1,
"templates": { "data": [
{ "id": 55, "name": "Ubuntu 24.04", "image_file": "ubuntu-24.04", "status": true,
"datacenter": { "id": 9, "name": "fsn1", "display_name": "Falkenstein" },
"os_group": { "id": 1, "name": "Ubuntu", "type": "linux" },
"children": { "data": [] } }
] } }
]
}
}

GET /plans/datacenter/{datacenter_id}​

Scope: plans:read. پلن‌های قابل سفارش در یک دیتاسنتر، به تفکیک خانواده و همراه قیمت به ازای هر ارز.

{
"success": true,
"data": {
"groups": [
{ "id": 1, "name": "Standard",
"plans": [
{ "id": 101, "name": "std-2", "display_name": "Standard 2", "recommended": true, "cycle": "hourly",
"cpu": { "size": 2, "unit": "vCPU" }, "ram": { "size": 4, "unit": "GB" }, "storage": { "size": 80, "unit": "GB" },
"prices": [ { "code": "USD", "currency": "US Dollar", "hourly": "0.0070", "monthly": "4.50", "yearly": "48.00" } ] }
] }
]
}
}

GET /plans/{id}​

Scope: plans:read. یک پلن، با همان قالب یکی از آیتم‌های بالا.

سرورها​

سرور در هر جا که فهرست یا دریافت شود به این شکل است:

{
"id": 4821,
"status": "active",
"instance_status": "RUNNING",
"name": "web-1",
"hostname": "web-1",
"ip_addresses": [ { "ip": "203.0.113.10", "type": "primary" } ],
"protected": false,
"cycle": "hourly",
"plan": { "id": 101, "name": "std-2" },
"datacenter": { "id": 9, "name": "fsn1", "display_name": "Falkenstein", "country": "DE" },
"os": { "id": 55, "name": "Ubuntu 24.04" },
"created_at": "2026-10-02T09:30:00Z"
}

status وضعیت پلتفرم است (creating، active، suspended، powering_on، powering_off، restarting، reinstalling_os، failed، terminated و ...)؛ instance_status همان است که ارائه‌دهنده گزارش می‌کند (RUNNING، STOPPED، REBOOTING، REBUILDING، BUILD، ERROR و ...). type آدرس یکی از primary، secondary یا floating است.

GET /servers​

Scope: servers:read. سرورهای شما، جدیدترین اول. پارامترها: page، limit، status (فیلتر).

GET /servers/{id}​

Scope: servers:read. یک سرور.

GET /servers/{id}/status​

Scope: servers:read. پاسخی کوچک که بررسی مکرر آن ارزان است.

{ "success": true, "data": { "id": 4821, "status": "active", "instance_status": "RUNNING" } }

GET /servers/{id}/actions​

Scope: servers:read. تاریخچه عملیات یک سرور، جدیدترین اول. پارامتر: limit (۱ تا ۱۰۰، پیش‌فرض ۱۵).

{
"success": true,
"data": {
"server_id": 4821,
"actions": [
{ "id": "9b1f0c5e", "type": "restart", "status": "success",
"started_at": "2026-10-02T09:40:00Z", "finished_at": "2026-10-02T09:40:09Z", "created_at": "2026-10-02T09:40:00Z" }
]
}
}

POST /servers​

Scope: servers:write. هدر: Idempotency-Key (اجباری). پاسخ 202.

فیلداجباریتوضیح
plan_idبلهاز /plans/datacenter/{id}
datacenter_idبلهاز /regions
os_idبلهاز /os/datacenter/{id}
currency_idخیرارز کیف پول؛ پیش‌فرض ارز کیف پول اصلی شماست (در نبود آن NO_DEFAULT_WALLET)
hostnameخیرنام سرور، حداکثر ۲۵۵ نویسه (hostnames هم به عنوان هم‌نام پذیرفته می‌شود و اولویت دارد)
auth_typeخیرpassword (پیش‌فرض) یا ssh
auth_valueبا passwordرمز root
ssh_key_idبا sshیکی از کلیدهای SSH شما (auth_id هم به عنوان هم‌نام پذیرفته می‌شود)
project_idخیرپروژه‌ای که سرور در آن قرار می‌گیرد
service_countخیر۱ تا ۱۰
{
"success": true,
"data": {
"id": 4821,
"status": "creating",
"instance_status": null,
"name": "web-1",
"ip_addresses": [],
"protected": false,
"cycle": "hourly",
"plan": { "name": "std-2" },
"datacenter": { "id": 9 },
"os": { "name": "Ubuntu 24.04" },
"root_password": "Str0ng!Passw0rd",
"created_at": "2026-10-02T09:30:00Z"
}
}

root_password فقط در همین پاسخ (و در تکرار ایدمپوتنت) برمی‌گردد و برای سرورهایی که با کلید SSH ساخته شوند وجود ندارد. آدرس‌ها معمولاً کمی بعد ظاهر می‌شوند؛ سرور را دوباره بخوانید. هزینه بلافاصله از کیف پول رزرو می‌شود. خطاهای ممکن: 402 INSUFFICIENT_BALANCE، 403، 409، 422، 429.

DELETE /servers/{id}​

Scope: servers:write. غیرقابل بازگشت است. سرور محافظت‌شده باید ابتدا محافظتش خاموش شود. پاسخ 202.

بدنه اختیاری: {"reason": "other", "note": "..."} (پیش‌فرض reason برابر other است و note تا ۱۰۰۰ نویسه).

{ "success": true, "data": { "server_id": 4821, "message": "Server deletion started" } }

POST /servers/{id}/restart​

Scope: servers:write. بدنه اختیاری {"mode": "soft" | "hard"}. پاسخ 202 با {"server_id": 4821, "message": "Restart started"}.

POST /servers/{id}/power-on​

Scope: servers:write. پاسخ 202 با {"server_id": 4821, "message": "Power on started"}.

POST /servers/{id}/power-off​

Scope: servers:write. پاسخ 202 با {"server_id": 4821, "message": "Power off started"}. سرور خاموش ممکن است همچنان صورتحساب شود.

POST /servers/{id}/rename​

Scope: servers:write. بدنه {"name": "web-2"} (۱ تا ۳۰ نویسه). پاسخ 200 با {"server_id": 4821, "name": "web-2"}.

POST /servers/{id}/reinstall​

Scope: servers:write. بدنه {"os_id": 56}. همه داده‌های سرور پاک می‌شود. پاسخ 202 با {"server_id": 4821, "message": "Reinstall started"}.

POST /servers/{id}/toggle-protection​

Scope: servers:write. بدنه {"enabled": true} یا {"enabled": false} وضعیت را صریحاً تعیین می‌کند؛ بدون بدنه وضعیت فعلی برعکس می‌شود، پس شکل صریح را ترجیح دهید. پاسخ 200 با {"server_id": 4821, "protected": true}.

کلیدهای SSH​

هر کلید به یک دیتاسنتر تعلق دارد، چون ارائه‌دهندگان کلیدها را به تفکیک مکان نگه می‌دارند.

{ "id": 12, "name": "laptop", "key": "ssh-ed25519 AAAAC3Nza... me@laptop", "protected": false, "datacenter_id": 9, "created_at": "2026-10-01T12:00:00Z" }
نقطه پایانیScopeتوضیح
GET /ssh-keysssh-keys:readصفحه‌بندی‌شده
GET /ssh-keys/{id}ssh-keys:read
POST /ssh-keysssh-keys:writeبدنه name، public_key، datacenter_id (همگی اجباری) و is_protected. پاسخ 201
PUT /ssh-keys/{id}ssh-keys:writeبدنه name و/یا is_protected؛ دست‌کم یکی. خود کلید قابل تغییر نیست
DELETE /ssh-keys/{id}ssh-keys:writeسرورهایی که قبلاً با این کلید ساخته شده‌اند تغییری نمی‌کنند

فایروال‌ها​

{
"id": 7, "name": "web", "protected": false, "datacenter_id": 9,
"rules": [ { "id": "r-91c2", "direction": "ingress", "protocol": "tcp", "port_range": "443", "remote_ip": "0.0.0.0/0", "description": "https" } ],
"created_at": "2026-10-01T12:00:00Z"
}
نقطه پایانیScopeتوضیح
GET /firewallsfirewalls:readصفحه‌بندی‌شده
GET /firewalls/{id}firewalls:readهمراه قوانین
POST /firewallsfirewalls:writeبدنه name، datacenter_id (اجباری) و description. خالی ساخته می‌شود؛ قوانین را بعداً اضافه کنید. پاسخ 201
PUT /firewalls/{id}firewalls:writeبدنه name و/یا description؛ دست‌کم یکی. پاسخ شامل قوانین نیست
DELETE /firewalls/{id}firewalls:write
POST /firewalls/{id}/rulesfirewalls:writeبدنه direction (ingress/egress) و protocol (tcp، udp، icmp، esp، gre) اجباری؛ port_range، remote_ip، description اختیاری. port_range عدد یا بازه صعودی ۱ تا ۶۵۵۳۵ و remote_ip آدرس یا CIDR معتبر است، وگرنه 400. پاسخ 201 با قانون جدید
DELETE /firewalls/{id}/rules/{rule_id}firewalls:writerule_id همان رشته id قانون است
POST /firewalls/{id}/attachfirewalls:writeبدنه {"server_ids": [4821]}، ۱ تا ۵۰ شناسه، سرورهای همان دیتاسنتر فایروال
POST /firewalls/{id}/detachfirewalls:writeهمان بدنه

صورتحساب​

GET /balance​

Scope: balance:read. یک کیف پول به ازای هر ارز. primary کیف پول پیش‌فرضی است که هنگام ساخت سرور و نبود currency_id استفاده می‌شود.

{
"success": true,
"data": { "wallets": [
{ "id": 31, "balance": 25.4, "primary": true, "status": "active",
"currency": { "id": 1, "code": "USD", "name": "US Dollar", "symbol": "$" } }
] }
}

GET /balance/transactions​

Scope: balance:read. صفحه‌بندی‌شده.

{ "id": 905, "mode": "debit", "amount": 4.5, "status": "paid", "reference": "0b6c...", "type": "service", "currency": { "id": 1, "code": "USD", "name": "US Dollar", "symbol": "$" }, "created_at": "2026-10-02T09:30:00Z" }

GET /invoices​

Scope: invoices:read. صفحه‌بندی‌شده، جدیدترین اول؛ فاکتورهای با مبلغ صفر فهرست نمی‌شوند. پارامترها: page، limit، status (draft، issued، paid، overdue، cancelled).

{
"number": "INV-2026-000123", "status": "paid", "payment_status": "paid",
"subtotal": 4.5, "discount": 0, "tax": 0, "total": 4.5,
"issued_at": "2026-10-02T09:30:00Z", "due_at": "2026-10-09T09:30:00Z", "paid_at": "2026-10-02T09:31:00Z"
}

GET /invoices/{number}​

Scope: invoices:read. یک فاکتور همراه اقلامش. شماره متن است (2041 یا INV-2026-000123)؛ هرگز آن را به عدد صحیح تبدیل نکنید.

{ "...": "invoice fields as above", "items": [ { "amount": 4.5, "currency": { "id": 1, "code": "USD", "name": "US Dollar", "symbol": "$" }, "description": "std-2 hourly" } ] }

مهاجرت از نسخه‌های قبلی​

  • آدرس پایه https://api.ariaservice.net/api/v1 است.
  • POST /servers اکنون هدر Idempotency-Key را الزامی می‌کند و پاسخ 202 می‌دهد؛ پاسخ ساخت و عملیات، شیءهای کوچک و ثابت هستند، نه سرور کامل.
  • حذف قانون فایروال با id قانون انجام می‌شود (DELETE /firewalls/{id}/rules/{rule_id})، نه با جایگاه آن در فهرست.
  • فایروال خالی ساخته می‌شود؛ قوانین را با POST /firewalls/{id}/rules اضافه کنید.
  • ساخت کلید SSH به datacenter_id نیاز دارد.
  • جدید: GET /servers/{id}/actions، GET /invoices، GET /invoices/{number} و scope با نام invoices:read.