وب سرویس ابری آریانت
وب سرویس آریانت، سرویس عمومی خرید و مدیریت سرورهای ابری است. ابزار خط فرمان 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:read | GET /regions |
os:read | GET /os/datacenter/{id} |
plans:read | GET /plans/... |
servers:read | GET /servers، /servers/{id}، /servers/{id}/status، /servers/{id}/actions |
servers:write | ساخت، حذف، راهاندازی مجدد، روشن/خاموش، تغییر نام، نصب مجدد، محافظت |
balance:read | GET /balance، /balance/transactions |
invoices:read | GET /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).
کدهای خطا
| HTTP | error.code | معنی |
|---|---|---|
| 400 | VALIDATION_ERROR | فیلدی ارسال نشده یا نامعتبر است؛ پیام نام آن را میگوید |
| 400 | INVALID_ID | شناسه در مسیر عدد نیست |
| 400 | IDEMPOTENCY_KEY_REQUIRED | POST /servers بدون Idempotency-Key |
| 400 | INVALID_IDEMPOTENCY_KEY | کلید ۸ تا ۱۲۸ نویسه از A-Z a-z 0-9 _ - : . نیست |
| 400 | NO_DEFAULT_WALLET | currency_id داده نشده و حساب کیف پول پیشفرض ندارد |
| 400 | BAD_REQUEST | پلتفرم درخواست را نامعتبر دانست |
| 401 | UNAUTHORIZED | توکن نبودن، نامعتبر، منقضی یا ابطالشده |
| 402 | INSUFFICIENT_BALANCE | موجودی کیف پول برای سفارش کافی نیست |
| 403 | FORBIDDEN | حساب فعال نیست یا اجازه این کار را ندارد |
| 403 | INSUFFICIENT_SCOPE | توکن scope لازم برای این نقطه پایانی را ندارد |
| 403 | IP_NOT_ALLOWED | درخواست از آدرسی خارج از فهرست مجاز توکن آمده است |
| 404 | NOT_FOUND | منبع در حساب شما وجود ندارد |
| 409 | CONFLICT | درخواستی با همان Idempotency-Key هنوز در حال اجراست؛ کمی بعد دوباره تلاش کنید |
| 422 | VALIDATION_ERROR | درخواست درست است اما اکنون قابل انجام نیست (سرور محافظتشده، پلن تمامشده، استفاده از کلید با بدنه متفاوت و ...) |
| 429 | RATE_LIMIT_EXCEEDED | تعداد درخواستها بیش از حد است |
| 502 | UPSTREAM_ERROR | پلتفرم نتوانست درخواست را کامل کند؛ دوباره تلاش کنید |
| 503 | UPSTREAM_UNAVAILABLE / WRITES_UNAVAILABLE | پلتفرم موقتاً در دسترس نیست؛ با همان کلید دوباره تلاش کنید |
| 500 | INTERNAL_ERROR | خطای پیشبینینشده |
خطاهای 429، 502 و 503 را با فاصلهگذاری فزاینده (back-off) دوباره بفرستید. تکرار درخواست ساخت تا زمانی که همان Idempotency-Key را بفرستید بیخطر است.
محدودیت نرخ
محدودیتها برای هر کاربر اعمال میشوند، به جز ساخت سرور که برای هر توکن است. هر نمونه از API آنها را مستقل اعمال میکند، پس آنها را عددی دقیق ندانید و حد پایین بگیرید.
| گروه | محدودیت |
|---|---|
| خواندن | ۱۲۰ در دقیقه، burst برابر ۲۰ |
| نوشتن (عملیات، کلید SSH، فایروال، توکن) | حدود ۲۰ در دقیقه، burst برابر ۵ |
POST /servers | burst برابر ۵ و سپس ۵ در ساعت برای هر توکن؛ پلتفرم علاوه بر آن ۱۰ در ساعت برای هر حساب را سقف میگذارد |
با رسیدن به حد مجاز، 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-keys | ssh-keys:read | صفحهبندیشده |
GET /ssh-keys/{id} | ssh-keys:read | |
POST /ssh-keys | ssh-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 /firewalls | firewalls:read | صفحهبندیشده |
GET /firewalls/{id} | firewalls:read | همراه قوانین |
POST /firewalls | firewalls:write | بدنه name، datacenter_id (اجباری) و description. خالی ساخته میشود؛ قوانین را بعداً اضافه کنید. پاسخ 201 |
PUT /firewalls/{id} | firewalls:write | بدنه name و/یا description؛ دستکم یکی. پاسخ شامل قوانین نیست |
DELETE /firewalls/{id} | firewalls:write | |
POST /firewalls/{id}/rules | firewalls: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:write | rule_id همان رشته id قانون است |
POST /firewalls/{id}/attach | firewalls:write | بدنه {"server_ids": [4821]}، ۱ تا ۵۰ شناسه، سرورهای همان دیتاسنتر فایروال |
POST /firewalls/{id}/detach | firewalls: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.