Skip to main content

Arianet Cloud API

The Cloud API manages Arianet Cloud resources: servers, volumes, private networks, NAT gateways, firewalls, floating, elastic and primary IPs, load balancers, images, snapshots and backups. The arianet cloud CLI commands and the Terraform provider are built on it.

VPS or Cloud?

VPS ordered through /api/v1/servers (the arianet vps commands) are documented in the VPS API. This page covers Arianet Cloud only. Both APIs accept the same token.

Quick start​

  1. Create a token in the panel at cloud.ariaservice.net/users/api-tokens with the scopes cloud:servers:read (every GET) and cloud:servers:write (every change).
  2. Call the API:
export ARIANET_TOKEN="paste-your-token-here"
BASE=https://api.ariaservice.net/cloud/v1
AUTH="Authorization: Bearer $ARIANET_TOKEN"

curl -s $BASE/datacenters -H "$AUTH" # datacenter codes, e.g. ovh
curl -s "$BASE/plans?datacenter=ovh" -H "$AUTH" # plan ids and prices
curl -s "$BASE/images?type=system" -H "$AUTH" # image slugs, e.g. ubuntu-24.04

curl -s -X POST $BASE/servers -H "$AUTH" -H "Content-Type: application/json" \
-d '{"name":"web-1","datacenter":"ovh","plan_id":3,"image":"ubuntu-24.04","ssh_key_ids":[5],"labels":{"role":"web"}}'

The create answers 201 with the server, the action_id of its create action and a root_password that is shown once (it is never stored in the clear). count (1-10) creates several servers in one call. Follow the action until it finishes (see Actions).

Authentication​

Authorization: Bearer <token>
ScopeAllows
cloud:servers:readevery GET
cloud:servers:writeevery POST, PUT, PATCH and DELETE

Resources are always those of the token's account. A missing, invalid or revoked token answers 401; a token without the needed scope, or used from an address outside its IP allowlist, answers 403.

Public price list​

The price list needs no token and may be called from any origin (cached for a minute):

curl -s https://api.ariaservice.net/cloud/v1/public/pricing
curl -s "https://api.ariaservice.net/cloud/v1/public/pricing?datacenter=ovh"
{
"pricing": {
"vat_included": false,
"hours_per_month": 730,
"server_types": [
{
"id": 1, "name": "C1", "group": "shared", "cores": 1, "memory_mb": 2048, "disk_gb": 20,
"included_traffic_gb": 20000, "minimum_usage_hours": 1,
"prices": [
{ "location": "ovh", "price_hourly": { "net": 900, "currency": "IRR" }, "price_monthly": { "net": 657000, "currency": "IRR" } }
]
}
],
"resources": [
{ "sku": "volume_gb", "location": "ovh", "unit": "...", "price_hourly": { "net": 0, "currency": "IRR" }, "price_monthly": { "net": 0, "currency": "IRR" } }
]
}
}

server_types lists every plan with its price per location; resources lists every other price on sale (primary_ipv4, floating_ipv4, floating_ipv6, elastic_ipv4, volume_gb, snapshot_gb, backup as a percentage of the plan, load balancer types and nat_gateway). Prices exclude VAT and come from the same rows billing uses. GET /pricing (with a token) returns your account's own price rows.

Lists, labels and projects​

Every resource list takes:

ParameterMeaning
label_selectorComma-separated terms that must all hold: key=value, key!=value, key (has the label) or !key (has not). Example: env=prod,tier!=db. A malformed selector answers 422 invalid_label_selector.
project_idOnly resources in this project
page, per_pageOpt-in paging: per_page 1-100, default 25. Without page and per_page the whole list is returned as one page.
{ "data": [ { "id": 12, "name": "web-1" } ], "meta": { "pagination": { "page": 1, "per_page": 25, "previous_page": null, "next_page": null, "last_page": 1 } } }

Resources carry labels (key/value pairs) and belong to a project (the account's default project unless you pass project_id on create). PATCH changes name, labels, delete protection (protection_delete) and project; only the fields you send change.

Asynchronous actions​

A change that takes time answers 202 (or 201 for a create) with an action_id. Poll the action until status is success or error:

curl -s $BASE/actions/812 -H "$AUTH"
# {"data":{"id":812,"command":"create","status":"running","progress":40,"resource":{...},"error":null,"started_at":"...","finished_at":null}}

GET /actions lists the account's actions (newest first) and GET /<resource>/{id}/actions those of one resource. With the CLI: arianet cloud actions wait <id>.

Errors​

Every error uses one envelope:

{ "error": "Human-readable message", "code": "not_found", "reason": "..." }

Branch on code, which is stable. reason narrows it when there is more than one way to hit it (for example the resource for quota_exceeded). The codes each HTTP status can carry are listed under x-error-codes in the OpenAPI document.

HTTPTypical code
400invalid_input
401unauthorized
402not enough balance for the order
403forbidden, identity_needed
404not_found
409the resource's state does not allow this now (already_attached, ip_change_fee_not_confirmed, ...)
422well-formed but refused (datacenter_closed, invalid_label_selector, quota_exceeded, plan_sold_out, ...)
423locked, server_locked, lb_locked: the resource is busy with another operation
429rate_limit_exceeded
503unavailable, datacenter_unavailable, ... (carries Retry-After)

Rate limits​

Each token's account and user may make 3600 requests an hour and 60 a minute. Every answer carries:

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

Over the limit the answer is 429 with code rate_limit_exceeded and a Retry-After header (seconds). Wait that long before retrying. A 503 also carries Retry-After.

curl -s -D - -o /dev/null $BASE/servers -H "$AUTH" | grep -i -e ratelimit -e retry-after

Servers​

Method and pathWhat it does
GET /serversList servers
POST /serversCreate one server, or up to 10 with count
GET /servers/{id}One server
PATCH /servers/{id}Change name, labels, protection_delete, protection_rebuild or project_id
DELETE /servers/{id}Delete a server (options below)
POST /servers/{id}/actions/{op}poweron, poweroff (hard), shutdown (ACPI), reboot, reset, rebuild ({"image":"..."}), change_plan ({"plan_id":4}), enable_rescue, disable_rescue, reset_password, change_ipv4 ({"confirm_paid":true} for a paid change)
POST /servers/{id}/actions/attach_to_network, detach_from_networkPrivate networks
POST /servers/{id}/actions/enable_backup, disable_backup, change_backup_window, create_backup, restore_backupBackups
POST /servers/{id}/actions/create_imageSnapshot the server
GET /servers/{id}/costsWhat the server costs (below)
GET /servers/{id}/actions, /backups, /snapshots, /metrics, /networking, /storage, /events, /ip-changesDetails and history
POST /servers/{id}/consoleA single-use VNC console link, valid for 60 seconds

Create body fields: name, datacenter, plan_id, image (required); ssh_key_ids, ssh_keys, user_data (cloud-init, at most 32 KiB), start_after_create, firewall_ids, networks, volume_ids, backups, labels, project_id, count. image is a slug such as ubuntu-24.04, or snapshot:<id> / backup:<id>.

Deleting a server​

curl -s -X DELETE "$BASE/servers/12?keep_backups=true&delete_snapshots=true" -H "$AUTH"
Query parameterDefaultMeaning
keep_backupsfalseKeep the finished backups as snapshots, billed per GB until you delete them (402 when the balance does not cover them)
delete_snapshotsfalseDelete the server's snapshots too; protected ones stay. By default snapshots survive the server and stay billed.
reason-Why: price, performance, ip_filtered, no_longer_needed, migrating, support or other
note-A few words why (required with reason=other, at most 500 characters)

A server with delete protection must have it turned off first (PATCH /servers/{id} with {"protection_delete": false}).

Server costs​

GET /servers/{id}/costs returns the server's current hourly and monthly rate per billed piece and what its copies would cost after a delete:

{
"data": {
"server_id": 12,
"hours_per_month": 730,
"lines": [
{ "type": "server", "id": 12, "name": "web-1", "sku": "...", "quantity": 1, "unit": "...", "hourly_price": 3300, "monthly_price": 2409000, "currency": "IRR" },
{ "type": "volume", "id": 7, "name": "data", "sku": "volume_gb", "quantity": 50, "unit": "...", "hourly_price": 0, "monthly_price": 0, "currency": "IRR" }
],
"totals": [ { "currency": "IRR", "hourly_price": 3300, "monthly_price": 2409000 } ],
"snapshots": { "count": 1, "size_gb": 20, "hourly_price": 0, "monthly_price": 0, "currency": "IRR" },
"kept_backups": { "count": 0, "size_gb": 0, "hourly_price": 0, "monthly_price": 0, "currency": "IRR" }
}
}

Line type is server, primary_ipv4, floating_ip, elastic_ip, volume or backup; quantity is 1, a volume's GB, or the backup's percent of the plan. totals sums the lines per currency. snapshots stay billed after a delete; kept_backups only with keep_backups=true. (Numbers above are illustrative.)

Other resources​

ResourcePaths
Volumes/volumes, /volumes/{id}, POST /volumes/{id}/actions/{op} (attach with server_id, detach, resize with size_gb, grow only), GET /volume-prices
Private networks/networks, /networks/{id}, POST /networks/{id}/subnets, DELETE /networks/{id}/subnets/{subnet}, PUT /networks/{id}/routes
NAT gateways/nat-gateways, /nat-gateways/{id}
Firewalls/firewalls, /firewalls/{id} (PUT replaces the rules), PUT /firewalls/{id}/servers, POST /firewalls/{id}/actions/{op} (apply_to_resources, remove_from_resources)
Floating IPs/floating-ips, /floating-ips/{id}, POST /floating-ips/{id}/actions/{op} (assign, unassign, change_dns_ptr)
Elastic IPs/elastic-ips, /elastic-ips/{id}, POST /elastic-ips/{id}/actions/{op} (assign, unassign)
Primary IPs/primary-ips, /primary-ips/{id}, POST /primary-ips/{id}/actions/change_dns_ptr
Load balancers/load-balancers, /load-balancers/{id}, POST /load-balancers/{id}/actions/{op} (services, targets, type, algorithm, private network), GET /load-balancers/{id}/health, GET /load-balancer-types
ImagesGET /images, GET /images/custom, GET /datacenters/{code}/images
Snapshots and backups/snapshots, /snapshots/{id}, /backups, /backups/{id}, POST /backups/{id}/actions/convert (keep a backup as a snapshot)
Catalog and accountGET /datacenters, GET /plans, GET /pricing, GET /public/pricing, GET /limits
ActionsGET /actions, GET /actions/{id}, GET /actions/{id}/events

Every field, body and answer is in the interactive reference and the OpenAPI document.

Tools​