Skip to main content

API conventions

Every Arianet API is REST over HTTPS, takes and returns JSON, and authenticates with a Bearer token. This page puts the shared rules and each product's differences in one place, so your client works correctly against all of them.

Base URLs and versions​

APIBase URLOpenAPI document
Arianet Cloudhttps://api.ariaservice.net/cloud/v1openapi.json
VPShttps://api.ariaservice.net/api/v1openapi.yaml
Regional VPShttps://api.ariaservice.net/vps/v1openapi.json
Hostinghttps://api.ariaservice.net/hosting/v1openapi.json
Dedicated servershttps://api.ariaservice.net/baremetal/v1openapi.json
SMShttps://api.ariaservice.net/sms/v1openapi.json

The version is part of the path (v1). Write clients that ignore unknown response fields; new fields and values are added without a version change.

Requests and responses​

  • POST, PUT and PATCH bodies are JSON and need Content-Type: application/json.
  • Times are UTC in ISO 8601 / RFC 3339 (2026-10-02T09:30:00Z).
  • Ids are integers unless the product page says otherwise (invoice numbers and SMS message ids, for example, are strings).
  • PATCH changes only the fields you send.

Successful responses come in two shapes:

{ "data": { "id": 12, "name": "web-1" } }

Errors​

Every error carries a stable, machine-readable code. Base your logic on the HTTP status and the code, never on the message; the message is for people and may change.

APIError format
Cloud{"error": "...", "code": "not_found", "reason": "..."}; reason, when present, narrows the case down
Regional VPS, hosting, dedicated servers{"error": "...", "code": "not_found"}
SMS{"code": "not_found", "message": "..."}
VPS (/api/v1){"success": false, "error": {"code": "NOT_FOUND", "message": "..."}}

HTTP statuses mean the same thing everywhere:

HTTPMeansRetry?
400 / 422Invalid input, or a valid request that cannot be done right nowNo; fix the request
401No token, or an invalid oneNo
402Not enough wallet balanceAfter topping up
403Not allowedNo
404The resource does not exist in your accountNo
409 / 423The resource's state does not allow it now, or another operation holds itYes, a little later
429Rate limitedYes, after Retry-After
500 / 502 / 503Temporary server-side errorYes, with growing back-off
504The answer did not arrive in time; the request may have runRead the state first

The full list of codes for each API is on its product page and in its OpenAPI document.

Rate limits​

APILimit
Cloud60 requests a minute and 3,600 an hour per account and user
VPS (/api/v1)Reads 120 a minute; writes about 20 a minute; creating servers 5 an hour per token (details)
Regional VPS, hosting, dedicated servers, SMSPer caller; the current values are in the RateLimit-* headers

The newer APIs send these headers on every response:

HeaderMeaning
RateLimit-LimitRequests allowed in the current window
RateLimit-RemainingRequests left
RateLimit-ResetSeconds until the next window

Over the limit, the answer is 429 and Retry-After (in seconds) says how long to wait.

Retrying​

Retry 429, 502, 503 and network errors with exponential back-off, honouring Retry-After when present. Only retry requests that spend money with an idempotency key.

import os
import random
import time
import requests

RETRY = {429, 502, 503}

def call(method, url, **kwargs):
headers = {"Authorization": f"Bearer {os.environ['ARIANET_TOKEN']}", **kwargs.pop("headers", {})}
for attempt in range(6):
resp = requests.request(method, url, headers=headers, timeout=30, **kwargs)
if resp.status_code not in RETRY:
return resp
wait = float(resp.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait + random.random())
return resp

The CLI retries rate-limited reads by itself; it never retries changes automatically.

Pagination​

APIParametersPage information in the response
Cloudpage, per_page (1 to 100, default 25); without them the whole list comes in one pagemeta.pagination: page, per_page, previous_page, next_page, last_page
SMSpage, per_page (up to 200)meta: total, current_page, per_page
VPS (/api/v1)page, limit (1 to 100, default 15)pagination: current_page, per_page, total, last_page
Regional VPS, hosting, dedicated serversLists come back whole; action lists take limit-

Asynchronous operations​

Work that takes time (creating, deleting, reinstalling, resizing, power) answers 201 or 202 at once and runs in the background. Follow it to the end like this:

APIWhat to pollFinal state
CloudGET /actions/{id} with the response's action_idstatus: success or error
Regional VPS, hostingGET /actions/{id}state: success or error
Dedicated serversGET /orders/{id} (delivery steps)Order delivered or cancelled
SMSGET /batches/{id} or the webhookcompleted, partial or failed
VPS (/api/v1)GET /servers/{id}/status or GET /servers/{id}/actionsstatus is active / action success or failed

Poll every few seconds (every 5 seconds, say) and cap the total wait. The CLI does this with --wait and actions wait.

Safe retries (idempotency)​

If the answer to an order never reaches you (a dropped connection, a 504), you cannot know whether it was placed. With an idempotency key you can safely send the same request again: no second order is made and the first answer comes back.

APIRequestsHow
VPS (/api/v1)POST /serversIdempotency-Key header, required (details)
Regional VPSPOST /serversIdempotency-Key header
HostingPOST /accountsIdempotency-Key header
Dedicated serversPOST /orders, POST /servers/{id}/renewIdempotency-Key header
SMSPOST /messagesclient_reference field (or the Idempotency-Key header)

Make a new key (a UUID, for example) for every new order, and reuse it for retries until you have a definite answer.

curl -s -X POST https://api.ariaservice.net/vps/v1/servers \
-H "Authorization: Bearer $ARIANET_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"datacenter":"thr-1","plan_id":4,"image":"ubuntu-24.04","hostname":"web-1","billing_mode":"hourly"}'

Regions​

Regional VPS and hosting have a separate install per region. Pick the region with the Arianet-Region header; without it, the request goes to the product's default region:

curl -s https://api.ariaservice.net/hosting/v1/accounts \
-H "Authorization: Bearer $ARIANET_TOKEN" \
-H "Arianet-Region: iran-1"

An unknown region answers 404 region_not_found. SMS runs only in iran-1 and dedicated servers have a single install; neither needs the header.

Timeouts and 504​

Requests that travel to another region can end with 504 gateway_timeout even though the work was done. Before retrying, read the state (the resource list or the actions) or use an idempotency key.